Sfoglia il codice sorgente

Merge remote-tracking branch 'mrdoob/dev' into dev

Daniel 9 anni fa
parent
commit
4fac445591
82 ha cambiato i file con 3760 aggiunte e 3764 eliminazioni
  1. 340 607
      build/three.js
  2. 356 370
      build/three.min.js
  3. 7 16
      docs/api/math/Math.html
  4. 1 0
      docs/index.html
  5. 1 0
      editor/css/dark.css
  6. 1 0
      editor/css/light.css
  7. 7 16
      editor/index.html
  8. 1 9
      editor/js/Editor.js
  9. 21 21
      editor/js/Menubar.File.js
  10. 10 6
      editor/js/Menubar.Status.js
  11. 2 2
      editor/js/Sidebar.Object3D.js
  12. 2 2
      editor/js/Sidebar.Project.js
  13. 7 8
      editor/js/Toolbar.js
  14. 33 22
      editor/js/libs/ui.js
  15. 8 4
      examples/canvas_geometry_text.html
  16. 2 0
      examples/index.html
  17. 0 0
      examples/js/geometries/TextGeometry.js
  18. 6 1
      examples/js/loaders/ColladaLoader2.js
  19. 146 32
      examples/js/loaders/VRMLLoader.js
  20. 716 258
      examples/js/loaders/sea3d/SEA3D.js
  21. 244 152
      examples/js/loaders/sea3d/SEA3DLoader.js
  22. 1 1
      examples/js/renderers/CSS3DRenderer.js
  23. 1 1
      examples/js/renderers/CSS3DStereoRenderer.js
  24. 13 204
      examples/js/utils/FontUtils.js
  25. 136 0
      examples/js/utils/ImageUtils.js
  26. 3 0
      examples/webgl_camera_logarithmicdepthbuffer.html
  27. 2 0
      examples/webgl_custom_attributes_lines.html
  28. 9 7
      examples/webgl_geometry_normals.html
  29. 3 2
      examples/webgl_geometry_spline_editor.html
  30. 2 2
      examples/webgl_geometry_text.html
  31. 2 4
      examples/webgl_geometry_text2.html
  32. 1 3
      examples/webgl_materials_bumpmap.html
  33. 1 1
      examples/webgl_materials_bumpmap_skin.html
  34. 6 5
      examples/webgl_materials_lightmap.html
  35. 2 0
      examples/webgl_modifier_subdivision.html
  36. 2 0
      examples/webgl_modifier_tessellation.html
  37. 83 85
      examples/webgl_octree.html
  38. 2 2
      examples/webgl_shaders_vector.html
  39. 2 0
      examples/webgl_shadowmap.html
  40. 2 0
      examples/webgl_shadowmap_performance.html
  41. 1 1
      package.json
  42. 11 1
      src/Three.js
  43. 1 1
      src/animation/KeyframeTrack.js
  44. 39 0
      src/core/Channels.js
  45. 1 0
      src/core/Object3D.js
  46. 49 0
      src/extras/CurveUtils.js
  47. 11 175
      src/extras/ImageUtils.js
  48. 750 0
      src/extras/ShapeUtils.js
  49. 1 50
      src/extras/core/Curve.js
  50. 0 147
      src/extras/core/CurvePath.js
  51. 28 49
      src/extras/core/Path.js
  52. 3 611
      src/extras/core/Shape.js
  53. 6 6
      src/extras/curves/ClosedSplineCurve3.js
  54. 10 13
      src/extras/curves/CubicBezierCurve.js
  55. 6 6
      src/extras/curves/CubicBezierCurve3.js
  56. 10 12
      src/extras/curves/QuadraticBezierCurve.js
  57. 6 6
      src/extras/curves/QuadraticBezierCurve3.js
  58. 5 5
      src/extras/curves/SplineCurve.js
  59. 6 6
      src/extras/curves/SplineCurve3.js
  60. 11 13
      src/extras/geometries/ExtrudeGeometry.js
  61. 2 2
      src/extras/geometries/PolyhedronGeometry.js
  62. 3 3
      src/extras/geometries/ShapeGeometry.js
  63. 1 2
      src/extras/geometries/TubeGeometry.js
  64. 2 0
      src/lights/AmbientLight.js
  65. 2 0
      src/lights/HemisphereLight.js
  66. 60 0
      src/loaders/CubeTextureLoader.js
  67. 163 261
      src/loaders/Loader.js
  68. 0 9
      src/loaders/ObjectLoader.js
  69. 5 3
      src/loaders/TextureLoader.js
  70. 17 55
      src/math/Color.js
  71. 8 12
      src/math/Math.js
  72. 3 3
      src/math/Matrix4.js
  73. 41 69
      src/math/Vector2.js
  74. 31 93
      src/math/Vector3.js
  75. 26 118
      src/math/Vector4.js
  76. 111 64
      src/renderers/WebGLRenderer.js
  77. 8 2
      src/renderers/shaders/ShaderLib.js
  78. 121 119
      src/renderers/webgl/WebGLShadowMap.js
  79. 2 0
      utils/build/includes/common.json
  80. 2 2
      utils/build/includes/extras.json
  81. 1 0
      utils/exporters/max/ThreeJSAnimationExporter.ms
  82. 12 2
      utils/exporters/max/ThreeJSExporter_MorphTargets_v0.ms

File diff suppressed because it is too large
+ 340 - 607
build/three.js


+ 356 - 370
build/three.min.js

@@ -1,19 +1,19 @@
 // threejs.org/license
-'use strict';var THREE={REVISION:"73dev"};"function"===typeof define&&define.amd?define("three",THREE):"undefined"!==typeof exports&&"undefined"!==typeof module&&(module.exports=THREE);
+'use strict';var THREE={REVISION:"73"};"function"===typeof define&&define.amd?define("three",THREE):"undefined"!==typeof exports&&"undefined"!==typeof module&&(module.exports=THREE);
 void 0!==self.requestAnimationFrame&&void 0!==self.cancelAnimationFrame||function(){for(var a=0,b=["ms","moz","webkit","o"],c=0;c<b.length&&!self.requestAnimationFrame;++c)self.requestAnimationFrame=self[b[c]+"RequestAnimationFrame"],self.cancelAnimationFrame=self[b[c]+"CancelAnimationFrame"]||self[b[c]+"CancelRequestAnimationFrame"];void 0===self.requestAnimationFrame&&void 0!==self.setTimeout&&(self.requestAnimationFrame=function(b){var c=Date.now(),g=Math.max(0,16-(c-a)),f=self.setTimeout(function(){b(c+
-g)},g);a=c+g;return f});void 0===self.cancelAnimationFrame&&void 0!==self.clearTimeout&&(self.cancelAnimationFrame=function(a){self.clearTimeout(a)})}();void 0===self.performance&&(self.performance={});void 0===self.performance.now&&function(){var a=Date.now();self.performance.now=function(){return Date.now()-a}}();void 0===Math.sign&&(Math.sign=function(a){return 0>a?-1:0<a?1:+a});void 0===Function.prototype.name&&void 0!==Object.defineProperty&&Object.defineProperty(Function.prototype,"name",{get:function(){return this.toString().match(/^\s*function\s*(\S*)\s*\(/)[1]}});
-THREE.MOUSE={LEFT:0,MIDDLE:1,RIGHT:2};THREE.CullFaceNone=0;THREE.CullFaceBack=1;THREE.CullFaceFront=2;THREE.CullFaceFrontBack=3;THREE.FrontFaceDirectionCW=0;THREE.FrontFaceDirectionCCW=1;THREE.BasicShadowMap=0;THREE.PCFShadowMap=1;THREE.PCFSoftShadowMap=2;THREE.FrontSide=0;THREE.BackSide=1;THREE.DoubleSide=2;THREE.FlatShading=1;THREE.SmoothShading=2;THREE.NoColors=0;THREE.FaceColors=1;THREE.VertexColors=2;THREE.NoBlending=0;THREE.NormalBlending=1;THREE.AdditiveBlending=2;
-THREE.SubtractiveBlending=3;THREE.MultiplyBlending=4;THREE.CustomBlending=5;THREE.AddEquation=100;THREE.SubtractEquation=101;THREE.ReverseSubtractEquation=102;THREE.MinEquation=103;THREE.MaxEquation=104;THREE.ZeroFactor=200;THREE.OneFactor=201;THREE.SrcColorFactor=202;THREE.OneMinusSrcColorFactor=203;THREE.SrcAlphaFactor=204;THREE.OneMinusSrcAlphaFactor=205;THREE.DstAlphaFactor=206;THREE.OneMinusDstAlphaFactor=207;THREE.DstColorFactor=208;THREE.OneMinusDstColorFactor=209;
-THREE.SrcAlphaSaturateFactor=210;THREE.NeverDepth=0;THREE.AlwaysDepth=1;THREE.LessDepth=2;THREE.LessEqualDepth=3;THREE.EqualDepth=4;THREE.GreaterEqualDepth=5;THREE.GreaterDepth=6;THREE.NotEqualDepth=7;THREE.MultiplyOperation=0;THREE.MixOperation=1;THREE.AddOperation=2;THREE.UVMapping=300;THREE.CubeReflectionMapping=301;THREE.CubeRefractionMapping=302;THREE.EquirectangularReflectionMapping=303;THREE.EquirectangularRefractionMapping=304;THREE.SphericalReflectionMapping=305;THREE.RepeatWrapping=1E3;
-THREE.ClampToEdgeWrapping=1001;THREE.MirroredRepeatWrapping=1002;THREE.NearestFilter=1003;THREE.NearestMipMapNearestFilter=1004;THREE.NearestMipMapLinearFilter=1005;THREE.LinearFilter=1006;THREE.LinearMipMapNearestFilter=1007;THREE.LinearMipMapLinearFilter=1008;THREE.UnsignedByteType=1009;THREE.ByteType=1010;THREE.ShortType=1011;THREE.UnsignedShortType=1012;THREE.IntType=1013;THREE.UnsignedIntType=1014;THREE.FloatType=1015;THREE.HalfFloatType=1025;THREE.UnsignedShort4444Type=1016;
-THREE.UnsignedShort5551Type=1017;THREE.UnsignedShort565Type=1018;THREE.AlphaFormat=1019;THREE.RGBFormat=1020;THREE.RGBAFormat=1021;THREE.LuminanceFormat=1022;THREE.LuminanceAlphaFormat=1023;THREE.RGBEFormat=THREE.RGBAFormat;THREE.RGB_S3TC_DXT1_Format=2001;THREE.RGBA_S3TC_DXT1_Format=2002;THREE.RGBA_S3TC_DXT3_Format=2003;THREE.RGBA_S3TC_DXT5_Format=2004;THREE.RGB_PVRTC_4BPPV1_Format=2100;THREE.RGB_PVRTC_2BPPV1_Format=2101;THREE.RGBA_PVRTC_4BPPV1_Format=2102;THREE.RGBA_PVRTC_2BPPV1_Format=2103;
-THREE.LoopOnce=2200;THREE.LoopRepeat=2201;THREE.LoopPingPong=2202;THREE.Projector=function(){console.error("THREE.Projector has been moved to /examples/js/renderers/Projector.js.");this.projectVector=function(a,b){console.warn("THREE.Projector: .projectVector() is now vector.project().");a.project(b)};this.unprojectVector=function(a,b){console.warn("THREE.Projector: .unprojectVector() is now vector.unproject().");a.unproject(b)};this.pickingRay=function(a,b){console.error("THREE.Projector: .pickingRay() is now raycaster.setFromCamera().")}};
+g)},g);a=c+g;return f});void 0===self.cancelAnimationFrame&&void 0!==self.clearTimeout&&(self.cancelAnimationFrame=function(a){self.clearTimeout(a)})}();void 0===self.performance&&(self.performance={});void 0===self.performance.now&&function(){var a=Date.now();self.performance.now=function(){return Date.now()-a}}();void 0===Number.EPSILON&&(Number.EPSILON=Math.pow(2,-52));void 0===Math.sign&&(Math.sign=function(a){return 0>a?-1:0<a?1:+a});
+void 0===Function.prototype.name&&void 0!==Object.defineProperty&&Object.defineProperty(Function.prototype,"name",{get:function(){return this.toString().match(/^\s*function\s*(\S*)\s*\(/)[1]}});THREE.MOUSE={LEFT:0,MIDDLE:1,RIGHT:2};THREE.CullFaceNone=0;THREE.CullFaceBack=1;THREE.CullFaceFront=2;THREE.CullFaceFrontBack=3;THREE.FrontFaceDirectionCW=0;THREE.FrontFaceDirectionCCW=1;THREE.BasicShadowMap=0;THREE.PCFShadowMap=1;THREE.PCFSoftShadowMap=2;THREE.FrontSide=0;THREE.BackSide=1;
+THREE.DoubleSide=2;THREE.FlatShading=1;THREE.SmoothShading=2;THREE.NoColors=0;THREE.FaceColors=1;THREE.VertexColors=2;THREE.NoBlending=0;THREE.NormalBlending=1;THREE.AdditiveBlending=2;THREE.SubtractiveBlending=3;THREE.MultiplyBlending=4;THREE.CustomBlending=5;THREE.AddEquation=100;THREE.SubtractEquation=101;THREE.ReverseSubtractEquation=102;THREE.MinEquation=103;THREE.MaxEquation=104;THREE.ZeroFactor=200;THREE.OneFactor=201;THREE.SrcColorFactor=202;THREE.OneMinusSrcColorFactor=203;
+THREE.SrcAlphaFactor=204;THREE.OneMinusSrcAlphaFactor=205;THREE.DstAlphaFactor=206;THREE.OneMinusDstAlphaFactor=207;THREE.DstColorFactor=208;THREE.OneMinusDstColorFactor=209;THREE.SrcAlphaSaturateFactor=210;THREE.NeverDepth=0;THREE.AlwaysDepth=1;THREE.LessDepth=2;THREE.LessEqualDepth=3;THREE.EqualDepth=4;THREE.GreaterEqualDepth=5;THREE.GreaterDepth=6;THREE.NotEqualDepth=7;THREE.MultiplyOperation=0;THREE.MixOperation=1;THREE.AddOperation=2;THREE.UVMapping=300;THREE.CubeReflectionMapping=301;
+THREE.CubeRefractionMapping=302;THREE.EquirectangularReflectionMapping=303;THREE.EquirectangularRefractionMapping=304;THREE.SphericalReflectionMapping=305;THREE.RepeatWrapping=1E3;THREE.ClampToEdgeWrapping=1001;THREE.MirroredRepeatWrapping=1002;THREE.NearestFilter=1003;THREE.NearestMipMapNearestFilter=1004;THREE.NearestMipMapLinearFilter=1005;THREE.LinearFilter=1006;THREE.LinearMipMapNearestFilter=1007;THREE.LinearMipMapLinearFilter=1008;THREE.UnsignedByteType=1009;THREE.ByteType=1010;
+THREE.ShortType=1011;THREE.UnsignedShortType=1012;THREE.IntType=1013;THREE.UnsignedIntType=1014;THREE.FloatType=1015;THREE.HalfFloatType=1025;THREE.UnsignedShort4444Type=1016;THREE.UnsignedShort5551Type=1017;THREE.UnsignedShort565Type=1018;THREE.AlphaFormat=1019;THREE.RGBFormat=1020;THREE.RGBAFormat=1021;THREE.LuminanceFormat=1022;THREE.LuminanceAlphaFormat=1023;THREE.RGBEFormat=THREE.RGBAFormat;THREE.RGB_S3TC_DXT1_Format=2001;THREE.RGBA_S3TC_DXT1_Format=2002;THREE.RGBA_S3TC_DXT3_Format=2003;
+THREE.RGBA_S3TC_DXT5_Format=2004;THREE.RGB_PVRTC_4BPPV1_Format=2100;THREE.RGB_PVRTC_2BPPV1_Format=2101;THREE.RGBA_PVRTC_4BPPV1_Format=2102;THREE.RGBA_PVRTC_2BPPV1_Format=2103;THREE.LoopOnce=2200;THREE.LoopRepeat=2201;THREE.LoopPingPong=2202;
+THREE.Projector=function(){console.error("THREE.Projector has been moved to /examples/js/renderers/Projector.js.");this.projectVector=function(a,b){console.warn("THREE.Projector: .projectVector() is now vector.project().");a.project(b)};this.unprojectVector=function(a,b){console.warn("THREE.Projector: .unprojectVector() is now vector.unproject().");a.unproject(b)};this.pickingRay=function(a,b){console.error("THREE.Projector: .pickingRay() is now raycaster.setFromCamera().")}};
 THREE.CanvasRenderer=function(){console.error("THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js");this.domElement=document.createElement("canvas");this.clear=function(){};this.render=function(){};this.setClearColor=function(){};this.setSize=function(){}};THREE.Color=function(a){return 3===arguments.length?this.fromArray(arguments):this.set(a)};
 THREE.Color.prototype={constructor:THREE.Color,r:1,g:1,b:1,set:function(a){a instanceof THREE.Color?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setHex:function(a){a=Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(){function a(a,c,d){0>d&&(d+=1);1<d&&(d-=1);return d<1/6?a+6*(c-a)*d:.5>d?c:d<2/3?a+6*(c-a)*(2/3-d):a}return function(b,
-c,d){b=THREE.Math.euclideanModulo(b,1);c=THREE.Math.clamp(c,0,1);d=THREE.Math.clamp(d,0,1);0===c?this.r=this.g=this.b=d:(c=.5>=d?d*(1+c):d+c-d*c,d=2*d-c,this.r=a(d,c,b+1/3),this.g=a(d,c,b),this.b=a(d,c,b-1/3));return this}}(),setStyle:function(a){function b(b){b=parseFloat(b);1>b&&console.warn("THREE.Color: Alpha component of color "+a+" will be ignored.");return b}var c;if(c=/^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(a)){var d=c[2];switch(c[1]){case "rgb":if(c=/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*$/.exec(d))return this.r=
-Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/255,this.b=Math.min(255,parseInt(c[3],10))/255,this;if(c=/^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b=Math.min(100,parseInt(c[3],10))/100,this;break;case "rgba":if(c=/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([0-9]*\.?[0-9]+)\s*$/.exec(d))return this.r=Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/
-255,this.b=Math.min(255,parseInt(c[3],10))/255,b(c[4]),this;if(c=/^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*([0-9]*\.?[0-9]+)\s*$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b=Math.min(100,parseInt(c[3],10))/100,b(c[4]),this;break;case "hsl":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*$/.exec(d)){var d=parseFloat(c[1]),e=parseInt(c[2],10)/100,g=parseInt(c[3],10)/100;return this.setHSL(d,e,g)}break;case "hsla":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*([0-9]*\.?[0-9]+)\s*$/.exec(d))return d=
-parseFloat(c[1]),e=parseInt(c[2],10)/100,g=parseInt(c[3],10)/100,b(c[4]),this.setHSL(d,e,g)}}else if(c=/^\#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2),16)/255,this;if(6===d)return this.r=parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0<a.length&&(c=THREE.ColorKeywords[a],
+c,d){b=THREE.Math.euclideanModulo(b,1);c=THREE.Math.clamp(c,0,1);d=THREE.Math.clamp(d,0,1);0===c?this.r=this.g=this.b=d:(c=.5>=d?d*(1+c):d+c-d*c,d=2*d-c,this.r=a(d,c,b+1/3),this.g=a(d,c,b),this.b=a(d,c,b-1/3));return this}}(),setStyle:function(a){function b(b){void 0!==b&&1>parseFloat(b)&&console.warn("THREE.Color: Alpha component of "+a+" will be ignored.")}var c;if(c=/^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(a)){var d=c[2];switch(c[1]){case "rgb":case "rgba":if(c=/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=
+Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/255,this.b=Math.min(255,parseInt(c[3],10))/255,b(c[5]),this;if(c=/^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b=Math.min(100,parseInt(c[3],10))/100,b(c[5]),this;break;case "hsl":case "hsla":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d)){var d=parseFloat(c[1])/
+360,e=parseInt(c[2],10)/100,g=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,g)}}}else if(c=/^\#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2),16)/255,this;if(6===d)return this.r=parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0<a.length&&(c=THREE.ColorKeywords[a],
 void 0!==c?this.setHex(c):console.warn("THREE.Color: Unknown color "+a));return this},clone:function(){return new this.constructor(this.r,this.g,this.b)},copy:function(a){this.r=a.r;this.g=a.g;this.b=a.b;return this},copyGammaToLinear:function(a,b){void 0===b&&(b=2);this.r=Math.pow(a.r,b);this.g=Math.pow(a.g,b);this.b=Math.pow(a.b,b);return this},copyLinearToGamma:function(a,b){void 0===b&&(b=2);var c=0<b?1/b:1;this.r=Math.pow(a.r,c);this.g=Math.pow(a.g,c);this.b=Math.pow(a.b,c);return this},convertGammaToLinear:function(){var a=
 this.r,b=this.g,c=this.b;this.r=a*a;this.g=b*b;this.b=c*c;return this},convertLinearToGamma:function(){this.r=Math.sqrt(this.r);this.g=Math.sqrt(this.g);this.b=Math.sqrt(this.b);return this},getHex:function(){return 255*this.r<<16^255*this.g<<8^255*this.b<<0},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getHSL:function(a){a=a||{h:0,s:0,l:0};var b=this.r,c=this.g,d=this.b,e=Math.max(b,c,d),g=Math.min(b,c,d),f,h=(g+e)/2;if(g===e)g=f=0;else{var l=e-g,g=.5>=h?l/(e+g):
 l/(2-e-g);switch(e){case b:f=(c-d)/l+(c<d?6:0);break;case c:f=(d-b)/l+2;break;case d:f=(b-c)/l+4}f/=6}a.h=f;a.s=g;a.l=h;return a},getStyle:function(){return"rgb("+(255*this.r|0)+","+(255*this.g|0)+","+(255*this.b|0)+")"},offsetHSL:function(a,b,c){var d=this.getHSL();d.h+=a;d.s+=b;d.l+=c;this.setHSL(d.h,d.s,d.l);return this},add:function(a){this.r+=a.r;this.g+=a.g;this.b+=a.b;return this},addColors:function(a,b){this.r=a.r+b.r;this.g=a.g+b.g;this.b=a.b+b.b;return this},addScalar:function(a){this.r+=
@@ -37,44 +37,44 @@ Math.sin(b*h)/l;this._w=g*f+this._w*h;this._x=c*f+this._x*h;this._y=d*f+this._y*
 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,get width(){return this.x},set width(a){this.x=a},get height(){return this.y},set height(a){this.y=a},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=a.y);return this},max:function(a){this.x<a.x&&(this.x=a.x);this.y<a.y&&(this.y=a.y);return this},clamp:function(a,b){this.x<a.x?this.x=a.x:this.x>b.x&&(this.x=b.x);this.y<a.y?this.y=a.y:this.y>b.y&&(this.y=b.y);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector2,b=new THREE.Vector2);a.set(c,c);b.set(d,d);return this.clamp(a,b)}}(),floor:function(){this.x=
-Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*
-this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x;a=this.y-a.y;return b*b+a*a},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=
-(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];return this}};
-THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0};
+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){isFinite(a)?(this.x*=a,this.y*=a):this.y=this.x=0;return this},divide:function(a){this.x/=a.x;
+this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector2,b=new THREE.Vector2);a.set(c,c);b.set(d,d);return this.clamp(a,
+b)}}(),clampLength:function(a,b){var c=this.length();this.multiplyScalar(Math.max(a,Math.min(b,c))/c);return this},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=
+-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x;a=this.y-a.y;return b*b+a*a},setLength:function(a){return this.multiplyScalar(a/
+this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=
+a.array[b+1];return this},rotateAround:function(a,b){var c=Math.cos(b),d=Math.sin(b),e=this.x-a.x,g=this.y-a.y;this.x=e*c-g*d+a.x;this.y=e*d+g*c+a.y;return this}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0};
 THREE.Vector3.prototype={constructor:THREE.Vector3,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+
 a);}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a,
 b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),
-this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a;return function(b){!1===b instanceof THREE.Euler&&console.error("THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromEuler(b));return this}}(),
-applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromAxisAngle(b,c));return this}}(),applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},
-applyProjection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,g=a.y,f=a.z;a=a.w;var h=a*b+g*d-f*c,l=a*c+f*b-e*d,k=a*d+e*c-g*b,b=-e*b-g*c-f*d;this.x=h*a+b*-e+l*-f-k*-g;this.y=l*a+b*-g+k*-e-h*-f;this.z=k*a+b*-f+h*-g-l*-e;return this},project:function(){var a;return function(b){void 0===
-a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyProjection(a)}}(),transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;this.normalize();return this},divide:function(a){this.x/=
-a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=a,this.y*=a,this.z*=a):this.z=this.y=this.x=0;return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);return this},max:function(a){this.x<a.x&&(this.x=a.x);this.y<a.y&&(this.y=a.y);this.z<a.z&&(this.z=a.z);return this},clamp:function(a,b){this.x<a.x?this.x=a.x:this.x>b.x&&(this.x=b.x);this.y<a.y?this.y=a.y:this.y>b.y&&(this.y=b.y);this.z<a.z?this.z=a.z:this.z>b.z&&
-(this.z=b.z);return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3,b=new THREE.Vector3);a.set(c,c,c);b.set(d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},
-roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+
-Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},cross:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),
-this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c=a.x,d=a.y,e=a.z,g=b.x,f=b.y,h=b.z;this.x=d*h-e*f;this.y=e*g-c*h;this.z=c*f-d*g;return this},projectOnVector:function(){var a,b;return function(c){void 0===a&&(a=new THREE.Vector3);a.copy(c).normalize();b=this.dot(a);return this.copy(a).multiplyScalar(b)}}(),projectOnPlane:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);a.copy(this).projectOnVector(b);
-return this.sub(a)}}(),reflect:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);return this.sub(a.copy(b).multiplyScalar(2*this.dot(b)))}}(),angleTo:function(a){a=this.dot(a)/(this.length()*a.length());return Math.acos(THREE.Math.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},setEulerFromRotationMatrix:function(a,b){console.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.")},
-setEulerFromQuaternion:function(a,b){console.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.")},getPositionFromMatrix:function(a){console.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().");return this.setFromMatrixPosition(a)},getScaleFromMatrix:function(a){console.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().");return this.setFromMatrixScale(a)},getColumnFromMatrix:function(a,
-b){console.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().");return this.setFromMatrixColumn(a,b)},setFromMatrixPosition:function(a){this.x=a.elements[12];this.y=a.elements[13];this.z=a.elements[14];return this},setFromMatrixScale:function(a){var b=this.set(a.elements[0],a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5],a.elements[6]).length();a=this.set(a.elements[8],a.elements[9],a.elements[10]).length();this.x=b;this.y=c;this.z=
-a;return this},setFromMatrixColumn:function(a,b){var c=4*a,d=b.elements;this.x=d[c];this.y=d[c+1];this.z=d[c+2];return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=
-a.array[b+2];return this}};THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1};
+this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){isFinite(a)?(this.x*=a,this.y*=a,this.z*=a):this.z=this.y=this.x=0;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a;return function(b){!1===b instanceof THREE.Euler&&console.error("THREE.Vector3: .applyEuler() now expects a Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromEuler(b));
+return this}}(),applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromAxisAngle(b,c));return this}}(),applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];
+return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,g=a.y,f=a.z;a=a.w;var h=a*b+g*d-f*c,l=a*c+f*b-e*d,k=a*d+e*c-g*b,b=-e*b-g*c-f*d;this.x=h*a+b*-e+l*-f-k*-g;this.y=l*a+b*-g+k*-e-h*-f;this.z=k*a+b*-f+h*-g-l*-e;return this},project:function(){var a;
+return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyProjection(a)}}(),transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;this.normalize();
+return this},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,
+this.z));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3,b=new THREE.Vector3);a.set(c,c,c);b.set(d,d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();this.multiplyScalar(Math.max(a,Math.min(b,c))/c);return this},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},
+round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},
+length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},cross:function(a,b){if(void 0!==
+b)return console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c=a.x,d=a.y,e=a.z,g=b.x,f=b.y,h=b.z;this.x=d*h-e*f;this.y=e*g-c*h;this.z=c*f-d*g;return this},projectOnVector:function(){var a,b;return function(c){void 0===a&&(a=new THREE.Vector3);a.copy(c).normalize();b=this.dot(a);return this.copy(a).multiplyScalar(b)}}(),
+projectOnPlane:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);return this.sub(a.copy(b).multiplyScalar(2*this.dot(b)))}}(),angleTo:function(a){a=this.dot(a)/(this.length()*a.length());return Math.acos(THREE.Math.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=
+this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},setEulerFromRotationMatrix:function(a,b){console.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.")},setEulerFromQuaternion:function(a,b){console.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.")},getPositionFromMatrix:function(a){console.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().");return this.setFromMatrixPosition(a)},
+getScaleFromMatrix:function(a){console.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().");return this.setFromMatrixScale(a)},getColumnFromMatrix:function(a,b){console.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().");return this.setFromMatrixColumn(a,b)},setFromMatrixPosition:function(a){this.x=a.elements[12];this.y=a.elements[13];this.z=a.elements[14];return this},setFromMatrixScale:function(a){var b=this.set(a.elements[0],
+a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5],a.elements[6]).length();a=this.set(a.elements[8],a.elements[9],a.elements[10]).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){var c=4*a,d=b.elements;this.x=d[c];this.y=d[c+1];this.z=d[c+2];return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===
+a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];return this}};THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1};
 THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;
 case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},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=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},
 addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;this.w+=a.w*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-=
-a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){0!==a?(a=1/a,this.x*=
-a,this.y*=a,this.z*=a,this.w*=a):(this.z=this.y=this.x=0,this.w=1);return this},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var g=a[8],f=a[1],h=a[5],l=a[9];c=a[2];b=a[6];var k=a[10];if(.01>Math.abs(d-f)&&.01>Math.abs(g-c)&&.01>Math.abs(l-b)){if(.1>Math.abs(d+f)&&.1>Math.abs(g+c)&&.1>
-Math.abs(l+b)&&.1>Math.abs(e+h+k-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;k=(k+1)/2;d=(d+f)/4;g=(g+c)/4;l=(l+b)/4;e>h&&e>k?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=g/b):h>k?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h),b=d/c,d=l/c):.01>k?(c=b=.707106781,d=0):(d=Math.sqrt(k),b=g/d,c=l/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-l)*(b-l)+(g-c)*(g-c)+(f-d)*(f-d));.001>Math.abs(a)&&(a=1);this.x=(b-l)/a;this.y=(g-c)/a;this.z=(f-d)/a;this.w=Math.acos((e+h+k-1)/
-2);return this},min:function(a){this.x>a.x&&(this.x=a.x);this.y>a.y&&(this.y=a.y);this.z>a.z&&(this.z=a.z);this.w>a.w&&(this.w=a.w);return this},max:function(a){this.x<a.x&&(this.x=a.x);this.y<a.y&&(this.y=a.y);this.z<a.z&&(this.z=a.z);this.w<a.w&&(this.w=a.w);return this},clamp:function(a,b){this.x<a.x?this.x=a.x:this.x>b.x&&(this.x=b.x);this.y<a.y?this.y=a.y:this.y>b.y&&(this.y=b.y);this.z<a.z?this.z=a.z:this.z>b.z&&(this.z=b.z);this.w<a.w?this.w=a.w:this.w>b.w&&(this.w=b.w);return this},clampScalar:function(){var a,
-b;return function(c,d){void 0===a&&(a=new THREE.Vector4,b=new THREE.Vector4);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);
-return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},
-length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){var b=this.length();0!==b&&a!==b&&this.multiplyScalar(a/b);return this},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,
-c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];this.w=
-a.array[b+3];return this}};THREE.Euler=function(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||THREE.Euler.DefaultOrder};THREE.Euler.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" ");THREE.Euler.DefaultOrder="XYZ";
+a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){isFinite(a)?(this.x*=a,this.y*=a,this.z*=a,this.w*=a):this.w=this.z=this.y=this.x=0;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},
+divideScalar:function(a){return this.multiplyScalar(1/a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var g=a[8],f=a[1],h=a[5],l=a[9];c=a[2];b=a[6];var k=a[10];if(.01>Math.abs(d-f)&&.01>Math.abs(g-c)&&.01>Math.abs(l-b)){if(.1>Math.abs(d+f)&&.1>Math.abs(g+c)&&.1>Math.abs(l+b)&&.1>Math.abs(e+
+h+k-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;k=(k+1)/2;d=(d+f)/4;g=(g+c)/4;l=(l+b)/4;e>h&&e>k?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=g/b):h>k?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h),b=d/c,d=l/c):.01>k?(c=b=.707106781,d=0):(d=Math.sqrt(k),b=g/d,c=l/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-l)*(b-l)+(g-c)*(g-c)+(f-d)*(f-d));.001>Math.abs(a)&&(a=1);this.x=(b-l)/a;this.y=(g-c)/a;this.z=(f-d)/a;this.w=Math.acos((e+h+k-1)/2);return this},min:function(a){this.x=
+Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));this.w=Math.max(a.w,Math.min(b.w,this.w));return this},clampScalar:function(){var a,b;return function(c,
+d){void 0===a&&(a=new THREE.Vector4,b=new THREE.Vector4);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},
+roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*
+this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===
+this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];this.w=a.array[b+3];return this}};
+THREE.Euler=function(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||THREE.Euler.DefaultOrder};THREE.Euler.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" ");THREE.Euler.DefaultOrder="XYZ";
 THREE.Euler.prototype={constructor:THREE.Euler,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get order(){return this._order},set order(a){this._order=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this.onChangeCallback();return this},clone:function(){return new this.constructor(this._x,
-this._y,this._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=THREE.Math.clamp,e=a.elements;a=e[0];var g=e[4],f=e[8],h=e[1],l=e[5],k=e[9],n=e[2],p=e[6],e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(-k,e),this._z=Math.atan2(-g,a)):(this._x=Math.atan2(p,l),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(k,-1,1)),.99999>Math.abs(k)?
-(this._y=Math.atan2(f,e),this._z=Math.atan2(h,l)):(this._y=Math.atan2(-n,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(p,-1,1)),.99999>Math.abs(p)?(this._y=Math.atan2(-n,e),this._z=Math.atan2(-g,l)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(n,-1,1)),.99999>Math.abs(n)?(this._x=Math.atan2(p,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-g,l))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-k,l),this._y=Math.atan2(-n,a)):(this._x=
+this._y,this._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=THREE.Math.clamp,e=a.elements;a=e[0];var g=e[4],f=e[8],h=e[1],l=e[5],k=e[9],m=e[2],p=e[6],e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(-k,e),this._z=Math.atan2(-g,a)):(this._x=Math.atan2(p,l),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(k,-1,1)),.99999>Math.abs(k)?
+(this._y=Math.atan2(f,e),this._z=Math.atan2(h,l)):(this._y=Math.atan2(-m,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(p,-1,1)),.99999>Math.abs(p)?(this._y=Math.atan2(-m,e),this._z=Math.atan2(-g,l)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(m,-1,1)),.99999>Math.abs(m)?(this._x=Math.atan2(p,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-g,l))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-k,l),this._y=Math.atan2(-m,a)):(this._x=
 0,this._y=Math.atan2(f,e))):"XZY"===b?(this._z=Math.asin(-d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(p,l),this._y=Math.atan2(f,a)):(this._x=Math.atan2(-k,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeRotationFromQuaternion(b);this.setFromRotationMatrix(a,c,d);return this}}(),setFromVector3:function(a,
 b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(){var a=new THREE.Quaternion;return function(b){a.setFromEuler(this);this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+
 3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new THREE.Vector3(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}};THREE.Line3=function(a,b){this.start=void 0!==a?a:new THREE.Vector3;this.end=void 0!==b?b:new THREE.Vector3};
@@ -100,33 +100,33 @@ 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,l,k,n,p,m,q,t,s){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]=l;u[6]=k;u[10]=n;u[14]=p;u[3]=m;u[7]=q;u[11]=t;u[15]=s;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,l,k,m,p,n,q,s,t){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]=l;v[6]=k;v[10]=m;v[14]=p;v[3]=n;v[7]=q;v[11]=s;v[15]=t;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 l=g*e,k=c*h,n=c*e;b[0]=f*h;b[4]=-f*e;b[8]=d;b[1]=l+k*d;b[5]=a-n*d;b[9]=-c*f;b[2]=n-a*d;b[6]=k+l*d;b[10]=g*f}else"YXZ"===a.order?(a=f*h,l=f*e,k=d*h,n=d*e,b[0]=a+n*c,b[4]=k*c-l,b[8]=g*d,b[1]=g*e,b[5]=g*h,b[9]=-c,b[2]=l*c-k,b[6]=n+a*c,b[10]=g*f):"ZXY"===a.order?(a=f*h,l=f*e,k=d*h,n=d*e,b[0]=a-n*c,b[4]=-g*e,b[8]=k+l*c,b[1]=l+k*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,l=g*e,k=c*h,n=c*e,b[0]=f*h,b[4]=k*d-l,b[8]=a*d+n,b[1]=f*e,b[5]=
-n*d+a,b[9]=l*d-k,b[2]=-d,b[6]=c*f,b[10]=g*f):"YZX"===a.order?(a=g*f,l=g*d,k=c*f,n=c*d,b[0]=f*h,b[4]=n-a*e,b[8]=k*e+l,b[1]=e,b[5]=g*h,b[9]=-c*h,b[2]=-d*h,b[6]=l*e+k,b[10]=a-n*e):"XZY"===a.order&&(a=g*f,l=g*d,k=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]=l*e-k,b[2]=k*e-l,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,l=e+e;a=c*f;var k=c*h,c=c*l,n=d*h,d=d*l,e=e*l,f=g*f,h=g*h,g=g*l;b[0]=1-(n+e);b[4]=k-g;b[8]=c+h;b[1]=k+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],l=c[12],k=c[1],n=c[5],p=c[9],m=c[13],q=c[2],t=c[6],s=c[10],u=c[14],x=c[3],v=c[7],D=c[11],c=c[15],w=d[0],A=d[4],B=d[8],z=d[12],y=d[1],L=d[5],G=d[9],C=d[13],N=d[2],M=d[6],O=d[10],K=d[14],E=d[3],J=d[7],Q=d[11],d=d[15];e[0]=g*w+f*y+h*N+l*E;e[4]=g*A+f*L+h*M+l*J;e[8]=g*B+f*G+h*O+l*Q;e[12]=g*z+f*C+h*K+l*d;e[1]=k*w+n*y+p*N+m*E;e[5]=k*A+n*L+p*M+m*J;e[9]=k*B+n*G+p*O+m*Q;e[13]=k*z+n*C+p*K+m*d;e[2]=q*w+t*y+s*N+u*E;e[6]=q*A+t*L+s*M+u*J;e[10]=
-q*B+t*G+s*O+u*Q;e[14]=q*z+t*C+s*K+u*d;e[3]=x*w+v*y+D*N+c*E;e[7]=x*A+v*L+D*M+c*J;e[11]=x*B+v*G+D*O+c*Q;e[15]=x*z+v*C+D*K+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.");
+e=Math.sin(e);if("XYZ"===a.order){a=g*h;var l=g*e,k=c*h,m=c*e;b[0]=f*h;b[4]=-f*e;b[8]=d;b[1]=l+k*d;b[5]=a-m*d;b[9]=-c*f;b[2]=m-a*d;b[6]=k+l*d;b[10]=g*f}else"YXZ"===a.order?(a=f*h,l=f*e,k=d*h,m=d*e,b[0]=a+m*c,b[4]=k*c-l,b[8]=g*d,b[1]=g*e,b[5]=g*h,b[9]=-c,b[2]=l*c-k,b[6]=m+a*c,b[10]=g*f):"ZXY"===a.order?(a=f*h,l=f*e,k=d*h,m=d*e,b[0]=a-m*c,b[4]=-g*e,b[8]=k+l*c,b[1]=l+k*c,b[5]=g*h,b[9]=m-a*c,b[2]=-g*d,b[6]=c,b[10]=g*f):"ZYX"===a.order?(a=g*h,l=g*e,k=c*h,m=c*e,b[0]=f*h,b[4]=k*d-l,b[8]=a*d+m,b[1]=f*e,b[5]=
+m*d+a,b[9]=l*d-k,b[2]=-d,b[6]=c*f,b[10]=g*f):"YZX"===a.order?(a=g*f,l=g*d,k=c*f,m=c*d,b[0]=f*h,b[4]=m-a*e,b[8]=k*e+l,b[1]=e,b[5]=g*h,b[9]=-c*h,b[2]=-d*h,b[6]=l*e+k,b[10]=a-m*e):"XZY"===a.order&&(a=g*f,l=g*d,k=c*f,m=c*d,b[0]=f*h,b[4]=-e,b[8]=d*h,b[1]=a*e+m,b[5]=g*h,b[9]=l*e-k,b[2]=k*e-l,b[6]=c*h,b[10]=m*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,l=e+e;a=c*f;var k=c*h,c=c*l,m=d*h,d=d*l,e=e*l,f=g*f,h=g*h,g=g*l;b[0]=1-(m+e);b[4]=k-g;b[8]=c+h;b[1]=k+g;b[5]=1-(a+e);b[9]=d-f;b[2]=c-h;b[6]=d+f;b[10]=1-(a+m);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.lengthSq()&&(c.z=1);a.crossVectors(g,c).normalize();0===a.lengthSq()&&(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],l=c[12],k=c[1],m=c[5],p=c[9],n=c[13],q=c[2],s=c[6],t=c[10],v=c[14],u=c[3],w=c[7],D=c[11],c=c[15],x=d[0],B=d[4],y=d[8],z=d[12],A=d[1],J=d[5],F=d[9],C=d[13],N=d[2],L=d[6],Q=d[10],M=d[14],K=d[3],E=d[7],O=d[11],d=d[15];e[0]=g*x+f*A+h*N+l*K;e[4]=g*B+f*J+h*L+l*E;e[8]=g*y+f*F+h*Q+l*O;e[12]=g*z+f*C+h*M+l*d;e[1]=k*x+m*A+p*N+n*K;e[5]=k*B+m*J+p*L+n*E;e[9]=k*y+m*F+p*Q+n*O;e[13]=k*z+m*C+p*M+n*d;e[2]=q*x+s*A+t*N+v*
+K;e[6]=q*B+s*J+t*L+v*E;e[10]=q*y+s*F+t*Q+v*O;e[14]=q*z+s*C+t*M+v*d;e[3]=u*x+w*A+D*N+c*K;e[7]=u*B+w*J+D*L+c*E;e[11]=u*y+w*F+D*Q+c*O;e[15]=u*z+w*C+D*M+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],l=a[13],k=a[2],n=a[6],p=a[10],m=a[14];return a[3]*(+e*h*n-d*l*
-n-e*f*p+c*l*p+d*f*m-c*h*m)+a[7]*(+b*h*m-b*l*p+e*g*p-d*g*m+d*l*k-e*h*k)+a[11]*(+b*l*n-b*f*m-e*g*n+c*g*m+e*f*k-c*l*k)+a[15]*(-d*f*k-b*h*n+b*f*p+d*g*n-c*g*p+c*h*k)},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]=
+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],l=a[13],k=a[2],m=a[6],p=a[10],n=a[14];return a[3]*(+e*h*m-d*l*
+m-e*f*p+c*l*p+d*f*n-c*h*n)+a[7]*(+b*h*n-b*l*p+e*g*p-d*g*n+d*l*k-e*h*k)+a[11]*(+b*l*m-b*f*n-e*g*m+c*g*n+e*f*k-c*l*k)+a[15]*(-d*f*k-b*h*m+b*f*p+d*g*m-c*g*p+c*h*k)},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],l=d[1],k=d[5],n=d[9],p=d[13],m=d[2],q=d[6],t=d[10],s=d[14],u=d[3],x=d[7],v=d[11],d=d[15];c[0]=n*s*x-p*t*x+p*q*v-k*s*v-n*q*d+k*t*d;c[4]=h*t*x-f*s*x-h*q*v+g*s*v+f*q*d-g*t*d;c[8]=f*p*x-h*n*x+h*k*v-g*p*v-f*k*d+g*n*d;c[12]=h*n*q-f*p*q-h*k*t+g*p*t+f*k*s-g*n*s;c[1]=p*t*u-n*s*u-p*m*v+l*s*v+n*m*d-l*t*d;c[5]=f*s*u-h*t*u+h*m*v-e*s*v-f*m*d+e*t*d;c[9]=h*n*u-f*p*u-h*l*v+e*p*v+f*l*d-e*n*d;c[13]=f*p*m-h*n*m+h*l*t-e*p*t-f*l*s+e*n*s;c[2]=k*s*u-p*q*u+p*m*x-l*s*
-x-k*m*d+l*q*d;c[6]=h*q*u-g*s*u-h*m*x+e*s*x+g*m*d-e*q*d;c[10]=g*p*u-h*k*u+h*l*x-e*p*x-g*l*d+e*k*d;c[14]=h*k*m-g*p*m-h*l*q+e*p*q+g*l*s-e*k*s;c[3]=n*q*u-k*t*u-n*m*x+l*t*x+k*m*v-l*q*v;c[7]=g*t*u-f*q*u+f*m*x-e*t*x-g*m*v+e*q*v;c[11]=f*k*u-g*n*u-f*l*x+e*n*x+g*l*v-e*k*v;c[15]=g*n*m-f*k*m+f*l*q-e*n*q-g*l*t+e*k*t;c=e*c[0]+l*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],l=d[1],k=d[5],m=d[9],p=d[13],n=d[2],q=d[6],s=d[10],t=d[14],v=d[3],u=d[7],w=d[11],d=d[15];c[0]=m*t*u-p*s*u+p*q*w-k*t*w-m*q*d+k*s*d;c[4]=h*s*u-f*t*u-h*q*w+g*t*w+f*q*d-g*s*d;c[8]=f*p*u-h*m*u+h*k*w-g*p*w-f*k*d+g*m*d;c[12]=h*m*q-f*p*q-h*k*s+g*p*s+f*k*t-g*m*t;c[1]=p*s*v-m*t*v-p*n*w+l*t*w+m*n*d-l*s*d;c[5]=f*t*v-h*s*v+h*n*w-e*t*w-f*n*d+e*s*d;c[9]=h*m*v-f*p*v-h*l*w+e*p*w+f*l*d-e*m*d;c[13]=f*p*n-h*m*n+h*l*s-e*p*s-f*l*t+e*m*t;c[2]=k*t*v-p*q*v+p*n*u-l*t*
+u-k*n*d+l*q*d;c[6]=h*q*v-g*t*v-h*n*u+e*t*u+g*n*d-e*q*d;c[10]=g*p*v-h*k*v+h*l*u-e*p*u-g*l*d+e*k*d;c[14]=h*k*n-g*p*n-h*l*q+e*p*q+g*l*t-e*k*t;c[3]=m*q*v-k*s*v-m*n*u+l*s*u+k*n*w-l*q*w;c[7]=g*s*v-f*q*v+f*n*u-e*s*u-g*n*w+e*q*w;c[11]=f*k*v-g*m*v-f*l*u+e*m*u+g*l*w-e*k*w;c[15]=g*m*n-f*k*n+f*l*q-e*m*q-g*l*s+e*k*s;c=e*c[0]+l*c[4]+n*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,l=e*g,k=e*f;this.set(l*g+c,l*f-d*h,l*h+d*f,0,l*f+d*h,k*f+c,k*h-d*g,0,l*h-d*f,k*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,
-0,0,0,0,c,0,0,0,0,1);return this},compose:function(a,b,c){this.makeRotationFromQuaternion(b);this.scale(c);this.setPosition(a);return this},decompose:function(){var a,b;return function(c,d,e){void 0===a&&(a=new THREE.Vector3);void 0===b&&(b=new THREE.Matrix4);var g=this.elements,f=a.set(g[0],g[1],g[2]).length(),h=a.set(g[4],g[5],g[6]).length(),l=a.set(g[8],g[9],g[10]).length();0>this.determinant()&&(f=-f);c.x=g[12];c.y=g[13];c.z=g[14];b.elements.set(this.elements);c=1/f;var g=1/h,k=1/l;b.elements[0]*=
-c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=g;b.elements[5]*=g;b.elements[6]*=g;b.elements[8]*=k;b.elements[9]*=k;b.elements[10]*=k;d.setFromRotationMatrix(b);e.x=f;e.y=h;e.z=l;return this}}(),makeFrustum:function(a,b,c,d,e,g){var f=this.elements;f[0]=2*e/(b-a);f[4]=0;f[8]=(b+a)/(b-a);f[12]=0;f[1]=0;f[5]=2*e/(d-c);f[9]=(d+c)/(d-c);f[13]=0;f[2]=0;f[6]=0;f[10]=-(g+e)/(g-e);f[14]=-2*g*e/(g-e);f[3]=0;f[7]=0;f[11]=-1;f[15]=0;return this},makePerspective:function(a,b,c,d){a=c*Math.tan(THREE.Math.degToRad(.5*
-a));var e=-a;return this.makeFrustum(e*b,a*b,e,a,c,d)},makeOrthographic:function(a,b,c,d,e,g){var f=this.elements,h=b-a,l=c-d,k=g-e;f[0]=2/h;f[4]=0;f[8]=0;f[12]=-((b+a)/h);f[1]=0;f[5]=2/l;f[9]=0;f[13]=-((c+d)/l);f[2]=0;f[6]=0;f[10]=-2/k;f[14]=-((g+e)/k);f[3]=0;f[7]=0;f[11]=0;f[15]=1;return this},equals:function(a){var b=this.elements;a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a){this.elements.set(a);return this},toArray:function(){var a=this.elements;return[a[0],
+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],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,l=e*g,k=e*f;this.set(l*g+c,l*f-d*h,l*h+d*f,0,l*f+d*h,k*f+c,k*h-d*g,0,l*h-d*f,k*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,0,0,0,0,c,
+0,0,0,0,1);return this},compose:function(a,b,c){this.makeRotationFromQuaternion(b);this.scale(c);this.setPosition(a);return this},decompose:function(){var a,b;return function(c,d,e){void 0===a&&(a=new THREE.Vector3);void 0===b&&(b=new THREE.Matrix4);var g=this.elements,f=a.set(g[0],g[1],g[2]).length(),h=a.set(g[4],g[5],g[6]).length(),l=a.set(g[8],g[9],g[10]).length();0>this.determinant()&&(f=-f);c.x=g[12];c.y=g[13];c.z=g[14];b.elements.set(this.elements);c=1/f;var g=1/h,k=1/l;b.elements[0]*=c;b.elements[1]*=
+c;b.elements[2]*=c;b.elements[4]*=g;b.elements[5]*=g;b.elements[6]*=g;b.elements[8]*=k;b.elements[9]*=k;b.elements[10]*=k;d.setFromRotationMatrix(b);e.x=f;e.y=h;e.z=l;return this}}(),makeFrustum:function(a,b,c,d,e,g){var f=this.elements;f[0]=2*e/(b-a);f[4]=0;f[8]=(b+a)/(b-a);f[12]=0;f[1]=0;f[5]=2*e/(d-c);f[9]=(d+c)/(d-c);f[13]=0;f[2]=0;f[6]=0;f[10]=-(g+e)/(g-e);f[14]=-2*g*e/(g-e);f[3]=0;f[7]=0;f[11]=-1;f[15]=0;return this},makePerspective:function(a,b,c,d){a=c*Math.tan(THREE.Math.degToRad(.5*a));
+var e=-a;return this.makeFrustum(e*b,a*b,e,a,c,d)},makeOrthographic:function(a,b,c,d,e,g){var f=this.elements,h=b-a,l=c-d,k=g-e;f[0]=2/h;f[4]=0;f[8]=0;f[12]=-((b+a)/h);f[1]=0;f[5]=2/l;f[9]=0;f[13]=-((c+d)/l);f[2]=0;f[6]=0;f[10]=-2/k;f[14]=-((g+e)/k);f[3]=0;f[7]=0;f[11]=0;f[15]=1;return this},equals:function(a){var b=this.elements;a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a){this.elements.set(a);return this},toArray:function(){var a=this.elements;return[a[0],
 a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15]]}};THREE.Ray=function(a,b){this.origin=void 0!==a?a:new THREE.Vector3;this.direction=void 0!==b?b:new THREE.Vector3};
 THREE.Ray.prototype={constructor:THREE.Ray,set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){return(b||new THREE.Vector3).copy(this.direction).multiplyScalar(a).add(this.origin)},recast:function(){var a=new THREE.Vector3;return function(b){this.origin.copy(this.at(b,a));return this}}(),closestPointToPoint:function(a,
 b){var c=b||new THREE.Vector3;c.subVectors(a,this.origin);var d=c.dot(this.direction);return 0>d?c.copy(this.origin):c.copy(this.direction).multiplyScalar(d).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(){var a=new THREE.Vector3;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceToSquared(b);a.copy(this.direction).multiplyScalar(c).add(this.origin);return a.distanceToSquared(b)}}(),
-distanceSqToSegment:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3;return function(d,e,g,f){a.copy(d).add(e).multiplyScalar(.5);b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a);var h=.5*d.distanceTo(e),l=-this.direction.dot(b),k=c.dot(this.direction),n=-c.dot(b),p=c.lengthSq(),m=Math.abs(1-l*l),q;0<m?(d=l*n-k,e=l*k-n,q=h*m,0<=d?e>=-q?e<=q?(h=1/m,d*=h,e*=h,l=d*(d+l*e+2*k)+e*(l*d+e+2*n)+p):(e=h,d=Math.max(0,-(l*e+k)),l=-d*d+e*(e+2*n)+p):(e=-h,d=Math.max(0,-(l*e+k)),
-l=-d*d+e*(e+2*n)+p):e<=-q?(d=Math.max(0,-(-l*h+k)),e=0<d?-h:Math.min(Math.max(-h,-n),h),l=-d*d+e*(e+2*n)+p):e<=q?(d=0,e=Math.min(Math.max(-h,-n),h),l=e*(e+2*n)+p):(d=Math.max(0,-(l*h+k)),e=0<d?h:Math.min(Math.max(-h,-n),h),l=-d*d+e*(e+2*n)+p)):(e=0<l?-h:h,d=Math.max(0,-(l*e+k)),l=-d*d+e*(e+2*n)+p);g&&g.copy(this.direction).multiplyScalar(d).add(this.origin);f&&f.copy(b).multiplyScalar(e).add(a);return l}}(),isIntersectionSphere:function(a){return this.distanceToPoint(a.center)<=a.radius},intersectSphere:function(){var a=
+distanceSqToSegment:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3;return function(d,e,g,f){a.copy(d).add(e).multiplyScalar(.5);b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a);var h=.5*d.distanceTo(e),l=-this.direction.dot(b),k=c.dot(this.direction),m=-c.dot(b),p=c.lengthSq(),n=Math.abs(1-l*l),q;0<n?(d=l*m-k,e=l*k-m,q=h*n,0<=d?e>=-q?e<=q?(h=1/n,d*=h,e*=h,l=d*(d+l*e+2*k)+e*(l*d+e+2*m)+p):(e=h,d=Math.max(0,-(l*e+k)),l=-d*d+e*(e+2*m)+p):(e=-h,d=Math.max(0,-(l*e+k)),
+l=-d*d+e*(e+2*m)+p):e<=-q?(d=Math.max(0,-(-l*h+k)),e=0<d?-h:Math.min(Math.max(-h,-m),h),l=-d*d+e*(e+2*m)+p):e<=q?(d=0,e=Math.min(Math.max(-h,-m),h),l=e*(e+2*m)+p):(d=Math.max(0,-(l*h+k)),e=0<d?h:Math.min(Math.max(-h,-m),h),l=-d*d+e*(e+2*m)+p)):(e=0<l?-h:h,d=Math.max(0,-(l*e+k)),l=-d*d+e*(e+2*m)+p);g&&g.copy(this.direction).multiplyScalar(d).add(this.origin);f&&f.copy(b).multiplyScalar(e).add(a);return l}}(),isIntersectionSphere:function(a){return this.distanceToPoint(a.center)<=a.radius},intersectSphere:function(){var a=
 new THREE.Vector3;return function(b,c){a.subVectors(b.center,this.origin);var d=a.dot(this.direction),e=a.dot(a)-d*d,g=b.radius*b.radius;if(e>g)return null;g=Math.sqrt(g-e);e=d-g;d+=g;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),isIntersectionPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0===b)return 0===a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+
 a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){var c=this.distanceToPlane(a);return null===c?null:this.at(c,b)},isIntersectionBox:function(){var a=new THREE.Vector3;return function(b){return null!==this.intersectBox(b,a)}}(),intersectBox:function(a,b){var c,d,e,g,f;d=1/this.direction.x;g=1/this.direction.y;f=1/this.direction.z;var h=this.origin;0<=d?(c=(a.min.x-h.x)*d,d*=a.max.x-h.x):(c=(a.max.x-h.x)*d,d*=a.min.x-h.x);0<=g?(e=(a.min.y-h.y)*g,g*=a.max.y-h.y):(e=(a.max.y-h.y)*g,g*=a.min.y-
 h.y);if(c>g||e>d)return null;if(e>c||c!==c)c=e;if(g<d||d!==d)d=g;0<=f?(e=(a.min.z-h.z)*f,f*=a.max.z-h.z):(e=(a.max.z-h.z)*f,f*=a.min.z-h.z);if(c>f||e>d)return null;if(e>c||c!==c)c=e;if(f<d||d!==d)d=f;return 0>d?null:this.at(0<=c?c:d,b)},intersectTriangle:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3,d=new THREE.Vector3;return function(e,g,f,h,l){b.subVectors(g,e);c.subVectors(f,e);d.crossVectors(b,c);g=this.direction.dot(d);if(0<g){if(h)return null;h=1}else if(0>g)h=-1,
@@ -136,8 +136,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],l=c[6],k=c[7],n=c[8],p=c[9],m=c[10],q=c[11],t=c[12],s=c[13],u=c[14],
-c=c[15];b[0].setComponents(g-a,k-f,q-n,c-t).normalize();b[1].setComponents(g+a,k+f,q+n,c+t).normalize();b[2].setComponents(g+d,k+h,q+p,c+s).normalize();b[3].setComponents(g-d,k-h,q-p,c-s).normalize();b[4].setComponents(g-e,k-l,q-m,c-u).normalize();b[5].setComponents(g+e,k+l,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],l=c[6],k=c[7],m=c[8],p=c[9],n=c[10],q=c[11],s=c[12],t=c[13],v=c[14],
+c=c[15];b[0].setComponents(g-a,k-f,q-m,c-s).normalize();b[1].setComponents(g+a,k+f,q+m,c+s).normalize();b[2].setComponents(g+d,k+h,q+p,c+t).normalize();b[3].setComponents(g-d,k-h,q-p,c-t).normalize();b[4].setComponents(g-e,k-l,q-n,c-v).normalize();b[5].setComponents(g+e,k+l,q+n,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,
@@ -145,26 +145,26 @@ c);return this}}(),clone:function(){return(new this.constructor).copy(this)},cop
 b){return this.orthoPoint(a,b).sub(a).negate()},orthoPoint:function(a,b){var c=this.distanceToPoint(a);return(b||new THREE.Vector3).copy(this.normal).multiplyScalar(c)},isIntersectionLine:function(a){var b=this.distanceToPoint(a.start);a=this.distanceToPoint(a.end);return 0>b&&0<a||0>a&&0<b},intersectLine:function(){var a=new THREE.Vector3;return function(b,c){var d=c||new THREE.Vector3,e=b.delta(a),g=this.normal.dot(e);if(0===g){if(0===this.distanceToPoint(b.start))return d.copy(b.start)}else return g=
 -(b.start.dot(this.normal)+this.constant)/g,0>g||1<g?void 0:d.copy(e).multiplyScalar(g).add(b.start)}}(),coplanarPoint:function(a){return(a||new THREE.Vector3).copy(this.normal).multiplyScalar(-this.constant)},applyMatrix4:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Matrix3;return function(d,e){var g=e||c.getNormalMatrix(d),g=a.copy(this.normal).applyMatrix3(g),f=this.coplanarPoint(b);f.applyMatrix4(d);this.setFromNormalAndCoplanarPoint(g,f);return this}}(),translate:function(a){this.constant-=
 a.dot(this.normal);return this},equals:function(a){return a.normal.equals(this.normal)&&a.constant===this.constant}};
-THREE.Math={generateUUID:function(){var a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),b=Array(36),c=0,d;return function(){for(var e=0;36>e;e++)8===e||13===e||18===e||23===e?b[e]="-":14===e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19===e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return a<b?b:a>c?c:a},clampBottom:function(a,b){return a<b?b:a},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+
-(a-b)*(e-d)/(c-b)},smoothstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){return(65280*Math.random()+255*Math.random())/65535},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(){var a=Math.PI/
-180;return function(b){return b*a}}(),radToDeg:function(){var a=180/Math.PI;return function(b){return b*a}}(),isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},nextPowerOfTwo:function(a){a--;a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;a++;return a}};
-THREE.Spline=function(a){function b(a,b,c,d,e,g,f){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*f+(-3*(b-c)-2*a-d)*g+a*e+b}this.points=a;var c=[],d={x:0,y:0,z:0},e,g,f,h,l,k,n,p,m;this.initFromArray=function(a){this.points=[];for(var b=0;b<a.length;b++)this.points[b]={x:a[b][0],y:a[b][1],z:a[b][2]}};this.getPoint=function(a){e=(this.points.length-1)*a;g=Math.floor(e);f=e-g;c[0]=0===g?g:g-1;c[1]=g;c[2]=g>this.points.length-2?this.points.length-1:g+1;c[3]=g>this.points.length-3?this.points.length-1:g+
-2;k=this.points[c[0]];n=this.points[c[1]];p=this.points[c[2]];m=this.points[c[3]];h=f*f;l=f*h;d.x=b(k.x,n.x,p.x,m.x,f,h,l);d.y=b(k.y,n.y,p.y,m.y,f,h,l);d.z=b(k.z,n.z,p.z,m.z,f,h,l);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;a<c;a++)b=this.points[a],d[a]=[b.x,b.y,b.z];return d};this.getLength=function(a){var b,c,d,e=b=b=0,g=new THREE.Vector3,f=new THREE.Vector3,h=[],l=0;h[0]=0;a||(a=100);c=this.points.length*a;g.copy(this.points[0]);for(a=1;a<c;a++)b=
+THREE.Math={generateUUID:function(){var a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),b=Array(36),c=0,d;return function(){for(var e=0;36>e;e++)8===e||13===e||18===e||23===e?b[e]="-":14===e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19===e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return Math.max(b,Math.min(c,a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},smoothstep:function(a,
+b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){return(65280*Math.random()+255*Math.random())/65535},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(){var a=Math.PI/180;return function(b){return b*a}}(),
+radToDeg:function(){var a=180/Math.PI;return function(b){return b*a}}(),isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},nearestPowerOfTwo:function(a){return Math.pow(2,Math.round(Math.log(a)/Math.LN2))},nextPowerOfTwo:function(a){a--;a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;a++;return a}};
+THREE.Spline=function(a){function b(a,b,c,d,e,g,f){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*f+(-3*(b-c)-2*a-d)*g+a*e+b}this.points=a;var c=[],d={x:0,y:0,z:0},e,g,f,h,l,k,m,p,n;this.initFromArray=function(a){this.points=[];for(var b=0;b<a.length;b++)this.points[b]={x:a[b][0],y:a[b][1],z:a[b][2]}};this.getPoint=function(a){e=(this.points.length-1)*a;g=Math.floor(e);f=e-g;c[0]=0===g?g:g-1;c[1]=g;c[2]=g>this.points.length-2?this.points.length-1:g+1;c[3]=g>this.points.length-3?this.points.length-1:g+
+2;k=this.points[c[0]];m=this.points[c[1]];p=this.points[c[2]];n=this.points[c[3]];h=f*f;l=f*h;d.x=b(k.x,m.x,p.x,n.x,f,h,l);d.y=b(k.y,m.y,p.y,n.y,f,h,l);d.z=b(k.z,m.z,p.z,n.z,f,h,l);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;a<c;a++)b=this.points[a],d[a]=[b.x,b.y,b.z];return d};this.getLength=function(a){var b,c,d,e=b=b=0,g=new THREE.Vector3,f=new THREE.Vector3,h=[],l=0;h[0]=0;a||(a=100);c=this.points.length*a;g.copy(this.points[0]);for(a=1;a<c;a++)b=
 a/c,d=this.getPoint(b),f.copy(d),l+=f.distanceTo(g),g.copy(d),b*=this.points.length-1,b=Math.floor(b),b!==e&&(h[b]=l,e=b);h[h.length]=l;return{chunks:h,total:l}};this.reparametrizeByArcLength=function(a){var b,c,d,e,g,f,h=[],l=new THREE.Vector3,k=this.getLength();h.push(l.copy(this.points[0]).clone());for(b=1;b<this.points.length;b++){c=k.chunks[b]-k.chunks[b-1];f=Math.ceil(a*c/k.total);e=(b-1)/(this.points.length-1);g=b/(this.points.length-1);for(c=1;c<f-1;c++)d=e+1/f*c*(g-e),d=this.getPoint(d),
 h.push(l.copy(d).clone());h.push(l.copy(this.points[b]).clone())}this.points=h}};THREE.Triangle=function(a,b,c){this.a=void 0!==a?a:new THREE.Vector3;this.b=void 0!==b?b:new THREE.Vector3;this.c=void 0!==c?c:new THREE.Vector3};THREE.Triangle.normal=function(){var a=new THREE.Vector3;return function(b,c,d,e){e=e||new THREE.Vector3;e.subVectors(d,c);a.subVectors(b,c);e.cross(a);b=e.lengthSq();return 0<b?e.multiplyScalar(1/Math.sqrt(b)):e.set(0,0,0)}}();
 THREE.Triangle.barycoordFromPoint=function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3;return function(d,e,g,f,h){a.subVectors(f,e);b.subVectors(g,e);c.subVectors(d,e);d=a.dot(a);e=a.dot(b);g=a.dot(c);var l=b.dot(b);f=b.dot(c);var k=d*l-e*e;h=h||new THREE.Vector3;if(0===k)return h.set(-2,-1,-1);k=1/k;l=(l*g-e*f)*k;d=(d*f-e*g)*k;return h.set(1-l-d,d,l)}}();
 THREE.Triangle.containsPoint=function(){var a=new THREE.Vector3;return function(b,c,d,e){b=THREE.Triangle.barycoordFromPoint(b,c,d,e,a);return 0<=b.x&&0<=b.y&&1>=b.x+b.y}}();
 THREE.Triangle.prototype={constructor:THREE.Triangle,set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},area:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,
 this.b);return.5*a.cross(b).length()}}(),midpoint:function(a){return(a||new THREE.Vector3).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(a){return THREE.Triangle.normal(this.a,this.b,this.c,a)},plane:function(a){return(a||new THREE.Plane).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(a,b){return THREE.Triangle.barycoordFromPoint(a,this.a,this.b,this.c,b)},containsPoint:function(a){return THREE.Triangle.containsPoint(a,this.a,this.b,this.c)},
-equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}};THREE.Clock=function(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1};
+equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}};THREE.Channels=function(){this.mask=1};THREE.Channels.prototype={constructor:THREE.Channels,set:function(a){this.mask=1<<a},enable:function(a){this.mask|=1<<a},toggle:function(a){this.mask^=1<<a},disable:function(a){this.mask&=~(1<<a)}};THREE.Clock=function(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1};
 THREE.Clock.prototype={constructor:THREE.Clock,start:function(){this.oldTime=this.startTime=self.performance.now();this.running=!0},stop:function(){this.getElapsedTime();this.running=!1},getElapsedTime:function(){this.getDelta();return this.elapsedTime},getDelta:function(){var a=0;this.autoStart&&!this.running&&this.start();if(this.running){var b=self.performance.now(),a=.001*(b-this.oldTime);this.oldTime=b;this.elapsedTime+=a}return a}};THREE.EventDispatcher=function(){};
 THREE.EventDispatcher.prototype={constructor:THREE.EventDispatcher,apply:function(a){a.addEventListener=THREE.EventDispatcher.prototype.addEventListener;a.hasEventListener=THREE.EventDispatcher.prototype.hasEventListener;a.removeEventListener=THREE.EventDispatcher.prototype.removeEventListener;a.dispatchEvent=THREE.EventDispatcher.prototype.dispatchEvent},addEventListener:function(a,b){void 0===this._listeners&&(this._listeners={});var c=this._listeners;void 0===c[a]&&(c[a]=[]);-1===c[a].indexOf(b)&&
 c[a].push(b)},hasEventListener:function(a,b){if(void 0===this._listeners)return!1;var c=this._listeners;return void 0!==c[a]&&-1!==c[a].indexOf(b)?!0:!1},removeEventListener:function(a,b){if(void 0!==this._listeners){var c=this._listeners[a];if(void 0!==c){var d=c.indexOf(b);-1!==d&&c.splice(d,1)}}},dispatchEvent:function(a){if(void 0!==this._listeners){var b=this._listeners[a.type];if(void 0!==b){a.target=this;for(var c=[],d=b.length,e=0;e<d;e++)c[e]=b[e];for(e=0;e<d;e++)c[e].call(this,a)}}}};
 (function(a){function b(a,b){return a.distance-b.distance}function c(a,b,g,f){if(!1!==a.visible&&(a.raycast(b,g),!0===f)){a=a.children;f=0;for(var h=a.length;f<h;f++)c(a[f],b,g,!0)}}a.Raycaster=function(b,c,g,f){this.ray=new a.Ray(b,c);this.near=g||0;this.far=f||Infinity;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points.");return this.Points}}})};
 a.Raycaster.prototype={constructor:a.Raycaster,linePrecision:1,set:function(a,b){this.ray.set(a,b)},setFromCamera:function(b,c){c instanceof a.PerspectiveCamera?(this.ray.origin.setFromMatrixPosition(c.matrixWorld),this.ray.direction.set(b.x,b.y,.5).unproject(c).sub(this.ray.origin).normalize()):c instanceof a.OrthographicCamera?(this.ray.origin.set(b.x,b.y,-1).unproject(c),this.ray.direction.set(0,0,-1).transformDirection(c.matrixWorld)):console.error("THREE.Raycaster: Unsupported camera type.")},
 intersectObject:function(a,e){var g=[];c(a,this,g,e);g.sort(b);return g},intersectObjects:function(a,e){var g=[];if(!1===Array.isArray(a))return console.warn("THREE.Raycaster.intersectObjects: objects is not an Array."),g;for(var f=0,h=a.length;f<h;f++)c(a[f],this,g,e);g.sort(b);return g}}})(THREE);
-THREE.Object3D=function(){Object.defineProperty(this,"id",{value:THREE.Object3DIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="Object3D";this.parent=null;this.children=[];this.up=THREE.Object3D.DefaultUp.clone();var a=new THREE.Vector3,b=new THREE.Euler,c=new THREE.Quaternion,d=new THREE.Vector3(1,1,1);b.onChange(function(){c.setFromEuler(b,!1)});c.onChange(function(){b.setFromQuaternion(c,void 0,!1)});Object.defineProperties(this,{position:{enumerable:!0,value:a},rotation:{enumerable:!0,
-value:b},quaternion:{enumerable:!0,value:c},scale:{enumerable:!0,value:d},modelViewMatrix:{value:new THREE.Matrix4},normalMatrix:{value:new THREE.Matrix3}});this.rotationAutoUpdate=!0;this.matrix=new THREE.Matrix4;this.matrixWorld=new THREE.Matrix4;this.matrixAutoUpdate=THREE.Object3D.DefaultMatrixAutoUpdate;this.matrixWorldNeedsUpdate=!1;this.visible=!0;this.receiveShadow=this.castShadow=!1;this.frustumCulled=!0;this.renderOrder=0;this.userData={}};
+THREE.Object3D=function(){Object.defineProperty(this,"id",{value:THREE.Object3DIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="Object3D";this.parent=null;this.channels=new THREE.Channels;this.children=[];this.up=THREE.Object3D.DefaultUp.clone();var a=new THREE.Vector3,b=new THREE.Euler,c=new THREE.Quaternion,d=new THREE.Vector3(1,1,1);b.onChange(function(){c.setFromEuler(b,!1)});c.onChange(function(){b.setFromQuaternion(c,void 0,!1)});Object.defineProperties(this,{position:{enumerable:!0,
+value:a},rotation:{enumerable:!0,value:b},quaternion:{enumerable:!0,value:c},scale:{enumerable:!0,value:d},modelViewMatrix:{value:new THREE.Matrix4},normalMatrix:{value:new THREE.Matrix3}});this.rotationAutoUpdate=!0;this.matrix=new THREE.Matrix4;this.matrixWorld=new THREE.Matrix4;this.matrixAutoUpdate=THREE.Object3D.DefaultMatrixAutoUpdate;this.matrixWorldNeedsUpdate=!1;this.visible=!0;this.receiveShadow=this.castShadow=!1;this.frustumCulled=!0;this.renderOrder=0;this.userData={}};
 THREE.Object3D.DefaultUp=new THREE.Vector3(0,1,0);THREE.Object3D.DefaultMatrixAutoUpdate=!0;
 THREE.Object3D.prototype={constructor:THREE.Object3D,get eulerOrder(){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");return this.rotation.order},set eulerOrder(a){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");this.rotation.order=a},get useQuaternion(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")},set useQuaternion(a){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")},set renderDepth(a){console.warn("THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.")},
 applyMatrix:function(a){this.matrix.multiplyMatrices(a,this.matrix);this.matrix.decompose(this.position,this.quaternion,this.scale)},setRotationFromAxisAngle:function(a,b){this.quaternion.setFromAxisAngle(a,b)},setRotationFromEuler:function(a){this.quaternion.setFromEuler(a,!0)},setRotationFromMatrix:function(a){this.quaternion.setFromRotationMatrix(a)},setRotationFromQuaternion:function(a){this.quaternion.copy(a)},rotateOnAxis:function(){var a=new THREE.Quaternion;return function(b,c){a.setFromAxisAngle(b,
@@ -202,9 +202,9 @@ THREE.Geometry=function(){Object.defineProperty(this,"id",{value:THREE.GeometryI
 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){function b(a,b,d){var e=void 0!==f?[n[a].clone(),n[b].clone(),n[d].clone()]:[],g=void 0!==h?[c.colors[a].clone(),c.colors[b].clone(),c.colors[d].clone()]:
-[],e=new THREE.Face3(a,b,d,e,g);c.faces.push(e);void 0!==l&&c.faceVertexUvs[0].push([p[a].clone(),p[b].clone(),p[d].clone()]);void 0!==k&&c.faceVertexUvs[1].push([m[a].clone(),m[b].clone(),m[d].clone()])}var c=this,d=null!==a.index?a.index.array:void 0,e=a.attributes,g=e.position.array,f=void 0!==e.normal?e.normal.array:void 0,h=void 0!==e.color?e.color.array:void 0,l=void 0!==e.uv?e.uv.array:void 0,k=void 0!==e.uv2?e.uv2.array:void 0;void 0!==k&&(this.faceVertexUvs[1]=[]);for(var n=[],p=[],m=[],
-q=e=0;e<g.length;e+=3,q+=2)c.vertices.push(new THREE.Vector3(g[e],g[e+1],g[e+2])),void 0!==f&&n.push(new THREE.Vector3(f[e],f[e+1],f[e+2])),void 0!==h&&c.colors.push(new THREE.Color(h[e],h[e+1],h[e+2])),void 0!==l&&p.push(new THREE.Vector2(l[q],l[q+1])),void 0!==k&&m.push(new THREE.Vector2(k[q],k[q+1]));if(void 0!==d)if(g=a.groups,0<g.length)for(e=0;e<g.length;e++)for(var q=g[e],t=q.start,s=q.count,q=t,t=t+s;q<t;q+=3)b(d[q],d[q+1],d[q+2]);else for(e=0;e<d.length;e+=3)b(d[e],d[e+1],d[e+2]);else for(e=
+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){function b(a,b,d){var e=void 0!==f?[m[a].clone(),m[b].clone(),m[d].clone()]:[],g=void 0!==h?[c.colors[a].clone(),c.colors[b].clone(),c.colors[d].clone()]:
+[],e=new THREE.Face3(a,b,d,e,g);c.faces.push(e);void 0!==l&&c.faceVertexUvs[0].push([p[a].clone(),p[b].clone(),p[d].clone()]);void 0!==k&&c.faceVertexUvs[1].push([n[a].clone(),n[b].clone(),n[d].clone()])}var c=this,d=null!==a.index?a.index.array:void 0,e=a.attributes,g=e.position.array,f=void 0!==e.normal?e.normal.array:void 0,h=void 0!==e.color?e.color.array:void 0,l=void 0!==e.uv?e.uv.array:void 0,k=void 0!==e.uv2?e.uv2.array:void 0;void 0!==k&&(this.faceVertexUvs[1]=[]);for(var m=[],p=[],n=[],
+q=e=0;e<g.length;e+=3,q+=2)c.vertices.push(new THREE.Vector3(g[e],g[e+1],g[e+2])),void 0!==f&&m.push(new THREE.Vector3(f[e],f[e+1],f[e+2])),void 0!==h&&c.colors.push(new THREE.Color(h[e],h[e+1],h[e+2])),void 0!==l&&p.push(new THREE.Vector2(l[q],l[q+1])),void 0!==k&&n.push(new THREE.Vector2(k[q],k[q+1]));if(void 0!==d)if(g=a.groups,0<g.length)for(e=0;e<g.length;e++)for(var q=g[e],s=q.start,t=q.count,q=s,s=s+t;q<s;q+=3)b(d[q],d[q+1],d[q+2]);else for(e=0;e<d.length;e+=3)b(d[e],d[e+1],d[e+2]);else for(e=
 0;e<g.length/3;e+=3)b(e,e+1,e+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,
 l=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),l.subVectors(e,g),h.cross(l),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]),
@@ -212,21 +212,21 @@ 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[
 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,l;c=0;for(d=this.faces.length;c<d;c++)h=new THREE.Vector3,l={a:new THREE.Vector3,b:new THREE.Vector3,c:new THREE.Vector3},e.push(h),f.push(l)}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],l=f.vertexNormals[c],h.copy(e.normal),l.a.copy(e.vertexNormals[0]),l.b.copy(e.vertexNormals[1]),l.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,l=a.faces,k=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=l.length;n<p;n++){var f=l[n],q,t=f.vertexNormals,s=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=s.length;b<g;b++)q=s[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());k.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(),
+a);else{var d,e=this.vertices.length,g=this.vertices,f=a.vertices,h=this.faces,l=a.faces,k=this.faceVertexUvs[0];a=a.faceVertexUvs[0];void 0===c&&(c=0);void 0!==b&&(d=(new THREE.Matrix3).getNormalMatrix(b));for(var m=0,p=f.length;m<p;m++){var n=f[m].clone();void 0!==b&&n.applyMatrix4(b);g.push(n)}m=0;for(p=l.length;m<p;m++){var f=l[m],q,s=f.vertexNormals,t=f.vertexColors,n=new THREE.Face3(f.a+e,f.b+e,f.c+e);n.normal.copy(f.normal);void 0!==d&&n.normal.applyMatrix3(d).normalize();b=0;for(g=s.length;b<
+g;b++)q=s[b].clone(),void 0!==d&&q.applyMatrix3(d).normalize(),n.vertexNormals.push(q);n.color.copy(f.color);b=0;for(g=t.length;b<g;b++)q=t[b],n.vertexColors.push(q.clone());n.materialIndex=f.materialIndex+c;h.push(n)}m=0;for(p=a.length;m<p;m++)if(c=a[m],d=[],void 0!==c){b=0;for(g=c.length;b<g;b++)d.push(c[b].clone());k.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},sortFacesByMaterialIndex:function(){for(var a=this.faces,b=a.length,c=0;c<b;c++)a[c]._id=c;a.sort(function(a,b){return a.materialIndex-b.materialIndex});var d=this.faceVertexUvs[0],e=this.faceVertexUvs[1],g,f;d&&d.length===b&&(g=[]);e&&e.length===b&&(f=[]);for(c=0;c<b;c++){var h=a[c]._id;g&&g.push(d[h]);f&&f.push(e[h])}g&&(this.faceVertexUvs[0]=g);f&&(this.faceVertexUvs[1]=
-f)},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!==k[b])return k[b];k[b]=l.length/3;l.push(a.x,a.y,a.z);return k[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=[],l=[],k={},n=[],p={},m=[],q={};for(f=0;f<this.faces.length;f++){var t=this.faces[f],s=void 0!==this.faceVertexUvs[0][f],u=0<t.normal.length(),x=0<t.vertexNormals.length,v=1!==t.color.r||1!==t.color.g||1!==t.color.b,
-D=0<t.vertexColors.length,w=0,w=a(w,0,0),w=a(w,1,!1),w=a(w,2,!1),w=a(w,3,s),w=a(w,4,u),w=a(w,5,x),w=a(w,6,v),w=a(w,7,D);h.push(w);h.push(t.a,t.b,t.c);s&&(s=this.faceVertexUvs[0][f],h.push(d(s[0]),d(s[1]),d(s[2])));u&&h.push(b(t.normal));x&&(u=t.vertexNormals,h.push(b(u[0]),b(u[1]),b(u[2])));v&&h.push(c(t.color));D&&(t=t.vertexColors,h.push(c(t[0]),c(t[1]),c(t[2])))}e.data={};e.data.vertices=g;e.data.normals=l;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)},
+f)},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!==k[b])return k[b];k[b]=l.length/3;l.push(a.x,a.y,a.z);return k[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]=m.length;m.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]=n.length/2;n.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=[],l=[],k={},m=[],p={},n=[],q={};for(f=0;f<this.faces.length;f++){var s=this.faces[f],t=void 0!==this.faceVertexUvs[0][f],v=0<s.normal.length(),u=0<s.vertexNormals.length,w=1!==s.color.r||1!==s.color.g||1!==s.color.b,
+D=0<s.vertexColors.length,x=0,x=a(x,0,0),x=a(x,1,!1),x=a(x,2,!1),x=a(x,3,t),x=a(x,4,v),x=a(x,5,u),x=a(x,6,w),x=a(x,7,D);h.push(x);h.push(s.a,s.b,s.c);t&&(t=this.faceVertexUvs[0][f],h.push(d(t[0]),d(t[1]),d(t[2])));v&&h.push(b(s.normal));u&&(v=s.vertexNormals,h.push(b(v[0]),b(v[1]),b(v[2])));w&&h.push(c(s.color));D&&(s=s.vertexColors,h.push(c(s[0]),c(s[1]),c(s[2])))}e.data={};e.data.vertices=g;e.data.normals=l;0<m.length&&(e.data.colors=m);0<n.length&&(e.data.uvs=[n]);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=[],l=0,k=f.length;l<k;l++)h.push(f[l].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 l=[],k=0;k<h;k++)l[k]=[];this.morphTargets.position=l}var n=a.morphNormals,p=n.length;if(0<p){for(var m=[],k=0;k<p;k++)m[k]=
-[];this.morphTargets.normal=m}for(var q=a.skinIndices,t=a.skinWeights,s=q.length===c.length,u=t.length===c.length,k=0;k<b.length;k++){var x=b[k];this.vertices.push(c[x.a],c[x.b],c[x.c]);var v=x.vertexNormals;3===v.length?this.normals.push(v[0],v[1],v[2]):(v=x.normal,this.normals.push(v,v,v));v=x.vertexColors;3===v.length?this.colors.push(v[0],v[1],v[2]):(v=x.color,this.colors.push(v,v,v));!0===e&&(v=d[0][k],void 0!==v?this.uvs.push(v[0],v[1],v[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ",
-k),this.uvs.push(new THREE.Vector2,new THREE.Vector2,new THREE.Vector2)));!0===g&&(v=d[1][k],void 0!==v?this.uvs2.push(v[0],v[1],v[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ",k),this.uvs2.push(new THREE.Vector2,new THREE.Vector2,new THREE.Vector2)));for(v=0;v<h;v++){var D=f[v].vertices;l[v].push(D[x.a],D[x.b],D[x.c])}for(v=0;v<p;v++)D=n[v].vertexNormals[k],m[v].push(D.a,D.b,D.c);s&&this.skinIndices.push(q[x.a],q[x.b],q[x.c]);u&&this.skinWeights.push(t[x.a],t[x.b],
-t[x.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);
+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 l=[],k=0;k<h;k++)l[k]=[];this.morphTargets.position=l}var m=a.morphNormals,p=m.length;if(0<p){for(var n=[],k=0;k<p;k++)n[k]=
+[];this.morphTargets.normal=n}for(var q=a.skinIndices,s=a.skinWeights,t=q.length===c.length,v=s.length===c.length,k=0;k<b.length;k++){var u=b[k];this.vertices.push(c[u.a],c[u.b],c[u.c]);var w=u.vertexNormals;3===w.length?this.normals.push(w[0],w[1],w[2]):(w=u.normal,this.normals.push(w,w,w));w=u.vertexColors;3===w.length?this.colors.push(w[0],w[1],w[2]):(w=u.color,this.colors.push(w,w,w));!0===e&&(w=d[0][k],void 0!==w?this.uvs.push(w[0],w[1],w[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ",
+k),this.uvs.push(new THREE.Vector2,new THREE.Vector2,new THREE.Vector2)));!0===g&&(w=d[1][k],void 0!==w?this.uvs2.push(w[0],w[1],w[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ",k),this.uvs2.push(new THREE.Vector2,new THREE.Vector2,new THREE.Vector2)));for(w=0;w<h;w++){var D=f[w].vertices;l[w].push(D[u.a],D[u.b],D[u.c])}for(w=0;w<p;w++)D=m[w].vertexNormals[k],n[w].push(D.a,D.b,D.c);t&&this.skinIndices.push(q[u.a],q[u.b],q[u.c]);v&&this.skinWeights.push(s[u.a],s[u.b],
+s[u.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;this.drawRange={start:0,count:Infinity}};
 THREE.BufferGeometry.prototype={constructor:THREE.BufferGeometry,addIndex:function(a){console.warn("THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().");this.setIndex(a)},getIndex:function(){return this.index},setIndex: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 .setIndex() for index attribute."),this.setIndex(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,
@@ -243,8 +243,8 @@ c.needsUpdate=!0),b.verticesNeedUpdate=!1);!0===b.normalsNeedUpdate&&(c=this.att
 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,l,k,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 s=0,u=c.length;s<u;++s)for(g=c[s],f=g.start,h=g.count,g=f,f+=h;g<f;g+=3)h=3*a[g+0],l=3*a[g+1],k=3*a[g+2],n.fromArray(d,h),p.fromArray(d,l),m.fromArray(d,k),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[l]+=q.x,e[l+1]+=q.y,e[l+2]+=q.z,e[k]+=q.x,e[k+1]+=q.y,e[k+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,
+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,l,k,m=new THREE.Vector3,p=new THREE.Vector3,n=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 t=0,v=c.length;t<v;++t)for(g=c[t],f=g.start,h=g.count,g=f,f+=h;g<f;g+=3)h=3*a[g+0],l=3*a[g+1],k=3*a[g+2],m.fromArray(d,h),p.fromArray(d,l),n.fromArray(d,k),q.subVectors(n,p),s.subVectors(m,p),q.cross(s),e[h]+=q.x,e[h+1]+=q.y,e[h+2]+=q.z,e[l]+=q.x,e[l+1]+=q.y,e[l+2]+=q.z,e[k]+=q.x,e[k+1]+=q.y,e[k+2]+=q.z}else for(g=0,f=d.length;g<f;g+=9)m.fromArray(d,g),p.fromArray(d,g+3),n.fromArray(d,g+6),q.subVectors(n,p),s.subVectors(m,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(){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 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!==
@@ -260,9 +260,9 @@ THREE.AnimationClip.prototype={constructor:THREE.AnimationClip,getAt:function(a)
 THREE.AnimationClip.CreateFromMorphTargetSequence=function(a,b,c){for(var d=b.length,e=[],g=0;g<d;g++){var f=[];f.push({time:(g+d-1)%d,value:0});f.push({time:g,value:1});f.push({time:(g+1)%d,value:0});f.sort(THREE.KeyframeTrack.keyComparer);0===f[0].time&&f.push({time:d,value:f[0].value});e.push((new THREE.NumberKeyframeTrack(".morphTargetInfluences["+b[g].name+"]",f)).scale(1/c))}return new THREE.AnimationClip(a,-1,e)};
 THREE.AnimationClip.findByName=function(a,b){for(var c=0;c<a.length;c++)if(a[c].name===b)return a[c];return null};THREE.AnimationClip.CreateClipsFromMorphTargetSequences=function(a,b){for(var c={},d=/^([\w-]*?)([\d]+)$/,e=0,g=a.length;e<g;e++){var f=a[e],h=f.name.match(d);if(h&&1<h.length){var l=h[1];(h=c[l])||(c[l]=h=[]);h.push(f)}}d=[];for(l in c)d.push(THREE.AnimationClip.CreateFromMorphTargetSequence(l,c[l],b));return d};
 THREE.AnimationClip.parse=function(a){for(var b=[],c=0;c<a.tracks.length;c++)b.push(THREE.KeyframeTrack.parse(a.tracks[c]).scale(1/a.fps));return new THREE.AnimationClip(a.name,a.duration,b)};
-THREE.AnimationClip.parseAnimation=function(a,b,c){if(!a)return console.error("  no animation in JSONLoader data"),null;var d=function(a,b,c,d,e){for(var g=[],f=0;f<b.length;f++){var h=b[f];void 0!==h[c]&&g.push({time:h.time,value:e(h)})}return 0<g.length?new d(a,g):null},e=[],g=a.name||"default",f=a.length||-1,h=a.fps||30;a=a.hierarchy||[];for(var l=0;l<a.length;l++){var k=a[l].keys;if(k&&0!=k.length)if(k[0].morphTargets){for(var f={},n=0;n<k.length;n++)if(k[n].morphTargets)for(var p=0;p<k[n].morphTargets.length;p++)f[k[n].morphTargets[p]]=
--1;for(var m in f){for(var q=[],p=0;p<k[n].morphTargets.length;p++){var t=k[n];q.push({time:t.time,value:t.morphTarget===m?1:0})}e.push(new THREE.NumberKeyframeTrack(c+".morphTargetInfluence["+m+"]",q))}f=f.length*(h||1)}else n=c+".bones["+b[l].name+"]",(p=d(n+".position",k,"pos",THREE.VectorKeyframeTrack,function(a){return(new THREE.Vector3).fromArray(a.pos)}))&&e.push(p),(p=d(n+".quaternion",k,"rot",THREE.QuaternionKeyframeTrack,function(a){return a.rot.slerp?a.rot.clone():(new THREE.Quaternion).fromArray(a.rot)}))&&
-e.push(p),(k=d(n+".scale",k,"scl",THREE.VectorKeyframeTrack,function(a){return(new THREE.Vector3).fromArray(a.scl)}))&&e.push(k)}return 0===e.length?null:new THREE.AnimationClip(g,f,e)};THREE.AnimationMixer=function(a){this.root=a;this.time=0;this.timeScale=1;this.actions=[];this.propertyBindingMap={}};
+THREE.AnimationClip.parseAnimation=function(a,b,c){if(!a)return console.error("  no animation in JSONLoader data"),null;var d=function(a,b,c,d,e){for(var g=[],f=0;f<b.length;f++){var h=b[f];void 0!==h[c]&&g.push({time:h.time,value:e(h)})}return 0<g.length?new d(a,g):null},e=[],g=a.name||"default",f=a.length||-1,h=a.fps||30;a=a.hierarchy||[];for(var l=0;l<a.length;l++){var k=a[l].keys;if(k&&0!=k.length)if(k[0].morphTargets){for(var f={},m=0;m<k.length;m++)if(k[m].morphTargets)for(var p=0;p<k[m].morphTargets.length;p++)f[k[m].morphTargets[p]]=
+-1;for(var n in f){for(var q=[],p=0;p<k[m].morphTargets.length;p++){var s=k[m];q.push({time:s.time,value:s.morphTarget===n?1:0})}e.push(new THREE.NumberKeyframeTrack(c+".morphTargetInfluence["+n+"]",q))}f=f.length*(h||1)}else m=c+".bones["+b[l].name+"]",(p=d(m+".position",k,"pos",THREE.VectorKeyframeTrack,function(a){return(new THREE.Vector3).fromArray(a.pos)}))&&e.push(p),(p=d(m+".quaternion",k,"rot",THREE.QuaternionKeyframeTrack,function(a){return a.rot.slerp?a.rot.clone():(new THREE.Quaternion).fromArray(a.rot)}))&&
+e.push(p),(k=d(m+".scale",k,"scl",THREE.VectorKeyframeTrack,function(a){return(new THREE.Vector3).fromArray(a.scl)}))&&e.push(k)}return 0===e.length?null:new THREE.AnimationClip(g,f,e)};THREE.AnimationMixer=function(a){this.root=a;this.time=0;this.timeScale=1;this.actions=[];this.propertyBindingMap={}};
 THREE.AnimationMixer.prototype={constructor:THREE.AnimationMixer,addAction:function(a){this.actions.push(a);a.init(this.time);a.mixer=this;for(var b=a.clip.tracks,c=a.localRoot||this.root,d=0;d<b.length;d++){var e=b[d],g=c.uuid+"-"+e.name,f=this.propertyBindingMap[g];void 0===f&&(f=new THREE.PropertyBinding(c,e.name),this.propertyBindingMap[g]=f);a.propertyBindings.push(f);f.referenceCount+=1}},removeAllActions:function(){for(var a=0;a<this.actions.length;a++)this.actions[a].mixer=null;for(var b in this.propertyBindingMap)this.propertyBindingMap[b].unbind();
 this.actions=[];this.propertyBindingMap={};return this},removeAction:function(a){var b=this.actions.indexOf(a);-1!==b&&(this.actions.splice(b,1),a.mixer=null);b=a.localRoot||this.root;a=a.clip.tracks;for(var c=0;c<a.length;c++){var d=b.uuid+"-"+a[c].name,e=this.propertyBindingMap[d];e.referenceCount-=1;0>=e.referenceCount&&(e.unbind(),delete this.propertyBindingMap[d])}return this},findActionByName:function(a){for(var b=0;b<this.actions.length;b++)if(this.actions[b].name===a)return this.actions[b];
 return null},play:function(a,b){a.startTime=this.time;this.addAction(a);return this},fadeOut:function(a,b){var c=[];c.push({time:this.time,value:1});c.push({time:this.time+b,value:0});a.weight=new THREE.NumberKeyframeTrack("weight",c);return this},fadeIn:function(a,b){var c=[];c.push({time:this.time,value:0});c.push({time:this.time+b,value:1});a.weight=new THREE.NumberKeyframeTrack("weight",c);return this},warp:function(a,b,c,d){var e=[];e.push({time:this.time,value:b});e.push({time:this.time+d,value:c});
@@ -273,7 +273,7 @@ b,c){return.5>c?a:b},lerp_boolean_immediate:function(a,b,c){return a},lerp_strin
 case "string":return b?THREE.AnimationUtils.lerp_string:THREE.AnimationUtils.lerp_string_immediate}}};THREE.KeyframeTrack=function(a,b){if(void 0===a)throw Error("track name is undefined");if(void 0===b||0===b.length)throw Error("no keys in track named "+a);this.name=a;this.keys=b;this.lastIndex=0;this.validate();this.optimize()};
 THREE.KeyframeTrack.prototype={constructor:THREE.KeyframeTrack,getAt:function(a){for(;this.lastIndex<this.keys.length&&a>=this.keys[this.lastIndex].time;)this.lastIndex++;for(;0<this.lastIndex&&a<this.keys[this.lastIndex-1].time;)this.lastIndex--;if(this.lastIndex>=this.keys.length)return this.setResult(this.keys[this.keys.length-1].value),this.result;if(0===this.lastIndex)return this.setResult(this.keys[0].value),this.result;var b=this.keys[this.lastIndex-1];this.setResult(b.value);if(b.constantToNext)return this.result;
 var c=this.keys[this.lastIndex];return this.result=this.lerpValues(this.result,c.value,(a-b.time)/(c.time-b.time))},shift:function(a){if(0!==a)for(var b=0;b<this.keys.length;b++)this.keys[b].time+=a;return this},scale:function(a){if(1!==a)for(var b=0;b<this.keys.length;b++)this.keys[b].time*=a;return this},trim:function(a,b){for(var c=0,d=1;d<this.keys.length;d++)this.keys[d]<=a&&c++;for(var e=0,d=this.keys.length-2;0<d;d++)if(this.keys[d]>=b)e++;else break;0<c+e&&(this.keys=this.keys.splice(c,this.keys.length-
-e-c));return this},validate:function(){var a=null;if(0===this.keys.length)console.error("  track is empty, no keys",this);else{for(var b=0;b<this.keys.length;b++){var c=this.keys[b];if(!c){console.error("  key is null in track",this,b);return}if("number"!==typeof c.time||Number.isNaN(c.time)){console.error("  key.time is not a valid number",this,b,c);return}if(void 0===c.value||null===c.value){console.error("  key.value is null in track",this,b,c);return}if(a&&a.time>c.time){console.error("  key.time is less than previous key time, out of order keys",
+e-c));return this},validate:function(){var a=null;if(0===this.keys.length)console.error("  track is empty, no keys",this);else{for(var b=0;b<this.keys.length;b++){var c=this.keys[b];if(!c){console.error("  key is null in track",this,b);return}if("number"!==typeof c.time||isNaN(c.time)){console.error("  key.time is not a valid number",this,b,c);return}if(void 0===c.value||null===c.value){console.error("  key.value is null in track",this,b,c);return}if(a&&a.time>c.time){console.error("  key.time is less than previous key time, out of order keys",
 this,b,c,a);return}a=c}return this}},optimize:function(){var a=[],b=this.keys[0];a.push(b);THREE.AnimationUtils.getEqualsFunc(b.value);for(var c=1;c<this.keys.length-1;c++){var d=this.keys[c],e=this.keys[c+1];b.time===d.time||this.compareValues(b.value,d.value)&&this.compareValues(d.value,e.value)||(b.constantToNext=this.compareValues(b.value,d.value),a.push(d),b=d)}a.push(this.keys[this.keys.length-1]);this.keys=a;return this}};THREE.KeyframeTrack.keyComparer=function(a,b){return a.time-b.time};
 THREE.KeyframeTrack.parse=function(a){if(void 0===a.type)throw Error("track type undefined, can not parse");return THREE.KeyframeTrack.GetTrackTypeForTypeName(a.type).parse(a)};
 THREE.KeyframeTrack.GetTrackTypeForTypeName=function(a){switch(a.toLowerCase()){case "vector":case "vector2":case "vector3":case "vector4":return THREE.VectorKeyframeTrack;case "quaternion":return THREE.QuaternionKeyframeTrack;case "integer":case "scalar":case "double":case "float":case "number":return THREE.NumberKeyframeTrack;case "bool":case "boolean":return THREE.BooleanKeyframeTrack;case "string":return THREE.StringKeyframeTrack}throw Error("Unsupported typeName: "+a);};
@@ -300,8 +300,8 @@ THREE.NumberKeyframeTrack.prototype.clone=function(){for(var a=[],b=0;b<this.key
 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 l=new THREE.PerspectiveCamera(90,1,a,b);l.up.set(0,-1,0);l.lookAt(new THREE.Vector3(0,0,-1));this.add(l);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.texture.generateMipmaps;c.texture.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.texture.generateMipmaps=m;c.activeCubeFace=5;a.render(b,l,c);a.setRenderTarget(null)}};THREE.CubeCamera.prototype=Object.create(THREE.Object3D.prototype);THREE.CubeCamera.prototype.constructor=THREE.CubeCamera;
+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 l=new THREE.PerspectiveCamera(90,1,a,b);l.up.set(0,-1,0);l.lookAt(new THREE.Vector3(0,0,-1));this.add(l);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,n=c.texture.generateMipmaps;c.texture.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.texture.generateMipmaps=n;c.activeCubeFace=5;a.render(b,l,c);a.setRenderTarget(null)}};THREE.CubeCamera.prototype=Object.create(THREE.Object3D.prototype);THREE.CubeCamera.prototype.constructor=THREE.CubeCamera;
 THREE.OrthographicCamera=function(a,b,c,d,e,g){THREE.Camera.call(this);this.type="OrthographicCamera";this.zoom=1;this.left=a;this.right=b;this.top=c;this.bottom=d;this.near=void 0!==e?e:.1;this.far=void 0!==g?g:2E3;this.updateProjectionMatrix()};THREE.OrthographicCamera.prototype=Object.create(THREE.Camera.prototype);THREE.OrthographicCamera.prototype.constructor=THREE.OrthographicCamera;
 THREE.OrthographicCamera.prototype.updateProjectionMatrix=function(){var a=(this.right-this.left)/(2*this.zoom),b=(this.top-this.bottom)/(2*this.zoom),c=(this.right+this.left)/2,d=(this.top+this.bottom)/2;this.projectionMatrix.makeOrthographic(c-a,c+a,d+b,d-b,this.near,this.far)};THREE.OrthographicCamera.prototype.copy=function(a){THREE.Camera.prototype.copy.call(this,a);this.left=a.left;this.right=a.right;this.top=a.top;this.bottom=a.bottom;this.near=a.near;this.far=a.far;this.zoom=a.zoom;return this};
 THREE.OrthographicCamera.prototype.toJSON=function(a){a=THREE.Object3D.prototype.toJSON.call(this,a);a.object.zoom=this.zoom;a.object.left=this.left;a.object.right=this.right;a.object.top=this.top;a.object.bottom=this.bottom;a.object.near=this.near;a.object.far=this.far;return a};THREE.PerspectiveCamera=function(a,b,c,d){THREE.Camera.call(this);this.type="PerspectiveCamera";this.zoom=1;this.fov=void 0!==a?a:50;this.aspect=void 0!==b?b:1;this.near=void 0!==c?c:.1;this.far=void 0!==d?d:2E3;this.updateProjectionMatrix()};
@@ -313,34 +313,35 @@ Object.defineProperties(THREE.Light.prototype,{onlyShadow:{set:function(a){conso
 a}},shadowCameraFar:{set:function(a){this.shadow.camera.far=a}},shadowCameraVisible:{set:function(a){console.warn("THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow ) instead.")}},shadowBias:{set:function(a){this.shadow.bias=a}},shadowDarkness:{set:function(a){this.shadow.darkness=a}},shadowMapWidth:{set:function(a){this.shadow.mapSize.width=a}},shadowMapHeight:{set:function(a){this.shadow.mapSize.height=a}}});
 THREE.Light.prototype.copy=function(a){THREE.Object3D.prototype.copy.call(this,a);this.color.copy(a.color);return this};
 THREE.Light.prototype.toJSON=function(a){a=THREE.Object3D.prototype.toJSON.call(this,a);a.object.color=this.color.getHex();void 0!==this.groundColor&&(a.object.groundColor=this.groundColor.getHex());void 0!==this.intensity&&(a.object.intensity=this.intensity);void 0!==this.distance&&(a.object.distance=this.distance);void 0!==this.angle&&(a.object.angle=this.angle);void 0!==this.decay&&(a.object.decay=this.decay);void 0!==this.exponent&&(a.object.exponent=this.exponent);return a};
-THREE.LightShadow=function(a){this.camera=a;this.bias=0;this.darkness=1;this.mapSize=new THREE.Vector2(512,512);this.matrix=this.map=null};THREE.LightShadow.prototype={constructor:THREE.LightShadow,copy:function(a){this.camera=a.camera.clone();this.bias=a.bias;this.darkness=a.darkness;this.mapSize.copy(a.mapSize)},clone:function(){return(new this.constructor).copy(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.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.shadow=new THREE.LightShadow(new THREE.OrthographicCamera(-500,500,500,-500,50,5E3))};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.shadow=a.shadow.clone();return this};THREE.HemisphereLight=function(a,b,c){THREE.Light.call(this,a);this.type="HemisphereLight";this.position.set(0,1,0);this.updateMatrix();this.groundColor=new THREE.Color(b);this.intensity=void 0!==c?c:1};THREE.HemisphereLight.prototype=Object.create(THREE.Light.prototype);
-THREE.HemisphereLight.prototype.constructor=THREE.HemisphereLight;THREE.HemisphereLight.prototype.copy=function(a){THREE.Light.prototype.copy.call(this,a);this.groundColor.copy(a.groundColor);this.intensity=a.intensity;return this};THREE.PointLight=function(a,b,c,d){THREE.Light.call(this,a);this.type="PointLight";this.intensity=void 0!==b?b:1;this.distance=void 0!==c?c:0;this.decay=void 0!==d?d:1;this.shadow=new THREE.LightShadow(new THREE.PerspectiveCamera(90,1,1,500))};
-THREE.PointLight.prototype=Object.create(THREE.Light.prototype);THREE.PointLight.prototype.constructor=THREE.PointLight;THREE.PointLight.prototype.copy=function(a){THREE.Light.prototype.copy.call(this,a);this.intensity=a.intensity;this.distance=a.distance;this.decay=a.decay;this.shadow=a.shadow.clone();return this};
+THREE.LightShadow=function(a){this.camera=a;this.bias=0;this.darkness=1;this.mapSize=new THREE.Vector2(512,512);this.matrix=this.map=null};THREE.LightShadow.prototype={constructor:THREE.LightShadow,copy:function(a){this.camera=a.camera.clone();this.bias=a.bias;this.darkness=a.darkness;this.mapSize.copy(a.mapSize)},clone:function(){return(new this.constructor).copy(this)}};THREE.AmbientLight=function(a){THREE.Light.call(this,a);this.type="AmbientLight";this.castShadow=void 0};
+THREE.AmbientLight.prototype=Object.create(THREE.Light.prototype);THREE.AmbientLight.prototype.constructor=THREE.AmbientLight;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.shadow=new THREE.LightShadow(new THREE.OrthographicCamera(-500,500,500,-500,50,5E3))};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.shadow=a.shadow.clone();return this};THREE.HemisphereLight=function(a,b,c){THREE.Light.call(this,a);this.type="HemisphereLight";this.castShadow=void 0;this.position.set(0,1,0);this.updateMatrix();this.groundColor=new THREE.Color(b);this.intensity=void 0!==c?c:1};
+THREE.HemisphereLight.prototype=Object.create(THREE.Light.prototype);THREE.HemisphereLight.prototype.constructor=THREE.HemisphereLight;THREE.HemisphereLight.prototype.copy=function(a){THREE.Light.prototype.copy.call(this,a);this.groundColor.copy(a.groundColor);this.intensity=a.intensity;return this};
+THREE.PointLight=function(a,b,c,d){THREE.Light.call(this,a);this.type="PointLight";this.intensity=void 0!==b?b:1;this.distance=void 0!==c?c:0;this.decay=void 0!==d?d:1;this.shadow=new THREE.LightShadow(new THREE.PerspectiveCamera(90,1,1,500))};THREE.PointLight.prototype=Object.create(THREE.Light.prototype);THREE.PointLight.prototype.constructor=THREE.PointLight;
+THREE.PointLight.prototype.copy=function(a){THREE.Light.prototype.copy.call(this,a);this.intensity=a.intensity;this.distance=a.distance;this.decay=a.decay;this.shadow=a.shadow.clone();return this};
 THREE.SpotLight=function(a,b,c,d,e,g){THREE.Light.call(this,a);this.type="SpotLight";this.position.set(0,1,0);this.updateMatrix();this.target=new THREE.Object3D;this.intensity=void 0!==b?b:1;this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.exponent=void 0!==e?e:10;this.decay=void 0!==g?g:1;this.shadow=new THREE.LightShadow(new THREE.PerspectiveCamera(50,1,50,5E3))};THREE.SpotLight.prototype=Object.create(THREE.Light.prototype);THREE.SpotLight.prototype.constructor=THREE.SpotLight;
 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.shadow=a.shadow.clone();return this};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},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,g,f,h,l,k,u){var x=c+f,v,D=THREE.Loader.Handlers.get(x);null!==D?v=D.load(x):(v=new THREE.Texture,
-D=a,D.setCrossOrigin(d),D.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=f;h&&(v.repeat.set(h[0],h[1]),1!==h[0]&&(v.wrapS=THREE.RepeatWrapping),1!==h[1]&&(v.wrapT=THREE.RepeatWrapping));l&&v.offset.set(l[0],l[1]);k&&(f={repeat:THREE.RepeatWrapping,mirror:THREE.MirroredRepeatWrapping},
-void 0!==f[k[0]]&&(v.wrapS=f[k[0]]),void 0!==f[k[1]]&&(v.wrapT=f[k[1]]));u&&(v.anisotropy=u);b[g]=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",l={};if(b.shading){var k=b.shading.toLowerCase();"phong"===k?h="MeshPhongMaterial":"basic"===k&&(h="MeshBasicMaterial")}void 0!==b.blending&&void 0!==THREE[b.blending]&&(l.blending=THREE[b.blending]);void 0!==b.transparent&&
-(l.transparent=b.transparent);void 0!==b.opacity&&1>b.opacity&&(l.transparent=!0);void 0!==b.depthTest&&(l.depthTest=b.depthTest);void 0!==b.depthWrite&&(l.depthWrite=b.depthWrite);void 0!==b.visible&&(l.visible=b.visible);void 0!==b.flipSided&&(l.side=THREE.BackSide);void 0!==b.doubleSided&&(l.side=THREE.DoubleSide);void 0!==b.wireframe&&(l.wireframe=b.wireframe);void 0!==b.vertexColors&&("face"===b.vertexColors?l.vertexColors=THREE.FaceColors:b.vertexColors&&(l.vertexColors=THREE.VertexColors));
-b.colorDiffuse?l.color=f(b.colorDiffuse):b.DbgColor&&(l.color=b.DbgColor);b.colorEmissive&&(l.emissive=f(b.colorEmissive));"MeshPhongMaterial"===h&&(b.colorSpecular&&(l.specular=f(b.colorSpecular)),b.specularCoef&&(l.shininess=b.specularCoef));void 0!==b.transparency&&(console.warn("THREE.Loader: transparency has been renamed to opacity"),b.opacity=b.transparency);void 0!==b.opacity&&(l.opacity=b.opacity);c&&(b.mapDiffuse&&g(l,"map",b.mapDiffuse,b.mapDiffuseRepeat,b.mapDiffuseOffset,b.mapDiffuseWrap,
-b.mapDiffuseAnisotropy),b.mapLight&&g(l,"lightMap",b.mapLight,b.mapLightRepeat,b.mapLightOffset,b.mapLightWrap,b.mapLightAnisotropy),b.mapAO&&g(l,"aoMap",b.mapAO,b.mapAORepeat,b.mapAOOffset,b.mapAOWrap,b.mapAOAnisotropy),b.mapBump&&g(l,"bumpMap",b.mapBump,b.mapBumpRepeat,b.mapBumpOffset,b.mapBumpWrap,b.mapBumpAnisotropy),b.mapNormal&&g(l,"normalMap",b.mapNormal,b.mapNormalRepeat,b.mapNormalOffset,b.mapNormalWrap,b.mapNormalAnisotropy),b.mapSpecular&&g(l,"specularMap",b.mapSpecular,b.mapSpecularRepeat,
-b.mapSpecularOffset,b.mapSpecularWrap,b.mapSpecularAnisotropy),b.mapAlpha&&g(l,"alphaMap",b.mapAlpha,b.mapAlphaRepeat,b.mapAlphaOffset,b.mapAlphaWrap,b.mapAlphaAnisotropy));b.mapBumpScale&&(l.bumpScale=b.mapBumpScale);b.mapNormalFactor&&(l.normalScale=new THREE.Vector2(b.mapNormalFactor,b.mapNormalFactor));h=new THREE[h](l);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.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,b,c;return function(d,e,g){function f(a,c,d,f,l){a=e+a;var k=THREE.Loader.Handlers.get(a);null!==k?a=k.load(a):(b.setCrossOrigin(g),a=b.load(a));void 0!==c&&(a.repeat.fromArray(c),1!==c[0]&&(a.wrapS=
+THREE.RepeatWrapping),1!==c[1]&&(a.wrapT=THREE.RepeatWrapping));void 0!==d&&a.offset.fromArray(d);void 0!==f&&("repeat"===f[0]&&(a.wrapS=THREE.RepeatWrapping),"mirror"===f[0]&&(a.wrapS=THREE.MirroredRepeatWrapping),"repeat"===f[1]&&(a.wrapT=THREE.RepeatWrapping),"mirror"===f[1]&&(a.wrapT=THREE.MirroredRepeatWrapping));void 0!==l&&(a.anisotropy=l);c=THREE.Math.generateUUID();h[c]=a;return c}void 0===a&&(a=new THREE.Color);void 0===b&&(b=new THREE.TextureLoader);void 0===c&&(c=new THREE.MaterialLoader);
+var h={},l={uuid:THREE.Math.generateUUID(),type:"MeshLambertMaterial"},k;for(k in d){var m=d[k];switch(k){case "DbgColor":l.color=m;break;case "DbgIndex":case "opticalDensity":case "illumination":break;case "DbgName":l.name=m;break;case "blending":l.blending=THREE[m];break;case "colorDiffuse":l.color=a.fromArray(m).getHex();break;case "colorSpecular":l.specular=a.fromArray(m).getHex();break;case "colorEmissive":l.emissive=a.fromArray(m).getHex();break;case "specularCoef":l.shininess=m;break;case "shading":"basic"===
+m.toLowerCase()&&(l.type="MeshBasicMaterial");"phong"===m.toLowerCase()&&(l.type="MeshPhongMaterial");break;case "mapDiffuse":l.map=f(m,d.mapDiffuseRepeat,d.mapDiffuseOffset,d.mapDiffuseWrap,d.mapDiffuseAnisotropy);break;case "mapDiffuseRepeat":case "mapDiffuseOffset":case "mapDiffuseWrap":case "mapDiffuseAnisotropy":break;case "mapLight":l.lightMap=f(m,d.mapLightRepeat,d.mapLightOffset,d.mapLightWrap,d.mapLightAnisotropy);break;case "mapLightRepeat":case "mapLightOffset":case "mapLightWrap":case "mapLightAnisotropy":break;
+case "mapAO":l.aoMap=f(m,d.mapAORepeat,d.mapAOOffset,d.mapAOWrap,d.mapAOAnisotropy);break;case "mapAORepeat":case "mapAOOffset":case "mapAOWrap":case "mapAOAnisotropy":break;case "mapBump":l.bumpMap=f(m,d.mapBumpRepeat,d.mapBumpOffset,d.mapBumpWrap,d.mapBumpAnisotropy);break;case "mapBumpScale":l.bumpScale=m;break;case "mapBumpRepeat":case "mapBumpOffset":case "mapBumpWrap":case "mapBumpAnisotropy":break;case "mapNormal":l.normalMap=f(m,d.mapNormalRepeat,d.mapNormalOffset,d.mapNormalWrap,d.mapNormalAnisotropy);
+break;case "mapNormalFactor":l.normalScale=[m,m];break;case "mapNormalRepeat":case "mapNormalOffset":case "mapNormalWrap":case "mapNormalAnisotropy":break;case "mapSpecular":l.specularMap=f(m,d.mapSpecularRepeat,d.mapSpecularOffset,d.mapSpecularWrap,d.mapSpecularAnisotropy);break;case "mapSpecularRepeat":case "mapSpecularOffset":case "mapSpecularWrap":case "mapSpecularAnisotropy":break;case "mapAlpha":l.alphaMap=f(m,d.mapAlphaRepeat,d.mapAlphaOffset,d.mapAlphaWrap,d.mapAlphaAnisotropy);break;case "mapAlphaRepeat":case "mapAlphaOffset":case "mapAlphaWrap":case "mapAlphaAnisotropy":break;
+case "flipSided":l.side=THREE.BackSide;break;case "doubleSided":l.side=THREE.DoubleSide;break;case "transparency":console.warn("THREE.Loader: transparency has been renamed to opacity");l.opacity=m;break;case "opacity":case "transparent":case "depthTest":case "depthWrite":case "transparent":case "visible":case "wireframe":l[k]=m;break;case "vertexColors":!0===m&&(l.vertexColors=THREE.VertexColors);"face"===m&&(l.vertexColors=THREE.FaceColors);break;default:console.error("Loader.createMaterial: Unsupported",
+k,m)}}"MeshPhongMaterial"!==l.type&&delete l.specular;1>l.opacity&&(l.transparent=!0);c.setTextures(h);return c.parse(l)}}()};THREE.Loader.Handlers={handlers:[],add:function(a,b){this.handlers.push(a,b)},get:function(a){for(var b=this.handlers,c=0,d=b.length;c<d;c+=2){var e=b[c+1];if(b[c].test(a))return e}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){c=c.target.response;THREE.Cache.add(a,c);b&&b(c);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 e.manager.itemStart(a),b?setTimeout(function(){b(g);e.manager.itemEnd(a)},0):e.manager.itemEnd(a),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){"boolean"===typeof a&&(console.warn("THREE.JSONLoader: showStatus parameter has been removed from constructor."),a=void 0);this.manager=void 0!==a?a:THREE.DefaultLoadingManager;this.withCredentials=!1};
 THREE.JSONLoader.prototype={constructor:THREE.JSONLoader,get statusDomElement(){void 0===this._statusDomElement&&(this._statusDomElement=document.createElement("div"));console.warn("THREE.JSONLoader: .statusDomElement has been removed.");return this._statusDomElement},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,l,k,n,p,m,q,t,s,u,x,v=a.faces;n=a.vertices;var D=a.normals,w=a.colors,A=0;if(void 0!==a.uvs){for(d=0;d<a.uvs.length;d++)a.uvs[d].length&&A++;for(d=0;d<A;d++)c.faceVertexUvs[d]=[]}l=0;for(k=n.length;l<k;)d=new THREE.Vector3,d.x=n[l++]*b,d.y=n[l++]*b,d.z=n[l++]*b,c.vertices.push(d);l=0;for(k=v.length;l<k;)if(b=v[l++],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=v[l];q.b=v[l+1];q.c=v[l+3];s=new THREE.Face3;s.a=v[l+1];s.b=v[l+2];s.c=
-v[l+3];l+=4;h&&(h=v[l++],q.materialIndex=h,s.materialIndex=h);h=c.faces.length;if(d)for(d=0;d<A;d++)for(u=a.uvs[d],c.faceVertexUvs[d][h]=[],c.faceVertexUvs[d][h+1]=[],f=0;4>f;f++)m=v[l++],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[l++],q.normal.set(D[p++],D[p++],D[p]),s.normal.copy(q.normal));if(t)for(d=0;4>d;d++)p=3*v[l++],t=new THREE.Vector3(D[p++],D[p++],D[p]),2!==d&&q.vertexNormals.push(t),0!==d&&s.vertexNormals.push(t);
-n&&(n=v[l++],n=w[n],q.color.setHex(n),s.color.setHex(n));if(b)for(d=0;4>d;d++)n=v[l++],n=w[n],2!==d&&q.vertexColors.push(new THREE.Color(n)),0!==d&&s.vertexColors.push(new THREE.Color(n));c.faces.push(q);c.faces.push(s)}else{q=new THREE.Face3;q.a=v[l++];q.b=v[l++];q.c=v[l++];h&&(h=v[l++],q.materialIndex=h);h=c.faces.length;if(d)for(d=0;d<A;d++)for(u=a.uvs[d],c.faceVertexUvs[d][h]=[],f=0;3>f;f++)m=v[l++],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[l++],q.normal.set(D[p++],
-D[p++],D[p]));if(t)for(d=0;3>d;d++)p=3*v[l++],t=new THREE.Vector3(D[p++],D[p++],D[p]),q.vertexNormals.push(t);n&&(n=v[l++],q.color.setHex(w[n]));if(b)for(d=0;3>d;d++)n=v[l++],q.vertexColors.push(new THREE.Color(w[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]:
+a.scale?1/a.scale:1;(function(b){var d,f,h,l,k,m,p,n,q,s,t,v,u,w=a.faces;m=a.vertices;var D=a.normals,x=a.colors,B=0;if(void 0!==a.uvs){for(d=0;d<a.uvs.length;d++)a.uvs[d].length&&B++;for(d=0;d<B;d++)c.faceVertexUvs[d]=[]}l=0;for(k=m.length;l<k;)d=new THREE.Vector3,d.x=m[l++]*b,d.y=m[l++]*b,d.z=m[l++]*b,c.vertices.push(d);l=0;for(k=w.length;l<k;)if(b=w[l++],q=b&1,h=b&2,d=b&8,p=b&16,s=b&32,m=b&64,b&=128,q){q=new THREE.Face3;q.a=w[l];q.b=w[l+1];q.c=w[l+3];t=new THREE.Face3;t.a=w[l+1];t.b=w[l+2];t.c=
+w[l+3];l+=4;h&&(h=w[l++],q.materialIndex=h,t.materialIndex=h);h=c.faces.length;if(d)for(d=0;d<B;d++)for(v=a.uvs[d],c.faceVertexUvs[d][h]=[],c.faceVertexUvs[d][h+1]=[],f=0;4>f;f++)n=w[l++],u=v[2*n],n=v[2*n+1],u=new THREE.Vector2(u,n),2!==f&&c.faceVertexUvs[d][h].push(u),0!==f&&c.faceVertexUvs[d][h+1].push(u);p&&(p=3*w[l++],q.normal.set(D[p++],D[p++],D[p]),t.normal.copy(q.normal));if(s)for(d=0;4>d;d++)p=3*w[l++],s=new THREE.Vector3(D[p++],D[p++],D[p]),2!==d&&q.vertexNormals.push(s),0!==d&&t.vertexNormals.push(s);
+m&&(m=w[l++],m=x[m],q.color.setHex(m),t.color.setHex(m));if(b)for(d=0;4>d;d++)m=w[l++],m=x[m],2!==d&&q.vertexColors.push(new THREE.Color(m)),0!==d&&t.vertexColors.push(new THREE.Color(m));c.faces.push(q);c.faces.push(t)}else{q=new THREE.Face3;q.a=w[l++];q.b=w[l++];q.c=w[l++];h&&(h=w[l++],q.materialIndex=h);h=c.faces.length;if(d)for(d=0;d<B;d++)for(v=a.uvs[d],c.faceVertexUvs[d][h]=[],f=0;3>f;f++)n=w[l++],u=v[2*n],n=v[2*n+1],u=new THREE.Vector2(u,n),c.faceVertexUvs[d][h].push(u);p&&(p=3*w[l++],q.normal.set(D[p++],
+D[p++],D[p]));if(s)for(d=0;3>d;d++)p=3*w[l++],s=new THREE.Vector3(D[p++],D[p++],D[p]),q.vertexNormals.push(s);m&&(m=w[l++],q.color.setHex(x[m]));if(b)for(d=0;3>d;d++)m=w[l++],q.vertexColors.push(new THREE.Color(x[m]));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.")})();(function(b){if(void 0!==
-a.morphTargets)for(var d=0,f=a.morphTargets.length;d<f;d++){c.morphTargets[d]={};c.morphTargets[d].name=a.morphTargets[d].name;c.morphTargets[d].vertices=[];for(var h=c.morphTargets[d].vertices,l=a.morphTargets[d].vertices,k=0,n=l.length;k<n;k+=3){var p=new THREE.Vector3;p.x=l[k]*b;p.y=l[k+1]*b;p.z=l[k+2]*b;h.push(p)}}if(void 0!==a.morphColors&&0<a.morphColors.length)for(console.warn('THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.'),b=c.faces,h=a.morphColors[0].colors,
+a.morphTargets)for(var d=0,f=a.morphTargets.length;d<f;d++){c.morphTargets[d]={};c.morphTargets[d].name=a.morphTargets[d].name;c.morphTargets[d].vertices=[];for(var h=c.morphTargets[d].vertices,l=a.morphTargets[d].vertices,k=0,m=l.length;k<m;k+=3){var p=new THREE.Vector3;p.x=l[k]*b;p.y=l[k+1]*b;p.z=l[k+2]*b;h.push(p)}}if(void 0!==a.morphColors&&0<a.morphColors.length)for(console.warn('THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.'),b=c.faces,h=a.morphColors[0].colors,
 d=0,f=b.length;d<f;d++)b[d].color.fromArray(h,3*d)})(d);(function(){var b=[],d=[];void 0!==a.animation&&d.push(a.animation);void 0!==a.animations&&(a.animations.length?d=d.concat(a.animations):d.push(a.animations));for(var f=0;f<d.length;f++){var h=THREE.AnimationClip.parseAnimation(d[f],c.bones);h&&b.push(h)}c.morphTargets&&(d=THREE.AnimationClip.CreateClipsFromMorphTargetSequences(c.morphTargets,10),b=b.concat(d));0<b.length&&(c.animations=b)})();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);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;
@@ -358,21 +359,22 @@ d=this.parseTextures(a.textures,d),d=this.parseMaterials(a.materials,d),e=this.p
 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 "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){var d=new THREE.MaterialLoader;d.setTextures(b);for(var e=
-0,g=a.length;e<g;e++){var f=d.parse(a[e]);c[f.uuid]=f}}return c},parseAnimations:function(a){for(var b=[],c=0;c<a.length;c++){var d=THREE.AnimationClip.parse(a[c]);b.push(d)}return b},parseImages:function(a,b){function c(a){d.manager.itemStart(a);return f.load(a,function(){d.manager.itemEnd(a)})}var d=this,e={};if(void 0!==a&&0<a.length){var g=new THREE.LoadingManager(b),f=new THREE.ImageLoader(g);f.setCrossOrigin(this.crossOrigin);for(var g=0,h=a.length;g<h;g++){var l=a[g],k=/^(\/\/)|([a-z]+:(\/\/)?)/i.test(l.url)?
-l.url:d.texturePath+l.url;e[l.uuid]=c(k)}}return e},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.offset&&(h.offset=new THREE.Vector2(f.offset[0],f.offset[1]));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){function e(a){void 0===c[a]&&console.warn("THREE.ObjectLoader: Undefined geometry",a);return c[a]}function g(a){if(void 0!==a)return void 0===d[a]&&console.warn("THREE.ObjectLoader: Undefined material",a),d[a]}var f;switch(b.type){case "Scene":f=new THREE.Scene;break;case "PerspectiveCamera":f=new THREE.PerspectiveCamera(b.fov,b.aspect,b.near,b.far);break;case "OrthographicCamera":f=new THREE.OrthographicCamera(b.left,b.right,b.top,b.bottom,b.near,b.far);break;
-case "AmbientLight":f=new THREE.AmbientLight(b.color);break;case "DirectionalLight":f=new THREE.DirectionalLight(b.color,b.intensity);break;case "PointLight":f=new THREE.PointLight(b.color,b.intensity,b.distance,b.decay);break;case "SpotLight":f=new THREE.SpotLight(b.color,b.intensity,b.distance,b.angle,b.exponent,b.decay);break;case "HemisphereLight":f=new THREE.HemisphereLight(b.color,b.groundColor,b.intensity);break;case "Mesh":f=new THREE.Mesh(e(b.geometry),g(b.material));break;case "LOD":f=new THREE.LOD;
-break;case "Line":f=new THREE.Line(e(b.geometry),g(b.material),b.mode);break;case "PointCloud":case "Points":f=new THREE.Points(e(b.geometry),g(b.material));break;case "Sprite":f=new THREE.Sprite(g(b.material));break;case "Group":f=new THREE.Group;break;default:f=new THREE.Object3D}f.uuid=b.uuid;void 0!==b.name&&(f.name=b.name);void 0!==b.matrix?(a.fromArray(b.matrix),a.decompose(f.position,f.quaternion,f.scale)):(void 0!==b.position&&f.position.fromArray(b.position),void 0!==b.rotation&&f.rotation.fromArray(b.rotation),
-void 0!==b.scale&&f.scale.fromArray(b.scale));void 0!==b.castShadow&&(f.castShadow=b.castShadow);void 0!==b.receiveShadow&&(f.receiveShadow=b.receiveShadow);void 0!==b.visible&&(f.visible=b.visible);void 0!==b.userData&&(f.userData=b.userData);if(void 0!==b.children)for(var h in b.children)f.add(this.parseObject(b.children[h],c,d));if("LOD"===b.type){b=b.levels;for(var l=0;l<b.length;l++){var k=b[l];h=f.getObjectByProperty("uuid",k.object);void 0!==h&&f.addLevel(h,k.distance)}}return f}}()};
-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}};
+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;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){var d=new THREE.MaterialLoader;d.setTextures(b);for(var e=0,g=a.length;e<g;e++){var f=d.parse(a[e]);c[f.uuid]=f}}return c},
+parseAnimations:function(a){for(var b=[],c=0;c<a.length;c++){var d=THREE.AnimationClip.parse(a[c]);b.push(d)}return b},parseImages:function(a,b){function c(a){d.manager.itemStart(a);return f.load(a,function(){d.manager.itemEnd(a)})}var d=this,e={};if(void 0!==a&&0<a.length){var g=new THREE.LoadingManager(b),f=new THREE.ImageLoader(g);f.setCrossOrigin(this.crossOrigin);for(var g=0,h=a.length;g<h;g++){var l=a[g],k=/^(\/\/)|([a-z]+:(\/\/)?)/i.test(l.url)?l.url:d.texturePath+l.url;e[l.uuid]=c(k)}}return e},
+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.offset&&(h.offset=new THREE.Vector2(f.offset[0],f.offset[1]));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){function e(a){void 0===c[a]&&console.warn("THREE.ObjectLoader: Undefined geometry",a);return c[a]}function g(a){if(void 0!==a)return void 0===d[a]&&console.warn("THREE.ObjectLoader: Undefined material",a),d[a]}var f;switch(b.type){case "Scene":f=new THREE.Scene;break;case "PerspectiveCamera":f=new THREE.PerspectiveCamera(b.fov,b.aspect,b.near,b.far);break;case "OrthographicCamera":f=new THREE.OrthographicCamera(b.left,b.right,b.top,b.bottom,b.near,b.far);break;case "AmbientLight":f=new THREE.AmbientLight(b.color);
+break;case "DirectionalLight":f=new THREE.DirectionalLight(b.color,b.intensity);break;case "PointLight":f=new THREE.PointLight(b.color,b.intensity,b.distance,b.decay);break;case "SpotLight":f=new THREE.SpotLight(b.color,b.intensity,b.distance,b.angle,b.exponent,b.decay);break;case "HemisphereLight":f=new THREE.HemisphereLight(b.color,b.groundColor,b.intensity);break;case "Mesh":f=new THREE.Mesh(e(b.geometry),g(b.material));break;case "LOD":f=new THREE.LOD;break;case "Line":f=new THREE.Line(e(b.geometry),
+g(b.material),b.mode);break;case "PointCloud":case "Points":f=new THREE.Points(e(b.geometry),g(b.material));break;case "Sprite":f=new THREE.Sprite(g(b.material));break;case "Group":f=new THREE.Group;break;default:f=new THREE.Object3D}f.uuid=b.uuid;void 0!==b.name&&(f.name=b.name);void 0!==b.matrix?(a.fromArray(b.matrix),a.decompose(f.position,f.quaternion,f.scale)):(void 0!==b.position&&f.position.fromArray(b.position),void 0!==b.rotation&&f.rotation.fromArray(b.rotation),void 0!==b.scale&&f.scale.fromArray(b.scale));
+void 0!==b.castShadow&&(f.castShadow=b.castShadow);void 0!==b.receiveShadow&&(f.receiveShadow=b.receiveShadow);void 0!==b.visible&&(f.visible=b.visible);void 0!==b.userData&&(f.userData=b.userData);if(void 0!==b.children)for(var h in b.children)f.add(this.parseObject(b.children[h],c,d));if("LOD"===b.type){b=b.levels;for(var l=0;l<b.length;l++){var k=b[l];h=f.getObjectByProperty("uuid",k.object);void 0!==h&&f.addLevel(h,k.distance)}}return f}}()};
+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.Texture,g=new THREE.ImageLoader(this.manager);g.setCrossOrigin(this.crossOrigin);g.load(a,function(a){e.image=a;e.needsUpdate=!0;void 0!==b&&b(e)},c,d);return e},setCrossOrigin:function(a){this.crossOrigin=a}};THREE.CubeTextureLoader=function(a){this.manager=void 0!==a?a:THREE.DefaultLoadingManager};
+THREE.CubeTextureLoader.prototype={constructor:THREE.CubeTextureLoader,load:function(a,b,c,d){function e(c){f.load(a[c],function(a){g.images[c]=a;h++;6===h&&(g.needsUpdate=!0,b&&b(g))},void 0,d)}var g=new THREE.CubeTexture([]),f=new THREE.ImageLoader;f.setCrossOrigin(this.crossOrigin);var h=0;for(c=0;c<a.length;++c)e(c);return g},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};
 THREE.CompressedTextureLoader.prototype={constructor:THREE.CompressedTextureLoader,load:function(a,b,c,d){var e=this,g=[],f=new THREE.CompressedTexture;f.image=g;var h=new THREE.XHRLoader(this.manager);h.setCrossOrigin(this.crossOrigin);h.setResponseType("arraybuffer");if(Array.isArray(a))for(var l=0,k=function(k){h.load(a[k],function(a){a=e._parser(a,!0);g[k]={width:a.width,height:a.height,format:a.format,mipmaps:a.mipmaps};l+=1;6===l&&(1===a.mipmapCount&&(f.minFilter=THREE.LinearFilter),f.format=
-a.format,f.needsUpdate=!0,b&&b(f))},c,d)},n=0,p=a.length;n<p;++n)k(n);else h.load(a,function(a){a=e._parser(a,!0);if(a.isCubemap)for(var c=a.mipmaps.length/a.mipmapCount,d=0;d<c;d++){g[d]={mipmaps:[]};for(var h=0;h<a.mipmapCount;h++)g[d].mipmaps.push(a.mipmaps[d*a.mipmapCount+h]),g[d].format=a.format,g[d].width=a.width,g[d].height=a.height}else f.image.width=a.width,f.image.height=a.height,f.mipmaps=a.mipmaps;1===a.mipmapCount&&(f.minFilter=THREE.LinearFilter);f.format=a.format;f.needsUpdate=!0;b&&
+a.format,f.needsUpdate=!0,b&&b(f))},c,d)},m=0,p=a.length;m<p;++m)k(m);else h.load(a,function(a){a=e._parser(a,!0);if(a.isCubemap)for(var c=a.mipmaps.length/a.mipmapCount,d=0;d<c;d++){g[d]={mipmaps:[]};for(var h=0;h<a.mipmapCount;h++)g[d].mipmaps.push(a.mipmaps[d*a.mipmapCount+h]),g[d].format=a.format,g[d].width=a.width,g[d].height=a.height}else f.image.width=a.width,f.image.height=a.height,f.mipmaps=a.mipmaps;1===a.mipmapCount&&(f.minFilter=THREE.LinearFilter);f.format=a.format;f.needsUpdate=!0;b&&
 b(f)},c,d);return f},setCrossOrigin:function(a){this.crossOrigin=a}};
 THREE.Material=function(){Object.defineProperty(this,"id",{value:THREE.MaterialIdCount++});this.uuid=THREE.Math.generateUUID();this.name="";this.type="Material";this.side=THREE.FrontSide;this.opacity=1;this.transparent=!1;this.blending=THREE.NormalBlending;this.blendSrc=THREE.SrcAlphaFactor;this.blendDst=THREE.OneMinusSrcAlphaFactor;this.blendEquation=THREE.AddEquation;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=THREE.LessEqualDepth;this.colorWrite=this.depthWrite=
 this.depthTest=!0;this.precision=null;this.polygonOffset=!1;this.overdraw=this.alphaTest=this.polygonOffsetUnits=this.polygonOffsetFactor=0;this._needsUpdate=this.visible=!0};
@@ -420,35 +422,36 @@ this.image;void 0===c.uuid&&(c.uuid=THREE.Math.generateUUID());if(void 0===a.ima
 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,l){THREE.Texture.call(this,a,b,c,d,e,g,f,h,l);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,l){b=void 0!==b?b:THREE.CubeReflectionMapping;THREE.Texture.call(this,a,b,c,d,e,g,f,h,l);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,l,k,n){THREE.Texture.call(this,null,g,f,h,l,k,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,l,k,n){THREE.Texture.call(this,null,g,f,h,l,k,d,e,n);this.image={data:a,width:b,height:c};this.magFilter=void 0!==l?l:THREE.NearestFilter;this.minFilter=void 0!==k?k: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,l){function k(){requestAnimationFrame(k);a.readyState===a.HAVE_ENOUGH_DATA&&(n.needsUpdate=!0)}THREE.Texture.call(this,a,b,c,d,e,g,f,h,l);this.generateMipmaps=!1;var n=this;k()};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.CompressedTexture=function(a,b,c,d,e,g,f,h,l,k,m){THREE.Texture.call(this,null,g,f,h,l,k,d,e,m);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,l,k,m){THREE.Texture.call(this,null,g,f,h,l,k,d,e,m);this.image={data:a,width:b,height:c};this.magFilter=void 0!==l?l:THREE.NearestFilter;this.minFilter=void 0!==k?k: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,l){function k(){requestAnimationFrame(k);a.readyState===a.HAVE_ENOUGH_DATA&&(m.needsUpdate=!0)}THREE.Texture.call(this,a,b,c,d,e,g,f,h,l);this.generateMipmaps=!1;var m=this;k()};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.Points=function(a,b){THREE.Object3D.call(this);this.type="Points";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.PointsMaterial({color:16777215*Math.random()})};THREE.Points.prototype=Object.create(THREE.Object3D.prototype);THREE.Points.prototype.constructor=THREE.Points;
 THREE.Points.prototype.raycast=function(){var a=new THREE.Matrix4,b=new THREE.Ray;return function(c,d){function e(a,e){var f=b.distanceSqToPoint(a);if(f<l){var h=b.closestPointToPoint(a);h.applyMatrix4(g.matrixWorld);var k=c.ray.origin.distanceTo(h);k<c.near||k>c.far||d.push({distance:k,distanceToRay:Math.sqrt(f),point:h.clone(),index:e,face:null,object:g})}}var g=this,f=g.geometry,h=c.params.Points.threshold;a.getInverse(this.matrixWorld);b.copy(c.ray).applyMatrix4(a);if(null===f.boundingBox||!1!==
-b.isIntersectionBox(f.boundingBox)){var h=h/((this.scale.x+this.scale.y+this.scale.z)/3),l=h*h,h=new THREE.Vector3;if(f instanceof THREE.BufferGeometry){var k=f.index,f=f.attributes.position.array;if(null!==k)for(var n=k.array,k=0,p=n.length;k<p;k++){var m=n[k];h.fromArray(f,3*m);e(h,m)}else for(k=0,n=f.length/3;k<n;k++)h.fromArray(f,3*k),e(h,k)}else for(h=f.vertices,k=0,n=h.length;k<n;k++)e(h[k],k)}}}();THREE.Points.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};
+b.isIntersectionBox(f.boundingBox)){var h=h/((this.scale.x+this.scale.y+this.scale.z)/3),l=h*h,h=new THREE.Vector3;if(f instanceof THREE.BufferGeometry){var k=f.index,f=f.attributes.position.array;if(null!==k)for(var m=k.array,k=0,p=m.length;k<p;k++){var n=m[k];h.fromArray(f,3*n);e(h,n)}else for(k=0,m=f.length/3;k<m;k++)h.fromArray(f,3*k),e(h,k)}else for(h=f.vertices,k=0,m=h.length;k<m;k++)e(h[k],k)}}}();THREE.Points.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};
 THREE.PointCloud=function(a,b){console.warn("THREE.PointCloud has been renamed to THREE.Points.");return new THREE.Points(a,b)};THREE.ParticleSystem=function(a,b){console.warn("THREE.ParticleSystem has been renamed to THREE.Points.");return new THREE.Points(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,l=new THREE.Vector3,k=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)for(var f=m.array,q=q.position.array,m=0,t=f.length-1;m<t;m+=p){var s=f[m+1];h.fromArray(q,3*f[m]);l.fromArray(q,3*s);s=b.distanceSqToSegment(h,l,n,k);s>g||(n.applyMatrix4(this.matrixWorld),s=d.ray.origin.distanceTo(n),s<d.near||s>d.far||e.push({distance:s,point:k.clone().applyMatrix4(this.matrixWorld),index:m,face:null,faceIndex:null,object:this}))}else for(q=q.position.array,m=0,t=q.length/3-1;m<t;m+=p)h.fromArray(q,3*m),l.fromArray(q,
-3*m+3),s=b.distanceSqToSegment(h,l,n,k),s>g||(n.applyMatrix4(this.matrixWorld),s=d.ray.origin.distanceTo(n),s<d.near||s>d.far||e.push({distance:s,point:k.clone().applyMatrix4(this.matrixWorld),index:m,face:null,faceIndex:null,object:this}))}else if(f instanceof THREE.Geometry)for(h=f.vertices,l=h.length,m=0;m<l-1;m+=p)s=b.distanceSqToSegment(h[m],h[m+1],n,k),s>g||(n.applyMatrix4(this.matrixWorld),s=d.ray.origin.distanceTo(n),s<d.near||s>d.far||e.push({distance:s,point:k.clone().applyMatrix4(this.matrixWorld),
-index:m,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};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.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,l=new THREE.Vector3,k=new THREE.Vector3,m=new THREE.Vector3,p=this instanceof THREE.LineSegments?2:1;if(f instanceof
+THREE.BufferGeometry){var n=f.index,q=f.attributes;if(null!==n)for(var f=n.array,q=q.position.array,n=0,s=f.length-1;n<s;n+=p){var t=f[n+1];h.fromArray(q,3*f[n]);l.fromArray(q,3*t);t=b.distanceSqToSegment(h,l,m,k);t>g||(m.applyMatrix4(this.matrixWorld),t=d.ray.origin.distanceTo(m),t<d.near||t>d.far||e.push({distance:t,point:k.clone().applyMatrix4(this.matrixWorld),index:n,face:null,faceIndex:null,object:this}))}else for(q=q.position.array,n=0,s=q.length/3-1;n<s;n+=p)h.fromArray(q,3*n),l.fromArray(q,
+3*n+3),t=b.distanceSqToSegment(h,l,m,k),t>g||(m.applyMatrix4(this.matrixWorld),t=d.ray.origin.distanceTo(m),t<d.near||t>d.far||e.push({distance:t,point:k.clone().applyMatrix4(this.matrixWorld),index:n,face:null,faceIndex:null,object:this}))}else if(f instanceof THREE.Geometry)for(h=f.vertices,l=h.length,n=0;n<l-1;n+=p)t=b.distanceSqToSegment(h[n],h[n+1],m,k),t>g||(m.applyMatrix4(this.matrixWorld),t=d.ray.origin.distanceTo(m),t<d.near||t>d.far||e.push({distance:t,point:k.clone().applyMatrix4(this.matrixWorld),
+index:n,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};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(){function a(a,b,c,d,e,f,g){THREE.Triangle.barycoordFromPoint(a,b,c,d,s);e.multiplyScalar(s.x);f.multiplyScalar(s.y);g.multiplyScalar(s.z);e.add(f).add(g);return e.clone()}function b(a,b,c,d,e,f,g){var h=a.material;if(null===(h.side===THREE.BackSide?c.intersectTriangle(f,e,d,!0,g):c.intersectTriangle(d,e,f,h.side!==THREE.DoubleSide,g)))return null;x.copy(g);x.applyMatrix4(a.matrixWorld);c=b.ray.origin.distanceTo(x);return c<b.near||c>b.far?null:{distance:c,point:x.clone(),
-object:a}}function c(c,d,e,g,k,n,p,s){f.fromArray(g,3*n);h.fromArray(g,3*p);l.fromArray(g,3*s);if(c=b(c,d,e,f,h,l,u))k&&(m.fromArray(k,2*n),q.fromArray(k,2*p),t.fromArray(k,2*s),c.uv=a(u,f,h,l,m,q,t)),c.face=new THREE.Face3(n,p,s,THREE.Triangle.normal(f,h,l)),c.faceIndex=n;return c}var d=new THREE.Matrix4,e=new THREE.Ray,g=new THREE.Sphere,f=new THREE.Vector3,h=new THREE.Vector3,l=new THREE.Vector3,k=new THREE.Vector3,n=new THREE.Vector3,p=new THREE.Vector3,m=new THREE.Vector2,q=new THREE.Vector2,
-t=new THREE.Vector2,s=new THREE.Vector3,u=new THREE.Vector3,x=new THREE.Vector3;return function(s,x){var w=this.geometry,A=this.material;if(void 0!==A){null===w.boundingSphere&&w.computeBoundingSphere();var B=this.matrixWorld;g.copy(w.boundingSphere);g.applyMatrix4(B);if(!1!==s.ray.isIntersectionSphere(g)&&(d.getInverse(B),e.copy(s.ray).applyMatrix4(d),null===w.boundingBox||!1!==e.isIntersectionBox(w.boundingBox))){var z,y;if(w instanceof THREE.BufferGeometry){var L,G,A=w.index,B=w.attributes,w=B.position.array;
-void 0!==B.uv&&(z=B.uv.array);if(null!==A)for(var B=A.array,C=0,N=B.length;C<N;C+=3){if(A=B[C],L=B[C+1],G=B[C+2],y=c(this,s,e,w,z,A,L,G))y.faceIndex=Math.floor(C/3),x.push(y)}else for(C=0,N=w.length;C<N;C+=9)if(A=C/3,L=A+1,G=A+2,y=c(this,s,e,w,z,A,L,G))y.index=A,x.push(y)}else if(w instanceof THREE.Geometry){var M,O,B=A instanceof THREE.MeshFaceMaterial,C=!0===B?A.materials:null,N=w.vertices;L=w.faces;G=w.faceVertexUvs[0];0<G.length&&(z=G);for(var K=0,E=L.length;K<E;K++){var J=L[K];y=!0===B?C[J.materialIndex]:
-A;if(void 0!==y){G=N[J.a];M=N[J.b];O=N[J.c];if(!0===y.morphTargets){y=w.morphTargets;var Q=this.morphTargetInfluences;f.set(0,0,0);h.set(0,0,0);l.set(0,0,0);for(var T=0,H=y.length;T<H;T++){var R=Q[T];if(0!==R){var F=y[T].vertices;f.addScaledVector(k.subVectors(F[J.a],G),R);h.addScaledVector(n.subVectors(F[J.b],M),R);l.addScaledVector(p.subVectors(F[J.c],O),R)}}f.add(G);h.add(M);l.add(O);G=f;M=h;O=l}if(y=b(this,s,e,G,M,O,u))z&&(Q=z[K],m.copy(Q[0]),q.copy(Q[1]),t.copy(Q[2]),y.uv=a(u,G,M,O,m,q,t)),y.face=
-J,y.faceIndex=K,x.push(y)}}}}}}}();THREE.Mesh.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};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,t);e.multiplyScalar(t.x);f.multiplyScalar(t.y);g.multiplyScalar(t.z);e.add(f).add(g);return e.clone()}function b(a,b,c,d,e,f,g){var h=a.material;if(null===(h.side===THREE.BackSide?c.intersectTriangle(f,e,d,!0,g):c.intersectTriangle(d,e,f,h.side!==THREE.DoubleSide,g)))return null;u.copy(g);u.applyMatrix4(a.matrixWorld);c=b.ray.origin.distanceTo(u);return c<b.near||c>b.far?null:{distance:c,point:u.clone(),
+object:a}}function c(c,d,e,g,k,m,p,u){f.fromArray(g,3*m);h.fromArray(g,3*p);l.fromArray(g,3*u);if(c=b(c,d,e,f,h,l,v))k&&(n.fromArray(k,2*m),q.fromArray(k,2*p),s.fromArray(k,2*u),c.uv=a(v,f,h,l,n,q,s)),c.face=new THREE.Face3(m,p,u,THREE.Triangle.normal(f,h,l)),c.faceIndex=m;return c}var d=new THREE.Matrix4,e=new THREE.Ray,g=new THREE.Sphere,f=new THREE.Vector3,h=new THREE.Vector3,l=new THREE.Vector3,k=new THREE.Vector3,m=new THREE.Vector3,p=new THREE.Vector3,n=new THREE.Vector2,q=new THREE.Vector2,
+s=new THREE.Vector2,t=new THREE.Vector3,v=new THREE.Vector3,u=new THREE.Vector3;return function(u,t){var x=this.geometry,B=this.material;if(void 0!==B){null===x.boundingSphere&&x.computeBoundingSphere();var y=this.matrixWorld;g.copy(x.boundingSphere);g.applyMatrix4(y);if(!1!==u.ray.isIntersectionSphere(g)&&(d.getInverse(y),e.copy(u.ray).applyMatrix4(d),null===x.boundingBox||!1!==e.isIntersectionBox(x.boundingBox))){var z,A;if(x instanceof THREE.BufferGeometry){var J,F,B=x.index,y=x.attributes,x=y.position.array;
+void 0!==y.uv&&(z=y.uv.array);if(null!==B)for(var y=B.array,C=0,N=y.length;C<N;C+=3){if(B=y[C],J=y[C+1],F=y[C+2],A=c(this,u,e,x,z,B,J,F))A.faceIndex=Math.floor(C/3),t.push(A)}else for(C=0,N=x.length;C<N;C+=9)if(B=C/3,J=B+1,F=B+2,A=c(this,u,e,x,z,B,J,F))A.index=B,t.push(A)}else if(x instanceof THREE.Geometry){var L,Q,y=B instanceof THREE.MeshFaceMaterial,C=!0===y?B.materials:null,N=x.vertices;J=x.faces;F=x.faceVertexUvs[0];0<F.length&&(z=F);for(var M=0,K=J.length;M<K;M++){var E=J[M];A=!0===y?C[E.materialIndex]:
+B;if(void 0!==A){F=N[E.a];L=N[E.b];Q=N[E.c];if(!0===A.morphTargets){A=x.morphTargets;var O=this.morphTargetInfluences;f.set(0,0,0);h.set(0,0,0);l.set(0,0,0);for(var T=0,H=A.length;T<H;T++){var R=O[T];if(0!==R){var G=A[T].vertices;f.addScaledVector(k.subVectors(G[E.a],F),R);h.addScaledVector(m.subVectors(G[E.b],L),R);l.addScaledVector(p.subVectors(G[E.c],Q),R)}}f.add(F);h.add(L);l.add(Q);F=f;L=h;Q=l}if(A=b(this,u,e,F,L,Q,v))z&&(O=z[M],n.copy(O[0]),q.copy(O[1]),s.copy(O[2]),A.uv=a(v,F,L,Q,n,q,s)),A.face=
+E,A.faceIndex=M,t.push(A)}}}}}}}();THREE.Mesh.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};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)}};
 THREE.Skeleton.prototype.pose=function(){for(var a,b=0,c=this.bones.length;b<c;b++)(a=this.bones[b])&&a.matrixWorld.getInverse(this.boneInverses[b]);b=0;for(c=this.bones.length;b<c;b++)if(a=this.bones[b])a.parent?(a.matrix.getInverse(a.parent.matrixWorld),a.matrix.multiply(a.matrixWorld)):a.matrix.copy(a.matrixWorld),a.matrix.decompose(a.position,a.quaternion,a.scale)};
 THREE.Skeleton.prototype.update=function(){var a=new THREE.Matrix4;return function(){for(var b=0,c=this.bones.length;b<c;b++)a.multiplyMatrices(this.bones[b]?this.bones[b].matrixWorld:this.identityMatrix,this.boneInverses[b]),a.flattenToArrayOffset(this.boneMatrices,16*b);this.useVertexTexture&&(this.boneTexture.needsUpdate=!0)}}();THREE.Skeleton.prototype.clone=function(){return new THREE.Skeleton(this.bones,this.boneInverses,this.useVertexTexture)};
 THREE.SkinnedMesh=function(a,b,c){THREE.Mesh.call(this,a,b);this.type="SkinnedMesh";this.bindMode="attached";this.bindMatrix=new THREE.Matrix4;this.bindMatrixInverse=new THREE.Matrix4;a=[];if(this.geometry&&void 0!==this.geometry.bones){for(var d,e=0,g=this.geometry.bones.length;e<g;++e)d=this.geometry.bones[e],b=new THREE.Bone(this),a.push(b),b.name=d.name,b.position.fromArray(d.pos),b.quaternion.fromArray(d.rotq),void 0!==d.scl&&b.scale.fromArray(d.scl);e=0;for(g=this.geometry.bones.length;e<g;++e)d=
-this.geometry.bones[e],-1!==d.parent?a[d.parent].add(a[e]):this.add(a[e])}this.normalizeSkinWeights();this.updateMatrixWorld(!0);this.bind(new THREE.Skeleton(a,void 0,c),this.matrixWorld)};THREE.SkinnedMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.SkinnedMesh.prototype.constructor=THREE.SkinnedMesh;THREE.SkinnedMesh.prototype.bind=function(a,b){this.skeleton=a;void 0===b&&(this.updateMatrixWorld(!0),this.skeleton.calculateInverses(),b=this.matrixWorld);this.bindMatrix.copy(b);this.bindMatrixInverse.getInverse(b)};
-THREE.SkinnedMesh.prototype.pose=function(){this.skeleton.pose()};THREE.SkinnedMesh.prototype.normalizeSkinWeights=function(){if(this.geometry instanceof THREE.Geometry)for(var a=0;a<this.geometry.skinIndices.length;a++){var b=this.geometry.skinWeights[a],c=1/b.lengthManhattan();Infinity!==c?b.multiplyScalar(c):b.set(1)}};
+this.geometry.bones[e],-1!==d.parent&&null!==d.parent?a[d.parent].add(a[e]):this.add(a[e])}this.normalizeSkinWeights();this.updateMatrixWorld(!0);this.bind(new THREE.Skeleton(a,void 0,c),this.matrixWorld)};THREE.SkinnedMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.SkinnedMesh.prototype.constructor=THREE.SkinnedMesh;
+THREE.SkinnedMesh.prototype.bind=function(a,b){this.skeleton=a;void 0===b&&(this.updateMatrixWorld(!0),this.skeleton.calculateInverses(),b=this.matrixWorld);this.bindMatrix.copy(b);this.bindMatrixInverse.getInverse(b)};THREE.SkinnedMesh.prototype.pose=function(){this.skeleton.pose()};
+THREE.SkinnedMesh.prototype.normalizeSkinWeights=function(){if(this.geometry instanceof THREE.Geometry)for(var a=0;a<this.geometry.skinIndices.length;a++){var b=this.geometry.skinWeights[a],c=1/b.lengthManhattan();Infinity!==c?b.multiplyScalar(c):b.set(1)}};
 THREE.SkinnedMesh.prototype.updateMatrixWorld=function(a){THREE.Mesh.prototype.updateMatrixWorld.call(this,!0);"attached"===this.bindMode?this.bindMatrixInverse.getInverse(this.matrixWorld):"detached"===this.bindMode?this.bindMatrixInverse.getInverse(this.bindMatrix):console.warn("THREE.SkinnedMesh unrecognized bindMode: "+this.bindMode)};THREE.SkinnedMesh.prototype.clone=function(){return(new this.constructor(this.geometry,this.material,this.useVertexTexture)).copy(this)};
 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};
@@ -497,15 +500,15 @@ value:1}},emissivemap:{emissiveMap:{type:"t",value:null}},bumpmap:{bumpMap:{type
 lights:{ambientLightColor:{type:"fv",value:[]},directionalLightDirection:{type:"fv",value:[]},directionalLightColor:{type:"fv",value:[]},hemisphereLightDirection:{type:"fv",value:[]},hemisphereLightSkyColor:{type:"fv",value:[]},hemisphereLightGroundColor:{type:"fv",value:[]},pointLightColor:{type:"fv",value:[]},pointLightPosition:{type:"fv",value:[]},pointLightDistance:{type:"fv1",value:[]},pointLightDecay:{type:"fv1",value:[]},spotLightColor:{type:"fv",value:[]},spotLightPosition:{type:"fv",value:[]},
 spotLightDirection:{type:"fv",value:[]},spotLightDistance:{type:"fv1",value:[]},spotLightAngleCos:{type:"fv1",value:[]},spotLightExponent:{type:"fv1",value:[]},spotLightDecay:{type:"fv1",value:[]}},points:{psColor:{type:"c",value:new THREE.Color(15658734)},opacity:{type:"f",value:1},size:{type:"f",value:1},scale:{type:"f",value:1},map:{type:"t",value:null},offsetRepeat:{type:"v4",value:new THREE.Vector4(0,0,1,1)},fogDensity:{type:"f",value:2.5E-4},fogNear:{type:"f",value:1},fogFar:{type:"f",value:2E3},
 fogColor:{type:"c",value:new THREE.Color(16777215)}},shadowmap:{shadowMap:{type:"tv",value:[]},shadowMapSize:{type:"v2v",value:[]},shadowBias:{type:"fv1",value:[]},shadowDarkness:{type:"fv1",value:[]},shadowMatrix:{type:"m4v",value:[]}}};
-THREE.ShaderLib={basic:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.aomap,THREE.UniformsLib.fog]),vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.uv_pars_vertex,THREE.ShaderChunk.uv2_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.uv_vertex,THREE.ShaderChunk.uv2_vertex,
-THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.skinbase_vertex,"\t#ifdef USE_ENVMAP",THREE.ShaderChunk.beginnormal_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,"\t#endif",THREE.ShaderChunk.begin_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.project_vertex,THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,"}"].join("\n"),
-fragmentShader:["uniform vec3 diffuse;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.uv_pars_fragment,THREE.ShaderChunk.uv2_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.aomap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tvec3 totalAmbientLight = vec3( 1.0 );",
-THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,THREE.ShaderChunk.aomap_fragment,"\toutgoingLight = diffuseColor.rgb * totalAmbientLight;",THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},lambert:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,
-THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{emissive:{type:"c",value:new THREE.Color(0)}}]),vertexShader:["#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.uv_pars_vertex,THREE.ShaderChunk.uv2_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_lambert_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,
-THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.uv_vertex,THREE.ShaderChunk.uv2_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.beginnormal_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,THREE.ShaderChunk.begin_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.project_vertex,
-THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_lambert_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nuniform vec3 ambientLightColor;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.uv_pars_fragment,THREE.ShaderChunk.uv2_pars_fragment,
-THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tvec3 totalAmbientLight = ambientLightColor;\n\tvec3 shadowMask = vec3( 1.0 );",THREE.ShaderChunk.logdepthbuf_fragment,
-THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,THREE.ShaderChunk.shadowmap_fragment,"\t#ifdef DOUBLE_SIDED\n\t\tif ( gl_FrontFacing )\n\t\t\toutgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask + totalAmbientLight ) + emissive;\n\t\telse\n\t\t\toutgoingLight += diffuseColor.rgb * ( vLightBack * shadowMask + totalAmbientLight ) + emissive;\n\t#else\n\t\toutgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask + totalAmbientLight ) + emissive;\n\t#endif",
+THREE.ShaderLib={basic:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.aomap,THREE.UniformsLib.fog,THREE.UniformsLib.shadowmap]),vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.uv_pars_vertex,THREE.ShaderChunk.uv2_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,
+"void main() {",THREE.ShaderChunk.uv_vertex,THREE.ShaderChunk.uv2_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.skinbase_vertex,"\t#ifdef USE_ENVMAP",THREE.ShaderChunk.beginnormal_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,"\t#endif",THREE.ShaderChunk.begin_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.project_vertex,THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.worldpos_vertex,
+THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 diffuse;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.uv_pars_fragment,THREE.ShaderChunk.uv2_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.aomap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,
+THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tvec3 totalAmbientLight = vec3( 1.0 );\n\tvec3 shadowMask = vec3( 1.0 );",THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,THREE.ShaderChunk.aomap_fragment,
+THREE.ShaderChunk.shadowmap_fragment,"\toutgoingLight = diffuseColor.rgb * totalAmbientLight * shadowMask;",THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},lambert:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{emissive:{type:"c",value:new THREE.Color(0)}}]),vertexShader:["#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif",
+THREE.ShaderChunk.common,THREE.ShaderChunk.uv_pars_vertex,THREE.ShaderChunk.uv2_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_lambert_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.uv_vertex,THREE.ShaderChunk.uv2_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.beginnormal_vertex,
+THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,THREE.ShaderChunk.begin_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.project_vertex,THREE.ShaderChunk.logdepthbuf_vertex,THREE.ShaderChunk.worldpos_vertex,THREE.ShaderChunk.envmap_vertex,THREE.ShaderChunk.lights_lambert_vertex,THREE.ShaderChunk.shadowmap_vertex,"}"].join("\n"),fragmentShader:["uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nuniform vec3 ambientLightColor;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif",
+THREE.ShaderChunk.common,THREE.ShaderChunk.color_pars_fragment,THREE.ShaderChunk.uv_pars_fragment,THREE.ShaderChunk.uv2_pars_fragment,THREE.ShaderChunk.map_pars_fragment,THREE.ShaderChunk.alphamap_pars_fragment,THREE.ShaderChunk.envmap_pars_fragment,THREE.ShaderChunk.fog_pars_fragment,THREE.ShaderChunk.shadowmap_pars_fragment,THREE.ShaderChunk.specularmap_pars_fragment,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tvec3 totalAmbientLight = ambientLightColor;\n\tvec3 shadowMask = vec3( 1.0 );",
+THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.map_fragment,THREE.ShaderChunk.color_fragment,THREE.ShaderChunk.alphamap_fragment,THREE.ShaderChunk.alphatest_fragment,THREE.ShaderChunk.specularmap_fragment,THREE.ShaderChunk.shadowmap_fragment,"\t#ifdef DOUBLE_SIDED\n\t\tif ( gl_FrontFacing )\n\t\t\toutgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask + totalAmbientLight ) + emissive;\n\t\telse\n\t\t\toutgoingLight += diffuseColor.rgb * ( vLightBack * shadowMask + totalAmbientLight ) + emissive;\n\t#else\n\t\toutgoingLight += diffuseColor.rgb * ( vLightFront * shadowMask + totalAmbientLight ) + emissive;\n\t#endif",
 THREE.ShaderChunk.envmap_fragment,THREE.ShaderChunk.linear_to_gamma_fragment,THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},phong:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.aomap,THREE.UniformsLib.lightmap,THREE.UniformsLib.emissivemap,THREE.UniformsLib.bumpmap,THREE.UniformsLib.normalmap,THREE.UniformsLib.displacementmap,THREE.UniformsLib.fog,THREE.UniformsLib.lights,THREE.UniformsLib.shadowmap,{emissive:{type:"c",
 value:new THREE.Color(0)},specular:{type:"c",value:new THREE.Color(1118481)},shininess:{type:"f",value:30}}]),vertexShader:["#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif",THREE.ShaderChunk.common,THREE.ShaderChunk.uv_pars_vertex,THREE.ShaderChunk.uv2_pars_vertex,THREE.ShaderChunk.displacementmap_pars_vertex,THREE.ShaderChunk.envmap_pars_vertex,THREE.ShaderChunk.lights_phong_pars_vertex,THREE.ShaderChunk.color_pars_vertex,THREE.ShaderChunk.morphtarget_pars_vertex,
 THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.shadowmap_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.uv_vertex,THREE.ShaderChunk.uv2_vertex,THREE.ShaderChunk.color_vertex,THREE.ShaderChunk.beginnormal_vertex,THREE.ShaderChunk.morphnormal_vertex,THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.skinnormal_vertex,THREE.ShaderChunk.defaultnormal_vertex,"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif",THREE.ShaderChunk.begin_vertex,
@@ -528,86 +531,86 @@ THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},depthRGBA:{uniforms:{},v
 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")},
 distanceRGBA:{uniforms:{lightPos:{type:"v3",value:new THREE.Vector3(0,0,0)}},vertexShader:["varying vec4 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.begin_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.project_vertex,THREE.ShaderChunk.worldpos_vertex,"vWorldPosition = worldPosition;\n}"].join("\n"),fragmentShader:["uniform vec3 lightPos;\nvarying vec4 vWorldPosition;",
 THREE.ShaderChunk.common,"vec4 pack1K ( float depth ) {\n   depth /= 1000.0;\n   const vec4 bitSh = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\n\tconst vec4 bitMsk = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\n\tvec4 res = fract( depth * bitSh );\n\tres -= res.xxyz * bitMsk;\n\treturn res; \n}\nfloat unpack1K ( vec4 color ) {\n\tconst vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\n\treturn dot( color, bitSh ) * 1000.0;\n}\nvoid main () {\n\tgl_FragColor = pack1K( length( vWorldPosition.xyz - lightPos.xyz ) );\n}"].join("\n")}};
-THREE.WebGLRenderer=function(a){function b(a,b,c,d){!0===R&&(a*=d,b*=d,c*=d);r.clearColor(a,b,c,d)}function c(){I.init();r.viewport(na,oa,pa,qa);b(W.r,W.g,W.b,U)}function d(){ra=za=null;sa="";ta=-1;wa=!0;I.reset()}function e(a){a.preventDefault();d();c();X.clear()}function g(a){a=a.target;a.removeEventListener("dispose",g);a:{var b=X.get(a);if(a.image&&b.__image__webglTextureCube)r.deleteTexture(b.__image__webglTextureCube);else{if(void 0===b.__webglInit)break a;r.deleteTexture(b.__webglTexture)}X.delete(a)}la.textures--}
-function f(a){a=a.target;a.removeEventListener("dispose",f);var b=X.get(a),c=X.get(a.texture);if(a&&void 0!==c.__webglTexture){r.deleteTexture(c.__webglTexture);if(a instanceof THREE.WebGLRenderTargetCube)for(c=0;6>c;c++)r.deleteFramebuffer(b.__webglFramebuffer[c]),r.deleteRenderbuffer(b.__webglRenderbuffer[c]);else r.deleteFramebuffer(b.__webglFramebuffer),r.deleteRenderbuffer(b.__webglRenderbuffer);X.delete(a.texture);X.delete(a)}la.textures--}function h(a){a=a.target;a.removeEventListener("dispose",
-h);l(a);X.delete(a)}function l(a){var b=X.get(a).program;a.program=void 0;void 0!==b&&ua.releaseProgram(b)}function k(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=++$):(d=ea,f=++fa);f=d[f];void 0!==f?(f.id=a.id,f.object=a,f.geometry=b,f.material=c,f.z=V.z,f.group=e):(f={id:a.id,object:a,geometry:b,material:c,z:V.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)ja.push(a);else if(a instanceof THREE.LensFlare)ca.push(a);else if(a instanceof THREE.ImmediateRenderObject)!0===aa.sortObjects&&(V.setFromMatrixPosition(a.matrixWorld),V.applyProjection(xa)),m(a,null,a.material,V.z,
-null);else if(a instanceof THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.Points)if(a instanceof THREE.SkinnedMesh&&a.skeleton.update(),!1===a.frustumCulled||!0===Aa.intersectsObject(a)){var b=a.material;if(!0===b.visible){!0===aa.sortObjects&&(V.setFromMatrixPosition(a.matrixWorld),V.applyProjection(xa));var c=va.update(a);if(b instanceof THREE.MeshFaceMaterial)for(var d=c.groups,e=b.materials,b=0,f=d.length;b<f;b++){var g=d[b],h=e[g.materialIndex];!0===h.visible&&m(a,c,h,V.z,g)}else m(a,
-c,b,V.z,null)}}a=a.children;b=0;for(f=a.length;b<f;b++)q(a[b])}}function t(a,b,c,d,e){for(var f=0,g=a.length;f<g;f++){var h=a[f],l=h.object,k=h.geometry,m=void 0===e?h.material:e,h=h.group;l.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,l.matrixWorld);l.normalMatrix.getNormalMatrix(l.modelViewMatrix);if(l instanceof THREE.ImmediateRenderObject){s(m);var n=u(b,c,d,m,l);sa="";l.render(function(a){aa.renderBufferImmediate(a,n,m)})}else aa.renderBufferDirect(b,c,d,k,m,l,h)}}function s(a){a.side!==
-THREE.DoubleSide?I.enable(r.CULL_FACE):I.disable(r.CULL_FACE);I.setFlipSided(a.side===THREE.BackSide);!0===a.transparent?I.setBlending(a.blending,a.blendEquation,a.blendSrc,a.blendDst,a.blendEquationAlpha,a.blendSrcAlpha,a.blendDstAlpha):I.setBlending(THREE.NoBlending);I.setDepthFunc(a.depthFunc);I.setDepthTest(a.depthTest);I.setDepthWrite(a.depthWrite);I.setColorWrite(a.colorWrite);I.setPolygonOffset(a.polygonOffset,a.polygonOffsetFactor,a.polygonOffsetUnits)}function u(a,b,c,d,e){ya=0;var f=X.get(d);
-if(d.needsUpdate||!f.program){a:{var g=X.get(d),k=ua.getParameters(d,b,c,e),m=ua.getProgramCode(d,k),n=g.program,p=!0;if(void 0===n)d.addEventListener("dispose",h);else if(n.code!==m)l(d);else if(void 0!==k.shaderID)break a;else p=!1;p&&(k.shaderID?(n=THREE.ShaderLib[k.shaderID],g.__webglShader={name:d.type,uniforms:THREE.UniformsUtils.clone(n.uniforms),vertexShader:n.vertexShader,fragmentShader:n.fragmentShader}):g.__webglShader={name:d.type,uniforms:d.uniforms,vertexShader:d.vertexShader,fragmentShader:d.fragmentShader},
-d.__webglShader=g.__webglShader,n=ua.acquireProgram(d,k,m),g.program=n,d.program=n);k=n.getAttributes();if(d.morphTargets)for(m=d.numSupportedMorphTargets=0;m<aa.maxMorphTargets;m++)0<=k["morphTarget"+m]&&d.numSupportedMorphTargets++;if(d.morphNormals)for(m=d.numSupportedMorphNormals=0;m<aa.maxMorphNormals;m++)0<=k["morphNormal"+m]&&d.numSupportedMorphNormals++;g.uniformsList=[];var k=g.program.getUniforms(),q;for(q in g.__webglShader.uniforms)(m=k[q])&&g.uniformsList.push([g.__webglShader.uniforms[q],
-m])}d.needsUpdate=!1}m=n=p=!1;g=f.program;q=g.getUniforms();k=f.__webglShader.uniforms;g.id!==za&&(r.useProgram(g.program),za=g.id,m=n=p=!0);d.id!==ta&&(-1===ta&&(m=!0),ta=d.id,n=!0);if(p||a!==ra)r.uniformMatrix4fv(q.projectionMatrix,!1,a.projectionMatrix.elements),ga.logarithmicDepthBuffer&&r.uniform1f(q.logDepthBufFC,2/(Math.log(a.far+1)/Math.LN2)),a!==ra&&(ra=a),(d instanceof THREE.ShaderMaterial||d instanceof THREE.MeshPhongMaterial||d.envMap)&&void 0!==q.cameraPosition&&(V.setFromMatrixPosition(a.matrixWorld),
-r.uniform3f(q.cameraPosition,V.x,V.y,V.z)),(d instanceof THREE.MeshPhongMaterial||d instanceof THREE.MeshLambertMaterial||d instanceof THREE.MeshBasicMaterial||d instanceof THREE.ShaderMaterial||d.skinning)&&void 0!==q.viewMatrix&&r.uniformMatrix4fv(q.viewMatrix,!1,a.matrixWorldInverse.elements);d.skinning&&(e.bindMatrix&&void 0!==q.bindMatrix&&r.uniformMatrix4fv(q.bindMatrix,!1,e.bindMatrix.elements),e.bindMatrixInverse&&void 0!==q.bindMatrixInverse&&r.uniformMatrix4fv(q.bindMatrixInverse,!1,e.bindMatrixInverse.elements),
-ga.floatVertexTextures&&e.skeleton&&e.skeleton.useVertexTexture?(void 0!==q.boneTexture&&(p=v(),r.uniform1i(q.boneTexture,p),aa.setTexture(e.skeleton.boneTexture,p)),void 0!==q.boneTextureWidth&&r.uniform1i(q.boneTextureWidth,e.skeleton.boneTextureWidth),void 0!==q.boneTextureHeight&&r.uniform1i(q.boneTextureHeight,e.skeleton.boneTextureHeight)):e.skeleton&&e.skeleton.boneMatrices&&void 0!==q.boneGlobalMatrices&&r.uniformMatrix4fv(q.boneGlobalMatrices,!1,e.skeleton.boneMatrices));if(n){c&&d.fog&&
-(k.fogColor.value=c.color,c instanceof THREE.Fog?(k.fogNear.value=c.near,k.fogFar.value=c.far):c instanceof THREE.FogExp2&&(k.fogDensity.value=c.density));if(d instanceof THREE.MeshPhongMaterial||d instanceof THREE.MeshLambertMaterial||d.lights){if(wa){var m=!0,s,t=p=0,u=0,w,G,C,A=Ba,y=a.matrixWorldInverse,E=A.directional.colors,J=A.directional.positions,M=A.point.colors,Q=A.point.positions,K=A.point.distances,F=A.point.decays,H=A.spot.colors,L=A.spot.positions,O=A.spot.distances,I=A.spot.directions,
-T=A.spot.anglesCos,ea=A.spot.exponents,R=A.spot.decays,$=A.hemi.skyColors,da=A.hemi.groundColors,S=A.hemi.positions,fa=0,U=0,ca=0,W=0,ma=0,ja=0,Y=0,ia=0,ba=s=0;c=C=ba=0;for(n=b.length;c<n;c++)s=b[c],w=s.color,G=s.intensity,C=s.distance,s instanceof THREE.AmbientLight?s.visible&&(p+=w.r,t+=w.g,u+=w.b):s instanceof THREE.DirectionalLight?(ma+=1,s.visible&&(Z.setFromMatrixPosition(s.matrixWorld),V.setFromMatrixPosition(s.target.matrixWorld),Z.sub(V),Z.transformDirection(y),s=3*fa,J[s+0]=Z.x,J[s+1]=Z.y,
-J[s+2]=Z.z,D(E,s,w,G),fa+=1)):s instanceof THREE.PointLight?(ja+=1,s.visible&&(ba=3*U,D(M,ba,w,G),V.setFromMatrixPosition(s.matrixWorld),V.applyMatrix4(y),Q[ba+0]=V.x,Q[ba+1]=V.y,Q[ba+2]=V.z,K[U]=C,F[U]=0===s.distance?0:s.decay,U+=1)):s instanceof THREE.SpotLight?(Y+=1,s.visible&&(ba=3*ca,D(H,ba,w,G),Z.setFromMatrixPosition(s.matrixWorld),V.copy(Z).applyMatrix4(y),L[ba+0]=V.x,L[ba+1]=V.y,L[ba+2]=V.z,O[ca]=C,V.setFromMatrixPosition(s.target.matrixWorld),Z.sub(V),Z.transformDirection(y),I[ba+0]=Z.x,
-I[ba+1]=Z.y,I[ba+2]=Z.z,T[ca]=Math.cos(s.angle),ea[ca]=s.exponent,R[ca]=0===s.distance?0:s.decay,ca+=1)):s instanceof THREE.HemisphereLight&&(ia+=1,s.visible&&(Z.setFromMatrixPosition(s.matrixWorld),Z.transformDirection(y),C=3*W,S[C+0]=Z.x,S[C+1]=Z.y,S[C+2]=Z.z,w=s.color,s=s.groundColor,D($,C,w,G),D(da,C,s,G),W+=1));c=3*fa;for(n=Math.max(E.length,3*ma);c<n;c++)E[c]=0;c=3*U;for(n=Math.max(M.length,3*ja);c<n;c++)M[c]=0;c=3*ca;for(n=Math.max(H.length,3*Y);c<n;c++)H[c]=0;c=3*W;for(n=Math.max($.length,
-3*ia);c<n;c++)$[c]=0;c=3*W;for(n=Math.max(da.length,3*ia);c<n;c++)da[c]=0;A.directional.length=fa;A.point.length=U;A.spot.length=ca;A.hemi.length=W;A.ambient[0]=p;A.ambient[1]=t;A.ambient[2]=u;wa=!1}m?(m=Ba,k.ambientLightColor.value=m.ambient,k.directionalLightColor.value=m.directional.colors,k.directionalLightDirection.value=m.directional.positions,k.pointLightColor.value=m.point.colors,k.pointLightPosition.value=m.point.positions,k.pointLightDistance.value=m.point.distances,k.pointLightDecay.value=
-m.point.decays,k.spotLightColor.value=m.spot.colors,k.spotLightPosition.value=m.spot.positions,k.spotLightDistance.value=m.spot.distances,k.spotLightDirection.value=m.spot.directions,k.spotLightAngleCos.value=m.spot.anglesCos,k.spotLightExponent.value=m.spot.exponents,k.spotLightDecay.value=m.spot.decays,k.hemisphereLightSkyColor.value=m.hemi.skyColors,k.hemisphereLightGroundColor.value=m.hemi.groundColors,k.hemisphereLightDirection.value=m.hemi.positions,x(k,!0)):x(k,!1)}if(d instanceof THREE.MeshBasicMaterial||
+THREE.WebGLRenderer=function(a){function b(a,b,c,d){!0===G&&(a*=d,b*=d,c*=d);r.clearColor(a,b,c,d)}function c(){I.init();r.viewport(na,oa,pa,qa);b(U.r,U.g,U.b,X)}function d(){ra=Aa=null;sa="";ta=-1;wa=!0;I.reset()}function e(a){a.preventDefault();d();c();W.clear()}function g(a){a=a.target;a.removeEventListener("dispose",g);a:{var b=W.get(a);if(a.image&&b.__image__webglTextureCube)r.deleteTexture(b.__image__webglTextureCube);else{if(void 0===b.__webglInit)break a;r.deleteTexture(b.__webglTexture)}W.delete(a)}la.textures--}
+function f(a){a=a.target;a.removeEventListener("dispose",f);var b=W.get(a),c=W.get(a.texture);if(a&&void 0!==c.__webglTexture){r.deleteTexture(c.__webglTexture);if(a instanceof THREE.WebGLRenderTargetCube)for(c=0;6>c;c++)r.deleteFramebuffer(b.__webglFramebuffer[c]),r.deleteRenderbuffer(b.__webglRenderbuffer[c]);else r.deleteFramebuffer(b.__webglFramebuffer),r.deleteRenderbuffer(b.__webglRenderbuffer);W.delete(a.texture);W.delete(a)}la.textures--}function h(a){a=a.target;a.removeEventListener("dispose",
+h);l(a);W.delete(a)}function l(a){var b=W.get(a).program;a.program=void 0;void 0!==b&&ua.releaseProgram(b)}function k(a,b){return b[0]-a[0]}function m(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 n(a,b,c,d,e){var f;c.transparent?
+(d=Z,f=++fa):(d=ca,f=++ga);f=d[f];void 0!==f?(f.id=a.id,f.object=a,f.geometry=b,f.material=c,f.z=V.z,f.group=e):(f={id:a.id,object:a,geometry:b,material:c,z:V.z,group:e},d.push(f))}function q(a,b){if(!1!==a.visible){if(0!==(a.channels.mask&b.channels.mask))if(a instanceof THREE.Light)da.push(a);else if(a instanceof THREE.Sprite)ea.push(a);else if(a instanceof THREE.LensFlare)ja.push(a);else if(a instanceof THREE.ImmediateRenderObject)!0===aa.sortObjects&&(V.setFromMatrixPosition(a.matrixWorld),V.applyProjection(xa)),
+n(a,null,a.material,V.z,null);else if(a instanceof THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.Points)if(a instanceof THREE.SkinnedMesh&&a.skeleton.update(),!1===a.frustumCulled||!0===Ba.intersectsObject(a)){var c=a.material;if(!0===c.visible){!0===aa.sortObjects&&(V.setFromMatrixPosition(a.matrixWorld),V.applyProjection(xa));var d=va.update(a);if(c instanceof THREE.MeshFaceMaterial)for(var e=d.groups,f=c.materials,c=0,g=e.length;c<g;c++){var h=e[c],l=f[h.materialIndex];!0===l.visible&&
+n(a,d,l,V.z,h)}else n(a,d,c,V.z,null)}}d=a.children;c=0;for(g=d.length;c<g;c++)q(d[c],b)}}function s(a,b,c,d,e){for(var f=0,g=a.length;f<g;f++){var h=a[f],l=h.object,k=h.geometry,n=void 0===e?h.material:e,h=h.group;l.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,l.matrixWorld);l.normalMatrix.getNormalMatrix(l.modelViewMatrix);if(l instanceof THREE.ImmediateRenderObject){t(n);var m=v(b,c,d,n,l);sa="";l.render(function(a){aa.renderBufferImmediate(a,m,n)})}else aa.renderBufferDirect(b,c,d,k,
+n,l,h)}}function t(a){a.side!==THREE.DoubleSide?I.enable(r.CULL_FACE):I.disable(r.CULL_FACE);I.setFlipSided(a.side===THREE.BackSide);!0===a.transparent?I.setBlending(a.blending,a.blendEquation,a.blendSrc,a.blendDst,a.blendEquationAlpha,a.blendSrcAlpha,a.blendDstAlpha):I.setBlending(THREE.NoBlending);I.setDepthFunc(a.depthFunc);I.setDepthTest(a.depthTest);I.setDepthWrite(a.depthWrite);I.setColorWrite(a.colorWrite);I.setPolygonOffset(a.polygonOffset,a.polygonOffsetFactor,a.polygonOffsetUnits)}function v(a,
+b,c,d,e){ya=0;var f=W.get(d);if(d.needsUpdate||!f.program){a:{var g=W.get(d),k=ua.getParameters(d,b,c,e),n=ua.getProgramCode(d,k),m=g.program,q=!0;if(void 0===m)d.addEventListener("dispose",h);else if(m.code!==n)l(d);else if(void 0!==k.shaderID)break a;else q=!1;q&&(k.shaderID?(m=THREE.ShaderLib[k.shaderID],g.__webglShader={name:d.type,uniforms:THREE.UniformsUtils.clone(m.uniforms),vertexShader:m.vertexShader,fragmentShader:m.fragmentShader}):g.__webglShader={name:d.type,uniforms:d.uniforms,vertexShader:d.vertexShader,
+fragmentShader:d.fragmentShader},d.__webglShader=g.__webglShader,m=ua.acquireProgram(d,k,n),g.program=m,d.program=m);k=m.getAttributes();if(d.morphTargets)for(n=d.numSupportedMorphTargets=0;n<aa.maxMorphTargets;n++)0<=k["morphTarget"+n]&&d.numSupportedMorphTargets++;if(d.morphNormals)for(n=d.numSupportedMorphNormals=0;n<aa.maxMorphNormals;n++)0<=k["morphNormal"+n]&&d.numSupportedMorphNormals++;g.uniformsList=[];var k=g.program.getUniforms(),p;for(p in g.__webglShader.uniforms)(n=k[p])&&g.uniformsList.push([g.__webglShader.uniforms[p],
+n])}d.needsUpdate=!1}n=m=q=!1;g=f.program;p=g.getUniforms();k=f.__webglShader.uniforms;g.id!==Aa&&(r.useProgram(g.program),Aa=g.id,n=m=q=!0);d.id!==ta&&(-1===ta&&(n=!0),ta=d.id,m=!0);if(q||a!==ra)r.uniformMatrix4fv(p.projectionMatrix,!1,a.projectionMatrix.elements),ha.logarithmicDepthBuffer&&r.uniform1f(p.logDepthBufFC,2/(Math.log(a.far+1)/Math.LN2)),a!==ra&&(ra=a),(d instanceof THREE.ShaderMaterial||d instanceof THREE.MeshPhongMaterial||d.envMap)&&void 0!==p.cameraPosition&&(V.setFromMatrixPosition(a.matrixWorld),
+r.uniform3f(p.cameraPosition,V.x,V.y,V.z)),(d instanceof THREE.MeshPhongMaterial||d instanceof THREE.MeshLambertMaterial||d instanceof THREE.MeshBasicMaterial||d instanceof THREE.ShaderMaterial||d.skinning)&&void 0!==p.viewMatrix&&r.uniformMatrix4fv(p.viewMatrix,!1,a.matrixWorldInverse.elements);d.skinning&&(e.bindMatrix&&void 0!==p.bindMatrix&&r.uniformMatrix4fv(p.bindMatrix,!1,e.bindMatrix.elements),e.bindMatrixInverse&&void 0!==p.bindMatrixInverse&&r.uniformMatrix4fv(p.bindMatrixInverse,!1,e.bindMatrixInverse.elements),
+ha.floatVertexTextures&&e.skeleton&&e.skeleton.useVertexTexture?(void 0!==p.boneTexture&&(q=w(),r.uniform1i(p.boneTexture,q),aa.setTexture(e.skeleton.boneTexture,q)),void 0!==p.boneTextureWidth&&r.uniform1i(p.boneTextureWidth,e.skeleton.boneTextureWidth),void 0!==p.boneTextureHeight&&r.uniform1i(p.boneTextureHeight,e.skeleton.boneTextureHeight)):e.skeleton&&e.skeleton.boneMatrices&&void 0!==p.boneGlobalMatrices&&r.uniformMatrix4fv(p.boneGlobalMatrices,!1,e.skeleton.boneMatrices));if(m){c&&d.fog&&
+(k.fogColor.value=c.color,c instanceof THREE.Fog?(k.fogNear.value=c.near,k.fogFar.value=c.far):c instanceof THREE.FogExp2&&(k.fogDensity.value=c.density));if(d instanceof THREE.MeshPhongMaterial||d instanceof THREE.MeshLambertMaterial||d.lights){if(wa){var n=!0,s,t=q=0,x=0,v,F,C,y=Ca,E=a.matrixWorldInverse,B=y.directional.colors,K=y.directional.positions,O=y.point.colors,N=y.point.positions,M=y.point.distances,G=y.point.decays,J=y.spot.colors,H=y.spot.positions,Q=y.spot.distances,I=y.spot.directions,
+da=y.spot.anglesCos,T=y.spot.exponents,R=y.spot.decays,Z=y.hemi.skyColors,ga=y.hemi.groundColors,S=y.hemi.positions,ca=0,U=0,ea=0,fa=0,ja=0,ma=0,X=0,$=0,ba=s=0;c=C=ba=0;for(m=b.length;c<m;c++)s=b[c],v=s.color,F=s.intensity,C=s.distance,s instanceof THREE.AmbientLight?s.visible&&(q+=v.r,t+=v.g,x+=v.b):s instanceof THREE.DirectionalLight?(ja+=1,s.visible&&(Y.setFromMatrixPosition(s.matrixWorld),V.setFromMatrixPosition(s.target.matrixWorld),Y.sub(V),Y.transformDirection(E),s=3*ca,K[s+0]=Y.x,K[s+1]=Y.y,
+K[s+2]=Y.z,D(B,s,v,F),ca+=1)):s instanceof THREE.PointLight?(ma+=1,s.visible&&(ba=3*U,D(O,ba,v,F),V.setFromMatrixPosition(s.matrixWorld),V.applyMatrix4(E),N[ba+0]=V.x,N[ba+1]=V.y,N[ba+2]=V.z,M[U]=C,G[U]=0===s.distance?0:s.decay,U+=1)):s instanceof THREE.SpotLight?(X+=1,s.visible&&(ba=3*ea,D(J,ba,v,F),Y.setFromMatrixPosition(s.matrixWorld),V.copy(Y).applyMatrix4(E),H[ba+0]=V.x,H[ba+1]=V.y,H[ba+2]=V.z,Q[ea]=C,V.setFromMatrixPosition(s.target.matrixWorld),Y.sub(V),Y.transformDirection(E),I[ba+0]=Y.x,
+I[ba+1]=Y.y,I[ba+2]=Y.z,da[ea]=Math.cos(s.angle),T[ea]=s.exponent,R[ea]=0===s.distance?0:s.decay,ea+=1)):s instanceof THREE.HemisphereLight&&($+=1,s.visible&&(Y.setFromMatrixPosition(s.matrixWorld),Y.transformDirection(E),C=3*fa,S[C+0]=Y.x,S[C+1]=Y.y,S[C+2]=Y.z,v=s.color,s=s.groundColor,D(Z,C,v,F),D(ga,C,s,F),fa+=1));c=3*ca;for(m=Math.max(B.length,3*ja);c<m;c++)B[c]=0;c=3*U;for(m=Math.max(O.length,3*ma);c<m;c++)O[c]=0;c=3*ea;for(m=Math.max(J.length,3*X);c<m;c++)J[c]=0;c=3*fa;for(m=Math.max(Z.length,
+3*$);c<m;c++)Z[c]=0;c=3*fa;for(m=Math.max(ga.length,3*$);c<m;c++)ga[c]=0;y.directional.length=ca;y.point.length=U;y.spot.length=ea;y.hemi.length=fa;y.ambient[0]=q;y.ambient[1]=t;y.ambient[2]=x;wa=!1}n?(n=Ca,k.ambientLightColor.value=n.ambient,k.directionalLightColor.value=n.directional.colors,k.directionalLightDirection.value=n.directional.positions,k.pointLightColor.value=n.point.colors,k.pointLightPosition.value=n.point.positions,k.pointLightDistance.value=n.point.distances,k.pointLightDecay.value=
+n.point.decays,k.spotLightColor.value=n.spot.colors,k.spotLightPosition.value=n.spot.positions,k.spotLightDistance.value=n.spot.distances,k.spotLightDirection.value=n.spot.directions,k.spotLightAngleCos.value=n.spot.anglesCos,k.spotLightExponent.value=n.spot.exponents,k.spotLightDecay.value=n.spot.decays,k.hemisphereLightSkyColor.value=n.hemi.skyColors,k.hemisphereLightGroundColor.value=n.hemi.groundColors,k.hemisphereLightDirection.value=n.hemi.positions,u(k,!0)):u(k,!1)}if(d instanceof THREE.MeshBasicMaterial||
 d instanceof THREE.MeshLambertMaterial||d instanceof THREE.MeshPhongMaterial){k.opacity.value=d.opacity;k.diffuse.value=d.color;d.emissive&&(k.emissive.value=d.emissive);k.map.value=d.map;k.specularMap.value=d.specularMap;k.alphaMap.value=d.alphaMap;d.aoMap&&(k.aoMap.value=d.aoMap,k.aoMapIntensity.value=d.aoMapIntensity);var P;d.map?P=d.map:d.specularMap?P=d.specularMap:d.displacementMap?P=d.displacementMap:d.normalMap?P=d.normalMap:d.bumpMap?P=d.bumpMap:d.alphaMap?P=d.alphaMap:d.emissiveMap&&(P=
-d.emissiveMap);void 0!==P&&(P instanceof THREE.WebGLRenderTarget&&(P=P.texture),m=P.offset,P=P.repeat,k.offsetRepeat.value.set(m.x,m.y,P.x,P.y));k.envMap.value=d.envMap;k.flipEnvMap.value=d.envMap instanceof THREE.WebGLRenderTargetCube?1:-1;k.reflectivity.value=d.reflectivity;k.refractionRatio.value=d.refractionRatio}d instanceof THREE.LineBasicMaterial?(k.diffuse.value=d.color,k.opacity.value=d.opacity):d instanceof THREE.LineDashedMaterial?(k.diffuse.value=d.color,k.opacity.value=d.opacity,k.dashSize.value=
-d.dashSize,k.totalSize.value=d.dashSize+d.gapSize,k.scale.value=d.scale):d instanceof THREE.PointsMaterial?(k.psColor.value=d.color,k.opacity.value=d.opacity,k.size.value=d.size,k.scale.value=N.height/2,k.map.value=d.map,null!==d.map&&(a=d.map.offset,P=d.map.repeat,k.offsetRepeat.value.set(a.x,a.y,P.x,P.y))):d instanceof THREE.MeshPhongMaterial?(k.specular.value=d.specular,k.shininess.value=Math.max(d.shininess,1E-4),d.lightMap&&(k.lightMap.value=d.lightMap,k.lightMapIntensity.value=d.lightMapIntensity),
+d.emissiveMap);void 0!==P&&(P instanceof THREE.WebGLRenderTarget&&(P=P.texture),n=P.offset,P=P.repeat,k.offsetRepeat.value.set(n.x,n.y,P.x,P.y));k.envMap.value=d.envMap;k.flipEnvMap.value=d.envMap instanceof THREE.WebGLRenderTargetCube?1:-1;k.reflectivity.value=d.reflectivity;k.refractionRatio.value=d.refractionRatio}d instanceof THREE.LineBasicMaterial?(k.diffuse.value=d.color,k.opacity.value=d.opacity):d instanceof THREE.LineDashedMaterial?(k.diffuse.value=d.color,k.opacity.value=d.opacity,k.dashSize.value=
+d.dashSize,k.totalSize.value=d.dashSize+d.gapSize,k.scale.value=d.scale):d instanceof THREE.PointsMaterial?(k.psColor.value=d.color,k.opacity.value=d.opacity,k.size.value=d.size,k.scale.value=L.height/2,k.map.value=d.map,null!==d.map&&(a=d.map.offset,P=d.map.repeat,k.offsetRepeat.value.set(a.x,a.y,P.x,P.y))):d instanceof THREE.MeshPhongMaterial?(k.specular.value=d.specular,k.shininess.value=Math.max(d.shininess,1E-4),d.lightMap&&(k.lightMap.value=d.lightMap,k.lightMapIntensity.value=d.lightMapIntensity),
 d.emissiveMap&&(k.emissiveMap.value=d.emissiveMap),d.bumpMap&&(k.bumpMap.value=d.bumpMap,k.bumpScale.value=d.bumpScale),d.normalMap&&(k.normalMap.value=d.normalMap,k.normalScale.value.copy(d.normalScale)),d.displacementMap&&(k.displacementMap.value=d.displacementMap,k.displacementScale.value=d.displacementScale,k.displacementBias.value=d.displacementBias)):d instanceof THREE.MeshDepthMaterial?(k.mNear.value=a.near,k.mFar.value=a.far,k.opacity.value=d.opacity):d instanceof THREE.MeshNormalMaterial&&
-(k.opacity.value=d.opacity);if(e.receiveShadow&&!d._shadowPass&&k.shadowMatrix)for(a=d=0,P=b.length;a<P;a++)m=b[a],!1!==m.castShadow&&(m instanceof THREE.PointLight||m instanceof THREE.SpotLight||m instanceof THREE.DirectionalLight)&&(c=m.shadow,m instanceof THREE.PointLight?(V.setFromMatrixPosition(m.matrixWorld).negate(),c.matrix.identity().setPosition(V),k.shadowDarkness.value[d]=-c.darkness):k.shadowDarkness.value[d]=c.darkness,k.shadowMatrix.value[d]=c.matrix,k.shadowMap.value[d]=c.map,k.shadowMapSize.value[d]=
+(k.opacity.value=d.opacity);if(e.receiveShadow&&!d._shadowPass&&k.shadowMatrix)for(a=d=0,P=b.length;a<P;a++)n=b[a],!0===n.castShadow&&(n instanceof THREE.PointLight||n instanceof THREE.SpotLight||n instanceof THREE.DirectionalLight)&&(c=n.shadow,n instanceof THREE.PointLight?(V.setFromMatrixPosition(n.matrixWorld).negate(),c.matrix.identity().setPosition(V),k.shadowDarkness.value[d]=-c.darkness):k.shadowDarkness.value[d]=c.darkness,k.shadowMatrix.value[d]=c.matrix,k.shadowMap.value[d]=c.map,k.shadowMapSize.value[d]=
 c.mapSize,k.shadowBias.value[d]=c.bias,d++);b=f.uniformsList;f=0;for(d=b.length;f<d;f++)if(a=b[f][0],!1!==a.needsUpdate)switch(k=a.type,c=a.value,P=b[f][1],k){case "1i":r.uniform1i(P,c);break;case "1f":r.uniform1f(P,c);break;case "2f":r.uniform2f(P,c[0],c[1]);break;case "3f":r.uniform3f(P,c[0],c[1],c[2]);break;case "4f":r.uniform4f(P,c[0],c[1],c[2],c[3]);break;case "1iv":r.uniform1iv(P,c);break;case "3iv":r.uniform3iv(P,c);break;case "1fv":r.uniform1fv(P,c);break;case "2fv":r.uniform2fv(P,c);break;
 case "3fv":r.uniform3fv(P,c);break;case "4fv":r.uniform4fv(P,c);break;case "Matrix3fv":r.uniformMatrix3fv(P,!1,c);break;case "Matrix4fv":r.uniformMatrix4fv(P,!1,c);break;case "i":r.uniform1i(P,c);break;case "f":r.uniform1f(P,c);break;case "v2":r.uniform2f(P,c.x,c.y);break;case "v3":r.uniform3f(P,c.x,c.y,c.z);break;case "v4":r.uniform4f(P,c.x,c.y,c.z,c.w);break;case "c":r.uniform3f(P,c.r,c.g,c.b);break;case "iv1":r.uniform1iv(P,c);break;case "iv":r.uniform3iv(P,c);break;case "fv1":r.uniform1fv(P,c);
-break;case "fv":r.uniform3fv(P,c);break;case "v2v":void 0===a._array&&(a._array=new Float32Array(2*c.length));n=k=0;for(m=c.length;k<m;k++,n+=2)a._array[n+0]=c[k].x,a._array[n+1]=c[k].y;r.uniform2fv(P,a._array);break;case "v3v":void 0===a._array&&(a._array=new Float32Array(3*c.length));n=k=0;for(m=c.length;k<m;k++,n+=3)a._array[n+0]=c[k].x,a._array[n+1]=c[k].y,a._array[n+2]=c[k].z;r.uniform3fv(P,a._array);break;case "v4v":void 0===a._array&&(a._array=new Float32Array(4*c.length));n=k=0;for(m=c.length;k<
-m;k++,n+=4)a._array[n+0]=c[k].x,a._array[n+1]=c[k].y,a._array[n+2]=c[k].z,a._array[n+3]=c[k].w;r.uniform4fv(P,a._array);break;case "m3":r.uniformMatrix3fv(P,!1,c.elements);break;case "m3v":void 0===a._array&&(a._array=new Float32Array(9*c.length));k=0;for(m=c.length;k<m;k++)c[k].flattenToArrayOffset(a._array,9*k);r.uniformMatrix3fv(P,!1,a._array);break;case "m4":r.uniformMatrix4fv(P,!1,c.elements);break;case "m4v":void 0===a._array&&(a._array=new Float32Array(16*c.length));k=0;for(m=c.length;k<m;k++)c[k].flattenToArrayOffset(a._array,
-16*k);r.uniformMatrix4fv(P,!1,a._array);break;case "t":n=v();r.uniform1i(P,n);if(!c)continue;c instanceof THREE.CubeTexture||Array.isArray(c.image)&&6===c.image.length?B(c,n):c instanceof THREE.WebGLRenderTargetCube?z(c.texture,n):c instanceof THREE.WebGLRenderTarget?aa.setTexture(c.texture,n):aa.setTexture(c,n);break;case "tv":void 0===a._array&&(a._array=[]);k=0;for(m=a.value.length;k<m;k++)a._array[k]=v();r.uniform1iv(P,a._array);k=0;for(m=a.value.length;k<m;k++)c=a.value[k],n=a._array[k],c&&(c instanceof
-THREE.CubeTexture||c.image instanceof Array&&6===c.image.length?B(c,n):c instanceof THREE.WebGLRenderTarget?aa.setTexture(c.texture,n):c instanceof THREE.WebGLRenderTargetCube?z(c.texture,n):aa.setTexture(c,n));break;default:console.warn("THREE.WebGLRenderer: Unknown uniform type: "+k)}}r.uniformMatrix4fv(q.modelViewMatrix,!1,e.modelViewMatrix.elements);q.normalMatrix&&r.uniformMatrix3fv(q.normalMatrix,!1,e.normalMatrix.elements);void 0!==q.modelMatrix&&r.uniformMatrix4fv(q.modelMatrix,!1,e.matrixWorld.elements);
-return g}function x(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 v(){var a=ya;a>=ga.maxTextures&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+ga.maxTextures);ya+=1;return a}function D(a,b,c,d){a[b+0]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function w(a,b,c){c?(r.texParameteri(a,r.TEXTURE_WRAP_S,C(b.wrapS)),r.texParameteri(a,r.TEXTURE_WRAP_T,C(b.wrapT)),r.texParameteri(a,r.TEXTURE_MAG_FILTER,
-C(b.magFilter)),r.texParameteri(a,r.TEXTURE_MIN_FILTER,C(b.minFilter))):(r.texParameteri(a,r.TEXTURE_WRAP_S,r.CLAMP_TO_EDGE),r.texParameteri(a,r.TEXTURE_WRAP_T,r.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+" )"),r.texParameteri(a,r.TEXTURE_MAG_FILTER,G(b.magFilter)),r.texParameteri(a,r.TEXTURE_MIN_FILTER,
-G(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=S.get("EXT_texture_filter_anisotropic"))||b.type===THREE.FloatType&&null===S.get("OES_texture_float_linear")||b.type===THREE.HalfFloatType&&null===S.get("OES_texture_half_float_linear")||!(1<b.anisotropy||X.get(b).__currentAnisotropy)||(r.texParameterf(a,
-c.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(b.anisotropy,aa.getMaxAnisotropy())),X.get(b).__currentAnisotropy=b.anisotropy)}function A(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 B(a,b){var c=X.get(a);if(6===a.image.length)if(0<a.version&&c.__version!==a.version){c.__image__webglTextureCube||(a.addEventListener("dispose",g),c.__image__webglTextureCube=r.createTexture(),la.textures++);I.activeTexture(r.TEXTURE0+b);I.bindTexture(r.TEXTURE_CUBE_MAP,c.__image__webglTextureCube);r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,a.flipY);for(var d=a instanceof THREE.CompressedTexture,e=a.image[0]instanceof THREE.DataTexture,f=[],h=0;6>h;h++)f[h]=!aa.autoScaleCubemaps||d||e?e?a.image[h].image:
-a.image[h]:A(a.image[h],ga.maxCubemapSize);var h=f[0],k=THREE.Math.isPowerOfTwo(h.width)&&THREE.Math.isPowerOfTwo(h.height),l=C(a.format),m=C(a.type);w(r.TEXTURE_CUBE_MAP,a,k);for(h=0;6>h;h++)if(d)for(var n,p=f[h].mipmaps,q=0,s=p.length;q<s;q++)n=p[q],a.format!==THREE.RGBAFormat&&a.format!==THREE.RGBFormat?-1<I.getCompressedTextureFormats().indexOf(l)?I.compressedTexImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,q,l,n.width,n.height,0,n.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()"):
-I.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,q,l,n.width,n.height,0,l,m,n.data);else e?I.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,l,f[h].width,f[h].height,0,l,m,f[h].data):I.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,l,l,m,f[h]);a.generateMipmaps&&k&&r.generateMipmap(r.TEXTURE_CUBE_MAP);c.__version=a.version;if(a.onUpdate)a.onUpdate(a)}else I.activeTexture(r.TEXTURE0+b),I.bindTexture(r.TEXTURE_CUBE_MAP,c.__image__webglTextureCube)}function z(a,b){I.activeTexture(r.TEXTURE0+b);I.bindTexture(r.TEXTURE_CUBE_MAP,
-X.get(a).__webglTexture)}function y(a,b,c){r.bindFramebuffer(r.FRAMEBUFFER,a);r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,c,X.get(b.texture).__webglTexture,0)}function L(a,b){r.bindRenderbuffer(r.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(r.renderbufferStorage(r.RENDERBUFFER,r.DEPTH_COMPONENT16,b.width,b.height),r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_ATTACHMENT,r.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(r.renderbufferStorage(r.RENDERBUFFER,r.DEPTH_STENCIL,b.width,
-b.height),r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_STENCIL_ATTACHMENT,r.RENDERBUFFER,a)):r.renderbufferStorage(r.RENDERBUFFER,r.RGBA4,b.width,b.height)}function G(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?r.NEAREST:r.LINEAR}function C(a){var b;if(a===THREE.RepeatWrapping)return r.REPEAT;if(a===THREE.ClampToEdgeWrapping)return r.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return r.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return r.NEAREST;
+break;case "fv":r.uniform3fv(P,c);break;case "v2v":void 0===a._array&&(a._array=new Float32Array(2*c.length));m=k=0;for(n=c.length;k<n;k++,m+=2)a._array[m+0]=c[k].x,a._array[m+1]=c[k].y;r.uniform2fv(P,a._array);break;case "v3v":void 0===a._array&&(a._array=new Float32Array(3*c.length));m=k=0;for(n=c.length;k<n;k++,m+=3)a._array[m+0]=c[k].x,a._array[m+1]=c[k].y,a._array[m+2]=c[k].z;r.uniform3fv(P,a._array);break;case "v4v":void 0===a._array&&(a._array=new Float32Array(4*c.length));m=k=0;for(n=c.length;k<
+n;k++,m+=4)a._array[m+0]=c[k].x,a._array[m+1]=c[k].y,a._array[m+2]=c[k].z,a._array[m+3]=c[k].w;r.uniform4fv(P,a._array);break;case "m3":r.uniformMatrix3fv(P,!1,c.elements);break;case "m3v":void 0===a._array&&(a._array=new Float32Array(9*c.length));k=0;for(n=c.length;k<n;k++)c[k].flattenToArrayOffset(a._array,9*k);r.uniformMatrix3fv(P,!1,a._array);break;case "m4":r.uniformMatrix4fv(P,!1,c.elements);break;case "m4v":void 0===a._array&&(a._array=new Float32Array(16*c.length));k=0;for(n=c.length;k<n;k++)c[k].flattenToArrayOffset(a._array,
+16*k);r.uniformMatrix4fv(P,!1,a._array);break;case "t":m=w();r.uniform1i(P,m);if(!c)continue;c instanceof THREE.CubeTexture||Array.isArray(c.image)&&6===c.image.length?z(c,m):c instanceof THREE.WebGLRenderTargetCube?A(c.texture,m):c instanceof THREE.WebGLRenderTarget?aa.setTexture(c.texture,m):aa.setTexture(c,m);break;case "tv":void 0===a._array&&(a._array=[]);k=0;for(n=a.value.length;k<n;k++)a._array[k]=w();r.uniform1iv(P,a._array);k=0;for(n=a.value.length;k<n;k++)c=a.value[k],m=a._array[k],c&&(c instanceof
+THREE.CubeTexture||c.image instanceof Array&&6===c.image.length?z(c,m):c instanceof THREE.WebGLRenderTarget?aa.setTexture(c.texture,m):c instanceof THREE.WebGLRenderTargetCube?A(c.texture,m):aa.setTexture(c,m));break;default:console.warn("THREE.WebGLRenderer: Unknown uniform type: "+k)}}r.uniformMatrix4fv(p.modelViewMatrix,!1,e.modelViewMatrix.elements);p.normalMatrix&&r.uniformMatrix3fv(p.normalMatrix,!1,e.normalMatrix.elements);void 0!==p.modelMatrix&&r.uniformMatrix4fv(p.modelMatrix,!1,e.matrixWorld.elements);
+return g}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 w(){var a=ya;a>=ha.maxTextures&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+ha.maxTextures);ya+=1;return a}function D(a,b,c,d){a[b+0]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function x(a,b,c){c?(r.texParameteri(a,r.TEXTURE_WRAP_S,N(b.wrapS)),r.texParameteri(a,r.TEXTURE_WRAP_T,N(b.wrapT)),r.texParameteri(a,r.TEXTURE_MAG_FILTER,
+N(b.magFilter)),r.texParameteri(a,r.TEXTURE_MIN_FILTER,N(b.minFilter))):(r.texParameteri(a,r.TEXTURE_WRAP_S,r.CLAMP_TO_EDGE),r.texParameteri(a,r.TEXTURE_WRAP_T,r.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),r.texParameteri(a,r.TEXTURE_MAG_FILTER,C(b.magFilter)),r.texParameteri(a,r.TEXTURE_MIN_FILTER,C(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));!(c=S.get("EXT_texture_filter_anisotropic"))||b.type===THREE.FloatType&&null===S.get("OES_texture_float_linear")||b.type===THREE.HalfFloatType&&null===S.get("OES_texture_half_float_linear")||!(1<b.anisotropy||W.get(b).__currentAnisotropy)||(r.texParameterf(a,c.TEXTURE_MAX_ANISOTROPY_EXT,
+Math.min(b.anisotropy,aa.getMaxAnisotropy())),W.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 y(a){return THREE.Math.isPowerOfTwo(a.width)&&
+THREE.Math.isPowerOfTwo(a.height)}function z(a,b){var c=W.get(a);if(6===a.image.length)if(0<a.version&&c.__version!==a.version){c.__image__webglTextureCube||(a.addEventListener("dispose",g),c.__image__webglTextureCube=r.createTexture(),la.textures++);I.activeTexture(r.TEXTURE0+b);I.bindTexture(r.TEXTURE_CUBE_MAP,c.__image__webglTextureCube);r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,a.flipY);for(var d=a instanceof THREE.CompressedTexture,e=a.image[0]instanceof THREE.DataTexture,f=[],h=0;6>h;h++)f[h]=!aa.autoScaleCubemaps||
+d||e?e?a.image[h].image:a.image[h]:B(a.image[h],ha.maxCubemapSize);var k=y(f[0]),l=N(a.format),n=N(a.type);x(r.TEXTURE_CUBE_MAP,a,k);for(h=0;6>h;h++)if(d)for(var m,q=f[h].mipmaps,p=0,s=q.length;p<s;p++)m=q[p],a.format!==THREE.RGBAFormat&&a.format!==THREE.RGBFormat?-1<I.getCompressedTextureFormats().indexOf(l)?I.compressedTexImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,p,l,m.width,m.height,0,m.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()"):
+I.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,p,l,m.width,m.height,0,l,n,m.data);else e?I.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,l,f[h].width,f[h].height,0,l,n,f[h].data):I.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,l,l,n,f[h]);a.generateMipmaps&&k&&r.generateMipmap(r.TEXTURE_CUBE_MAP);c.__version=a.version;if(a.onUpdate)a.onUpdate(a)}else I.activeTexture(r.TEXTURE0+b),I.bindTexture(r.TEXTURE_CUBE_MAP,c.__image__webglTextureCube)}function A(a,b){I.activeTexture(r.TEXTURE0+b);I.bindTexture(r.TEXTURE_CUBE_MAP,
+W.get(a).__webglTexture)}function J(a,b,c){r.bindFramebuffer(r.FRAMEBUFFER,a);r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,c,W.get(b.texture).__webglTexture,0)}function F(a,b){r.bindRenderbuffer(r.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(r.renderbufferStorage(r.RENDERBUFFER,r.DEPTH_COMPONENT16,b.width,b.height),r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_ATTACHMENT,r.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(r.renderbufferStorage(r.RENDERBUFFER,r.DEPTH_STENCIL,b.width,
+b.height),r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_STENCIL_ATTACHMENT,r.RENDERBUFFER,a)):r.renderbufferStorage(r.RENDERBUFFER,r.RGBA4,b.width,b.height)}function C(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?r.NEAREST:r.LINEAR}function N(a){var b;if(a===THREE.RepeatWrapping)return r.REPEAT;if(a===THREE.ClampToEdgeWrapping)return r.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return r.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return r.NEAREST;
 if(a===THREE.NearestMipMapNearestFilter)return r.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return r.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return r.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return r.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return r.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return r.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return r.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return r.UNSIGNED_SHORT_5_5_5_1;
 if(a===THREE.UnsignedShort565Type)return r.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return r.BYTE;if(a===THREE.ShortType)return r.SHORT;if(a===THREE.UnsignedShortType)return r.UNSIGNED_SHORT;if(a===THREE.IntType)return r.INT;if(a===THREE.UnsignedIntType)return r.UNSIGNED_INT;if(a===THREE.FloatType)return r.FLOAT;b=S.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return r.ALPHA;if(a===THREE.RGBFormat)return r.RGB;if(a===THREE.RGBAFormat)return r.RGBA;
 if(a===THREE.LuminanceFormat)return r.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return r.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return r.FUNC_ADD;if(a===THREE.SubtractEquation)return r.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return r.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return r.ZERO;if(a===THREE.OneFactor)return r.ONE;if(a===THREE.SrcColorFactor)return r.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return r.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return r.SRC_ALPHA;
 if(a===THREE.OneMinusSrcAlphaFactor)return r.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return r.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return r.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return r.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return r.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return r.SRC_ALPHA_SATURATE;b=S.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=S.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=
-S.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 N=void 0!==a.canvas?a.canvas:document.createElement("canvas"),M=void 0!==a.context?a.context:null,O=N.width,K=N.height,E=1,J=void 0!==a.alpha?a.alpha:!1,Q=void 0!==a.depth?a.depth:!0,T=void 0!==a.stencil?a.stencil:!0,H=void 0!==a.antialias?a.antialias:!1,R=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:
-!0,F=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,W=new THREE.Color(0),U=0,Y=[],ea=[],fa=-1,da=[],$=-1,ma=new Float32Array(8),ja=[],ca=[];this.domElement=N;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 aa=this,za=null,ia=null,ta=-1,sa="",ra=null,ya=0,na=0,oa=0,pa=N.width,qa=N.height,Ca=
-0,Da=0,Aa=new THREE.Frustum,xa=new THREE.Matrix4,V=new THREE.Vector3,Z=new THREE.Vector3,wa=!0,Ba={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:[]}},la={geometries:0,textures:0},ka={calls:0,vertices:0,faces:0,points:0};this.info={render:ka,memory:la,programs:null};
-var r;try{J={alpha:J,depth:Q,stencil:T,antialias:H,premultipliedAlpha:R,preserveDrawingBuffer:F};r=M||N.getContext("webgl",J)||N.getContext("experimental-webgl",J);if(null===r){if(null!==N.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}N.addEventListener("webglcontextlost",e,!1)}catch(Ea){console.error("THREE.WebGLRenderer: "+Ea)}var S=new THREE.WebGLExtensions(r);S.get("OES_texture_float");S.get("OES_texture_float_linear");
-S.get("OES_texture_half_float");S.get("OES_texture_half_float_linear");S.get("OES_standard_derivatives");S.get("ANGLE_instanced_arrays");S.get("OES_element_index_uint")&&(THREE.BufferGeometry.MaxIndex=4294967296);var ga=new THREE.WebGLCapabilities(r,S,a),I=new THREE.WebGLState(r,S,C),X=new THREE.WebGLProperties,va=new THREE.WebGLObjects(r,X,this.info),ua=new THREE.WebGLPrograms(this,ga);this.info.programs=ua.programs;var Fa=new THREE.WebGLBufferRenderer(r,S,ka),Ga=new THREE.WebGLIndexedBufferRenderer(r,
-S,ka);c();this.context=r;this.capabilities=ga;this.extensions=S;this.state=I;var ha=new THREE.WebGLShadowMap(this,Y,va);this.shadowMap=ha;var Ha=new THREE.SpritePlugin(this,ja),Ia=new THREE.LensFlarePlugin(this,ca);this.getContext=function(){return r};this.getContextAttributes=function(){return r.getContextAttributes()};this.forceContextLoss=function(){S.get("WEBGL_lose_context").loseContext()};this.getMaxAnisotropy=function(){var a;return function(){if(void 0!==a)return a;var b=S.get("EXT_texture_filter_anisotropic");
-return a=null!==b?r.getParameter(b.MAX_TEXTURE_MAX_ANISOTROPY_EXT):0}}();this.getPrecision=function(){return ga.precision};this.getPixelRatio=function(){return E};this.setPixelRatio=function(a){void 0!==a&&(E=a)};this.getSize=function(){return{width:O,height:K}};this.setSize=function(a,b,c){O=a;K=b;N.width=a*E;N.height=b*E;!1!==c&&(N.style.width=a+"px",N.style.height=b+"px");this.setViewport(0,0,a,b)};this.setViewport=function(a,b,c,d){na=a*E;oa=b*E;pa=c*E;qa=d*E;r.viewport(na,oa,pa,qa)};this.getViewport=
-function(a){a.x=na/E;a.y=oa/E;a.z=pa/E;a.w=qa/E};this.setScissor=function(a,b,c,d){r.scissor(a*E,b*E,c*E,d*E)};this.enableScissorTest=function(a){I.setScissorTest(a)};this.getClearColor=function(){return W};this.setClearColor=function(a,c){W.set(a);U=void 0!==c?c:1;b(W.r,W.g,W.b,U)};this.getClearAlpha=function(){return U};this.setClearAlpha=function(a){U=a;b(W.r,W.g,W.b,U)};this.clear=function(a,b,c){var d=0;if(void 0===a||a)d|=r.COLOR_BUFFER_BIT;if(void 0===b||b)d|=r.DEPTH_BUFFER_BIT;if(void 0===
-c||c)d|=r.STENCIL_BUFFER_BIT;r.clear(d)};this.clearColor=function(){r.clear(r.COLOR_BUFFER_BIT)};this.clearDepth=function(){r.clear(r.DEPTH_BUFFER_BIT)};this.clearStencil=function(){r.clear(r.STENCIL_BUFFER_BIT)};this.clearTarget=function(a,b,c,d){this.setRenderTarget(a);this.clear(b,c,d)};this.resetGLState=d;this.dispose=function(){N.removeEventListener("webglcontextlost",e,!1)};this.renderBufferImmediate=function(a,b,c){I.initAttributes();var d=X.get(a);a.hasPositions&&!d.position&&(d.position=
+S.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 L=void 0!==a.canvas?a.canvas:document.createElement("canvas"),Q=void 0!==a.context?a.context:null,M=L.width,K=L.height,E=1,O=void 0!==a.alpha?a.alpha:!1,T=void 0!==a.depth?a.depth:!0,H=void 0!==a.stencil?a.stencil:!0,R=void 0!==a.antialias?a.antialias:!1,G=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:
+!0,ia=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,U=new THREE.Color(0),X=0,da=[],ca=[],ga=-1,Z=[],fa=-1,ma=new Float32Array(8),ea=[],ja=[];this.domElement=L;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 aa=this,Aa=null,za=null,ta=-1,sa="",ra=null,ya=0,na=0,oa=0,pa=L.width,qa=L.height,
+Da=0,Ea=0,Ba=new THREE.Frustum,xa=new THREE.Matrix4,V=new THREE.Vector3,Y=new THREE.Vector3,wa=!0,Ca={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:[]}},la={geometries:0,textures:0},ka={calls:0,vertices:0,faces:0,points:0};this.info={render:ka,memory:la,programs:null};
+var r;try{O={alpha:O,depth:T,stencil:H,antialias:R,premultipliedAlpha:G,preserveDrawingBuffer:ia};r=Q||L.getContext("webgl",O)||L.getContext("experimental-webgl",O);if(null===r){if(null!==L.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}L.addEventListener("webglcontextlost",e,!1)}catch(Fa){console.error("THREE.WebGLRenderer: "+Fa)}var S=new THREE.WebGLExtensions(r);S.get("OES_texture_float");S.get("OES_texture_float_linear");
+S.get("OES_texture_half_float");S.get("OES_texture_half_float_linear");S.get("OES_standard_derivatives");S.get("ANGLE_instanced_arrays");S.get("OES_element_index_uint")&&(THREE.BufferGeometry.MaxIndex=4294967296);var ha=new THREE.WebGLCapabilities(r,S,a),I=new THREE.WebGLState(r,S,N),W=new THREE.WebGLProperties,va=new THREE.WebGLObjects(r,W,this.info),ua=new THREE.WebGLPrograms(this,ha);this.info.programs=ua.programs;var Ga=new THREE.WebGLBufferRenderer(r,S,ka),Ha=new THREE.WebGLIndexedBufferRenderer(r,
+S,ka);c();this.context=r;this.capabilities=ha;this.extensions=S;this.state=I;var $=new THREE.WebGLShadowMap(this,da,va);this.shadowMap=$;var Ia=new THREE.SpritePlugin(this,ea),Ja=new THREE.LensFlarePlugin(this,ja);this.getContext=function(){return r};this.getContextAttributes=function(){return r.getContextAttributes()};this.forceContextLoss=function(){S.get("WEBGL_lose_context").loseContext()};this.getMaxAnisotropy=function(){var a;return function(){if(void 0!==a)return a;var b=S.get("EXT_texture_filter_anisotropic");
+return a=null!==b?r.getParameter(b.MAX_TEXTURE_MAX_ANISOTROPY_EXT):0}}();this.getPrecision=function(){return ha.precision};this.getPixelRatio=function(){return E};this.setPixelRatio=function(a){void 0!==a&&(E=a)};this.getSize=function(){return{width:M,height:K}};this.setSize=function(a,b,c){M=a;K=b;L.width=a*E;L.height=b*E;!1!==c&&(L.style.width=a+"px",L.style.height=b+"px");this.setViewport(0,0,a,b)};this.setViewport=function(a,b,c,d){na=a*E;oa=b*E;pa=c*E;qa=d*E;r.viewport(na,oa,pa,qa)};this.getViewport=
+function(a){a.x=na/E;a.y=oa/E;a.z=pa/E;a.w=qa/E};this.setScissor=function(a,b,c,d){r.scissor(a*E,b*E,c*E,d*E)};this.enableScissorTest=function(a){I.setScissorTest(a)};this.getClearColor=function(){return U};this.setClearColor=function(a,c){U.set(a);X=void 0!==c?c:1;b(U.r,U.g,U.b,X)};this.getClearAlpha=function(){return X};this.setClearAlpha=function(a){X=a;b(U.r,U.g,U.b,X)};this.clear=function(a,b,c){var d=0;if(void 0===a||a)d|=r.COLOR_BUFFER_BIT;if(void 0===b||b)d|=r.DEPTH_BUFFER_BIT;if(void 0===
+c||c)d|=r.STENCIL_BUFFER_BIT;r.clear(d)};this.clearColor=function(){r.clear(r.COLOR_BUFFER_BIT)};this.clearDepth=function(){r.clear(r.DEPTH_BUFFER_BIT)};this.clearStencil=function(){r.clear(r.STENCIL_BUFFER_BIT)};this.clearTarget=function(a,b,c,d){this.setRenderTarget(a);this.clear(b,c,d)};this.resetGLState=d;this.dispose=function(){L.removeEventListener("webglcontextlost",e,!1)};this.renderBufferImmediate=function(a,b,c){I.initAttributes();var d=W.get(a);a.hasPositions&&!d.position&&(d.position=
 r.createBuffer());a.hasNormals&&!d.normal&&(d.normal=r.createBuffer());a.hasUvs&&!d.uv&&(d.uv=r.createBuffer());a.hasColors&&!d.color&&(d.color=r.createBuffer());b=b.getAttributes();a.hasPositions&&(r.bindBuffer(r.ARRAY_BUFFER,d.position),r.bufferData(r.ARRAY_BUFFER,a.positionArray,r.DYNAMIC_DRAW),I.enableAttribute(b.position),r.vertexAttribPointer(b.position,3,r.FLOAT,!1,0,0));if(a.hasNormals){r.bindBuffer(r.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}r.bufferData(r.ARRAY_BUFFER,a.normalArray,r.DYNAMIC_DRAW);I.enableAttribute(b.normal);r.vertexAttribPointer(b.normal,3,r.FLOAT,!1,0,0)}a.hasUvs&&c.map&&(r.bindBuffer(r.ARRAY_BUFFER,d.uv),r.bufferData(r.ARRAY_BUFFER,a.uvArray,r.DYNAMIC_DRAW),I.enableAttribute(b.uv),r.vertexAttribPointer(b.uv,2,r.FLOAT,
-!1,0,0));a.hasColors&&c.vertexColors!==THREE.NoColors&&(r.bindBuffer(r.ARRAY_BUFFER,d.color),r.bufferData(r.ARRAY_BUFFER,a.colorArray,r.DYNAMIC_DRAW),I.enableAttribute(b.color),r.vertexAttribPointer(b.color,3,r.FLOAT,!1,0,0));I.disableUnusedAttributes();r.drawArrays(r.TRIANGLES,0,a.count);a.count=0};this.renderBufferDirect=function(a,b,c,d,e,f,g){s(e);var h=u(a,b,c,e,f),l=!1;a=d.id+"_"+h.id+"_"+e.wireframe;a!==sa&&(sa=a,l=!0);b=f.morphTargetInfluences;if(void 0!==b){a=[];c=0;for(l=b.length;c<l;c++){var m=
-b[c];a.push([m,c])}a.sort(k);8<a.length&&(a.length=8);var n=d.morphAttributes;c=0;for(l=a.length;c<l;c++)m=a[c],ma[c]=m[0],0!==m[0]?(b=m[1],!0===e.morphTargets&&n.position&&d.addAttribute("morphTarget"+c,n.position[b]),!0===e.morphNormals&&n.normal&&d.addAttribute("morphNormal"+c,n.normal[b])):(!0===e.morphTargets&&d.removeAttribute("morphTarget"+c),!0===e.morphNormals&&d.removeAttribute("morphNormal"+c));a=h.getUniforms();null!==a.morphTargetInfluences&&r.uniform1fv(a.morphTargetInfluences,ma);l=
-!0}b=d.index;c=d.attributes.position;!0===e.wireframe&&(b=va.getWireframeAttribute(d));null!==b?(a=Ga,a.setIndex(b)):a=Fa;if(l){a:{var l=void 0,p;if(d instanceof THREE.InstancedBufferGeometry&&(p=S.get("ANGLE_instanced_arrays"),null===p)){console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");break a}void 0===l&&(l=0);I.initAttributes();var m=d.attributes,h=h.getAttributes(),n=e.defaultAttributeValues,
-q;for(q in h){var t=h[q];if(0<=t){var v=m[q];if(void 0!==v){var x=v.itemSize,w=va.getAttributeBuffer(v);if(v instanceof THREE.InterleavedBufferAttribute){var G=v.data,D=G.stride,v=v.offset;G instanceof THREE.InstancedInterleavedBuffer?(I.enableAttributeAndDivisor(t,G.meshPerAttribute,p),void 0===d.maxInstancedCount&&(d.maxInstancedCount=G.meshPerAttribute*G.count)):I.enableAttribute(t);r.bindBuffer(r.ARRAY_BUFFER,w);r.vertexAttribPointer(t,x,r.FLOAT,!1,D*G.array.BYTES_PER_ELEMENT,(l*D+v)*G.array.BYTES_PER_ELEMENT)}else v instanceof
-THREE.InstancedBufferAttribute?(I.enableAttributeAndDivisor(t,v.meshPerAttribute,p),void 0===d.maxInstancedCount&&(d.maxInstancedCount=v.meshPerAttribute*v.count)):I.enableAttribute(t),r.bindBuffer(r.ARRAY_BUFFER,w),r.vertexAttribPointer(t,x,r.FLOAT,!1,0,l*x*4)}else if(void 0!==n&&(x=n[q],void 0!==x))switch(x.length){case 2:r.vertexAttrib2fv(t,x);break;case 3:r.vertexAttrib3fv(t,x);break;case 4:r.vertexAttrib4fv(t,x);break;default:r.vertexAttrib1fv(t,x)}}}I.disableUnusedAttributes()}null!==b&&r.bindBuffer(r.ELEMENT_ARRAY_BUFFER,
-va.getAttributeBuffer(b))}p=Infinity;null!==b?p=b.count:void 0!==c&&(p=c.count);q=d.drawRange.start;b=d.drawRange.count;c=null!==g?g.start:0;l=null!==g?g.count:Infinity;g=Math.max(0,q,c);p=Math.min(0+p,q+b,c+l)-1;p=Math.max(0,p-g+1);f instanceof THREE.Mesh?(!0===e.wireframe?(I.setLineWidth(e.wireframeLinewidth*E),a.setMode(r.LINES)):a.setMode(r.TRIANGLES),d instanceof THREE.InstancedBufferGeometry&&0<d.maxInstancedCount?a.renderInstances(d):a.render(g,p)):f instanceof THREE.Line?(d=e.linewidth,void 0===
-d&&(d=1),I.setLineWidth(d*E),f instanceof THREE.LineSegments?a.setMode(r.LINES):a.setMode(r.LINE_STRIP),a.render(g,p)):f instanceof THREE.Points&&(a.setMode(r.POINTS),a.render(g,p))};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;sa="";ta=-1;ra=null;wa=!0;!0===a.autoUpdate&&a.updateMatrixWorld();null===b.parent&&b.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);
-xa.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);Aa.setFromMatrix(xa);Y.length=0;$=fa=-1;ja.length=0;ca.length=0;q(a);ea.length=fa+1;da.length=$+1;!0===aa.sortObjects&&(ea.sort(n),da.sort(p));ha.render(a);ka.calls=0;ka.vertices=0;ka.faces=0;ka.points=0;this.setRenderTarget(c);(this.autoClear||d)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil);a.overrideMaterial?(d=a.overrideMaterial,t(ea,b,Y,e,d),t(da,b,Y,e,d)):(I.setBlending(THREE.NoBlending),t(ea,b,Y,e),t(da,
-b,Y,e));Ha.render(a,b);Ia.render(a,b,Ca,Da);c&&(a=c.texture,b=THREE.Math.isPowerOfTwo(c.width)&&THREE.Math.isPowerOfTwo(c.height),a.generateMipmaps&&b&&a.minFilter!==THREE.NearestFilter&&a.minFilter!==THREE.LinearFilter&&(a=c instanceof THREE.WebGLRenderTargetCube?r.TEXTURE_CUBE_MAP:r.TEXTURE_2D,c=X.get(c.texture).__webglTexture,I.bindTexture(a,c),r.generateMipmap(a),I.bindTexture(a,null)));I.setDepthTest(!0);I.setDepthWrite(!0);I.setColorWrite(!0)}};this.setFaceCulling=function(a,b){a===THREE.CullFaceNone?
-I.disable(r.CULL_FACE):(b===THREE.FrontFaceDirectionCW?r.frontFace(r.CW):r.frontFace(r.CCW),a===THREE.CullFaceBack?r.cullFace(r.BACK):a===THREE.CullFaceFront?r.cullFace(r.FRONT):r.cullFace(r.FRONT_AND_BACK),I.enable(r.CULL_FACE))};this.setTexture=function(a,b){var c=X.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=r.createTexture(),la.textures++);I.activeTexture(r.TEXTURE0+b);I.bindTexture(r.TEXTURE_2D,c.__webglTexture);r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,a.flipY);r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,a.premultiplyAlpha);r.pixelStorei(r.UNPACK_ALIGNMENT,a.unpackAlignment);a.image=A(a.image,ga.maxTextureSize);var e=a.image,d=THREE.Math.isPowerOfTwo(e.width)&&THREE.Math.isPowerOfTwo(e.height),
-f=C(a.format),h=C(a.type);w(r.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],I.texImage2D(r.TEXTURE_2D,l,f,e.width,e.height,0,f,h,e.data);a.generateMipmaps=!1}else I.texImage2D(r.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<I.getCompressedTextureFormats().indexOf(f)?I.compressedTexImage2D(r.TEXTURE_2D,
-l,f,e.width,e.height,0,e.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"):I.texImage2D(r.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],I.texImage2D(r.TEXTURE_2D,l,f,f,h,e);a.generateMipmaps=!1}else I.texImage2D(r.TEXTURE_2D,0,f,f,h,a.image);a.generateMipmaps&&d&&r.generateMipmap(r.TEXTURE_2D);c.__version=a.version;if(a.onUpdate)a.onUpdate(a)}}else I.activeTexture(r.TEXTURE0+
-b),I.bindTexture(r.TEXTURE_2D,c.__webglTexture)};this.setRenderTarget=function(a){var b=a instanceof THREE.WebGLRenderTargetCube;if(a&&void 0===X.get(a).__webglFramebuffer){var c=X.get(a),d=X.get(a.texture);void 0===a.depthBuffer&&(a.depthBuffer=!0);void 0===a.stencilBuffer&&(a.stencilBuffer=!0);a.addEventListener("dispose",f);d.__webglTexture=r.createTexture();la.textures++;var e=THREE.Math.isPowerOfTwo(a.width)&&THREE.Math.isPowerOfTwo(a.height),g=C(a.texture.format),h=C(a.texture.type);if(b){c.__webglFramebuffer=
-[];c.__webglRenderbuffer=[];I.bindTexture(r.TEXTURE_CUBE_MAP,d.__webglTexture);w(r.TEXTURE_CUBE_MAP,a.texture,e);for(d=0;6>d;d++)c.__webglFramebuffer[d]=r.createFramebuffer(),c.__webglRenderbuffer[d]=r.createRenderbuffer(),I.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+d,0,g,a.width,a.height,0,g,h,null),y(c.__webglFramebuffer[d],a,r.TEXTURE_CUBE_MAP_POSITIVE_X+d),L(c.__webglRenderbuffer[d],a);a.texture.generateMipmaps&&e&&r.generateMipmap(r.TEXTURE_CUBE_MAP)}else c.__webglFramebuffer=r.createFramebuffer(),
-c.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:r.createRenderbuffer(),I.bindTexture(r.TEXTURE_2D,d.__webglTexture),w(r.TEXTURE_2D,a.texture,e),I.texImage2D(r.TEXTURE_2D,0,g,a.width,a.height,0,g,h,null),y(c.__webglFramebuffer,a,r.TEXTURE_2D),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_ATTACHMENT,r.RENDERBUFFER,c.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_STENCIL_ATTACHMENT,
-r.RENDERBUFFER,c.__webglRenderbuffer):L(c.__webglRenderbuffer,a),a.texture.generateMipmaps&&e&&r.generateMipmap(r.TEXTURE_2D);b?I.bindTexture(r.TEXTURE_CUBE_MAP,null):I.bindTexture(r.TEXTURE_2D,null);r.bindRenderbuffer(r.RENDERBUFFER,null);r.bindFramebuffer(r.FRAMEBUFFER,null)}a?(c=X.get(a),d=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,c=a.width,e=a.height,h=g=0):(d=null,c=pa,e=qa,g=na,h=oa);d!==ia&&(r.bindFramebuffer(r.FRAMEBUFFER,d),r.viewport(g,h,c,e),ia=d);b&&(d=X.get(a.texture),
-r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,d.__webglTexture,0));Ca=c;Da=e};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!1===a instanceof THREE.WebGLRenderTarget)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else{var g=X.get(a).__webglFramebuffer;if(g){var h=!1;g!==ia&&(r.bindFramebuffer(r.FRAMEBUFFER,g),h=!0);try{var k=a.texture;k.format!==THREE.RGBAFormat&&C(k.format)!==
-r.getParameter(r.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."):k.type===THREE.UnsignedByteType||C(k.type)===r.getParameter(r.IMPLEMENTATION_COLOR_READ_TYPE)||k.type===THREE.FloatType&&S.get("WEBGL_color_buffer_float")||k.type===THREE.HalfFloatType&&S.get("EXT_color_buffer_half_float")?r.checkFramebufferStatus(r.FRAMEBUFFER)===r.FRAMEBUFFER_COMPLETE?r.readPixels(b,c,d,e,C(k.format),C(k.type),
-f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."):console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.")}finally{h&&r.bindFramebuffer(r.FRAMEBUFFER,ia)}}}};this.supportsFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' ).");return S.get("OES_texture_float")};this.supportsHalfFloatTextures=
-function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).");return S.get("OES_texture_half_float")};this.supportsStandardDerivatives=function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");return S.get("OES_standard_derivatives")};this.supportsCompressedTextureS3TC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' ).");
-return S.get("WEBGL_compressed_texture_s3tc")};this.supportsCompressedTexturePVRTC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return S.get("WEBGL_compressed_texture_pvrtc")};this.supportsBlendMinMax=function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return S.get("EXT_blend_minmax")};this.supportsVertexTextures=function(){return ga.vertexTextures};
-this.supportsInstancedArrays=function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).");return S.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 ha.enabled},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");ha.enabled=a}},shadowMapType:{get:function(){return ha.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.");ha.type=a}},shadowMapCullFace:{get:function(){return ha.cullFace},
-set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");ha.cullFace=a}},shadowMapDebug:{get:function(){return ha.debug},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapDebug is now .shadowMap.debug.");ha.debug=a}}})};
+!1,0,0));a.hasColors&&c.vertexColors!==THREE.NoColors&&(r.bindBuffer(r.ARRAY_BUFFER,d.color),r.bufferData(r.ARRAY_BUFFER,a.colorArray,r.DYNAMIC_DRAW),I.enableAttribute(b.color),r.vertexAttribPointer(b.color,3,r.FLOAT,!1,0,0));I.disableUnusedAttributes();r.drawArrays(r.TRIANGLES,0,a.count);a.count=0};this.renderBufferDirect=function(a,b,c,d,e,f,g){t(e);var h=v(a,b,c,e,f),l=!1;a=d.id+"_"+h.id+"_"+e.wireframe;a!==sa&&(sa=a,l=!0);b=f.morphTargetInfluences;if(void 0!==b){a=[];c=0;for(l=b.length;c<l;c++){var n=
+b[c];a.push([n,c])}a.sort(k);8<a.length&&(a.length=8);var m=d.morphAttributes;c=0;for(l=a.length;c<l;c++)n=a[c],ma[c]=n[0],0!==n[0]?(b=n[1],!0===e.morphTargets&&m.position&&d.addAttribute("morphTarget"+c,m.position[b]),!0===e.morphNormals&&m.normal&&d.addAttribute("morphNormal"+c,m.normal[b])):(!0===e.morphTargets&&d.removeAttribute("morphTarget"+c),!0===e.morphNormals&&d.removeAttribute("morphNormal"+c));a=h.getUniforms();null!==a.morphTargetInfluences&&r.uniform1fv(a.morphTargetInfluences,ma);l=
+!0}b=d.index;c=d.attributes.position;!0===e.wireframe&&(b=va.getWireframeAttribute(d));null!==b?(a=Ha,a.setIndex(b)):a=Ga;if(l){a:{var l=void 0,q;if(d instanceof THREE.InstancedBufferGeometry&&(q=S.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===l&&(l=0);I.initAttributes();var n=d.attributes,h=h.getAttributes(),m=e.defaultAttributeValues,
+p;for(p in h){var s=h[p];if(0<=s){var u=n[p];if(void 0!==u){var w=u.itemSize,x=va.getAttributeBuffer(u);if(u instanceof THREE.InterleavedBufferAttribute){var F=u.data,D=F.stride,u=u.offset;F instanceof THREE.InstancedInterleavedBuffer?(I.enableAttributeAndDivisor(s,F.meshPerAttribute,q),void 0===d.maxInstancedCount&&(d.maxInstancedCount=F.meshPerAttribute*F.count)):I.enableAttribute(s);r.bindBuffer(r.ARRAY_BUFFER,x);r.vertexAttribPointer(s,w,r.FLOAT,!1,D*F.array.BYTES_PER_ELEMENT,(l*D+u)*F.array.BYTES_PER_ELEMENT)}else u instanceof
+THREE.InstancedBufferAttribute?(I.enableAttributeAndDivisor(s,u.meshPerAttribute,q),void 0===d.maxInstancedCount&&(d.maxInstancedCount=u.meshPerAttribute*u.count)):I.enableAttribute(s),r.bindBuffer(r.ARRAY_BUFFER,x),r.vertexAttribPointer(s,w,r.FLOAT,!1,0,l*w*4)}else if(void 0!==m&&(w=m[p],void 0!==w))switch(w.length){case 2:r.vertexAttrib2fv(s,w);break;case 3:r.vertexAttrib3fv(s,w);break;case 4:r.vertexAttrib4fv(s,w);break;default:r.vertexAttrib1fv(s,w)}}}I.disableUnusedAttributes()}null!==b&&r.bindBuffer(r.ELEMENT_ARRAY_BUFFER,
+va.getAttributeBuffer(b))}q=Infinity;null!==b?q=b.count:void 0!==c&&(q=c.count);p=d.drawRange.start;b=d.drawRange.count;c=null!==g?g.start:0;l=null!==g?g.count:Infinity;g=Math.max(0,p,c);q=Math.min(0+q,p+b,c+l)-1;q=Math.max(0,q-g+1);f instanceof THREE.Mesh?(!0===e.wireframe?(I.setLineWidth(e.wireframeLinewidth*E),a.setMode(r.LINES)):a.setMode(r.TRIANGLES),d instanceof THREE.InstancedBufferGeometry&&0<d.maxInstancedCount?a.renderInstances(d):a.render(g,q)):f instanceof THREE.Line?(d=e.linewidth,void 0===
+d&&(d=1),I.setLineWidth(d*E),f instanceof THREE.LineSegments?a.setMode(r.LINES):a.setMode(r.LINE_STRIP),a.render(g,q)):f instanceof THREE.Points&&(a.setMode(r.POINTS),a.render(g,q))};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;sa="";ta=-1;ra=null;wa=!0;!0===a.autoUpdate&&a.updateMatrixWorld();null===b.parent&&b.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);
+xa.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);Ba.setFromMatrix(xa);da.length=0;fa=ga=-1;ea.length=0;ja.length=0;q(a,b);ca.length=ga+1;Z.length=fa+1;!0===aa.sortObjects&&(ca.sort(m),Z.sort(p));$.render(a);ka.calls=0;ka.vertices=0;ka.faces=0;ka.points=0;this.setRenderTarget(c);(this.autoClear||d)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil);a.overrideMaterial?(d=a.overrideMaterial,s(ca,b,da,e,d),s(Z,b,da,e,d)):(I.setBlending(THREE.NoBlending),s(ca,b,da,e),
+s(Z,b,da,e));Ia.render(a,b);Ja.render(a,b,Da,Ea);c&&(a=c.texture,b=y(c),a.generateMipmaps&&b&&a.minFilter!==THREE.NearestFilter&&a.minFilter!==THREE.LinearFilter&&(a=c instanceof THREE.WebGLRenderTargetCube?r.TEXTURE_CUBE_MAP:r.TEXTURE_2D,c=W.get(c.texture).__webglTexture,I.bindTexture(a,c),r.generateMipmap(a),I.bindTexture(a,null)));I.setDepthTest(!0);I.setDepthWrite(!0);I.setColorWrite(!0)}};this.setFaceCulling=function(a,b){a===THREE.CullFaceNone?I.disable(r.CULL_FACE):(b===THREE.FrontFaceDirectionCW?
+r.frontFace(r.CW):r.frontFace(r.CCW),a===THREE.CullFaceBack?r.cullFace(r.BACK):a===THREE.CullFaceFront?r.cullFace(r.FRONT):r.cullFace(r.FRONT_AND_BACK),I.enable(r.CULL_FACE))};this.setTexture=function(a,b){var c=W.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.addEventListener("dispose",g),c.__webglTexture=r.createTexture(),la.textures++);I.activeTexture(r.TEXTURE0+b);I.bindTexture(r.TEXTURE_2D,c.__webglTexture);r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,a.flipY);r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,a.premultiplyAlpha);r.pixelStorei(r.UNPACK_ALIGNMENT,a.unpackAlignment);a.image=B(a.image,ha.maxTextureSize);if((a.wrapS!==THREE.ClampToEdgeWrapping||a.wrapT!==THREE.ClampToEdgeWrapping||a.minFilter!==THREE.NearestFilter&&
+a.minFilter!==THREE.LinearFilter)&&!1===y(a.image)){d=a.image;if(d instanceof HTMLImageElement||d instanceof HTMLCanvasElement){var e=document.createElement("canvas");e.width=THREE.Math.nearestPowerOfTwo(d.width);e.height=THREE.Math.nearestPowerOfTwo(d.height);e.getContext("2d").drawImage(d,0,0,e.width,e.height);console.warn("THREE.WebGLRenderer: image is not power of two ("+d.width+"x"+d.height+"). Resized to "+e.width+"x"+e.height,d);d=e}a.image=d}var f=a.image,d=y(f),e=N(a.format),h=N(a.type);
+x(r.TEXTURE_2D,a,d);var k=a.mipmaps;if(a instanceof THREE.DataTexture)if(0<k.length&&d){for(var l=0,n=k.length;l<n;l++)f=k[l],I.texImage2D(r.TEXTURE_2D,l,e,f.width,f.height,0,e,h,f.data);a.generateMipmaps=!1}else I.texImage2D(r.TEXTURE_2D,0,e,f.width,f.height,0,e,h,f.data);else if(a instanceof THREE.CompressedTexture)for(l=0,n=k.length;l<n;l++)f=k[l],a.format!==THREE.RGBAFormat&&a.format!==THREE.RGBFormat?-1<I.getCompressedTextureFormats().indexOf(e)?I.compressedTexImage2D(r.TEXTURE_2D,l,e,f.width,
+f.height,0,f.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"):I.texImage2D(r.TEXTURE_2D,l,e,f.width,f.height,0,e,h,f.data);else if(0<k.length&&d){l=0;for(n=k.length;l<n;l++)f=k[l],I.texImage2D(r.TEXTURE_2D,l,e,e,h,f);a.generateMipmaps=!1}else I.texImage2D(r.TEXTURE_2D,0,e,e,h,a.image);a.generateMipmaps&&d&&r.generateMipmap(r.TEXTURE_2D);c.__version=a.version;if(a.onUpdate)a.onUpdate(a)}}else I.activeTexture(r.TEXTURE0+b),I.bindTexture(r.TEXTURE_2D,
+c.__webglTexture)};this.setRenderTarget=function(a){var b=a instanceof THREE.WebGLRenderTargetCube;if(a&&void 0===W.get(a).__webglFramebuffer){var c=W.get(a),d=W.get(a.texture);void 0===a.depthBuffer&&(a.depthBuffer=!0);void 0===a.stencilBuffer&&(a.stencilBuffer=!0);a.addEventListener("dispose",f);d.__webglTexture=r.createTexture();la.textures++;var e=y(a),g=N(a.texture.format),h=N(a.texture.type);if(b){c.__webglFramebuffer=[];c.__webglRenderbuffer=[];I.bindTexture(r.TEXTURE_CUBE_MAP,d.__webglTexture);
+x(r.TEXTURE_CUBE_MAP,a.texture,e);for(d=0;6>d;d++)c.__webglFramebuffer[d]=r.createFramebuffer(),c.__webglRenderbuffer[d]=r.createRenderbuffer(),I.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+d,0,g,a.width,a.height,0,g,h,null),J(c.__webglFramebuffer[d],a,r.TEXTURE_CUBE_MAP_POSITIVE_X+d),F(c.__webglRenderbuffer[d],a);a.texture.generateMipmaps&&e&&r.generateMipmap(r.TEXTURE_CUBE_MAP)}else c.__webglFramebuffer=r.createFramebuffer(),c.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:
+r.createRenderbuffer(),I.bindTexture(r.TEXTURE_2D,d.__webglTexture),x(r.TEXTURE_2D,a.texture,e),I.texImage2D(r.TEXTURE_2D,0,g,a.width,a.height,0,g,h,null),J(c.__webglFramebuffer,a,r.TEXTURE_2D),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_ATTACHMENT,r.RENDERBUFFER,c.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_STENCIL_ATTACHMENT,r.RENDERBUFFER,c.__webglRenderbuffer):F(c.__webglRenderbuffer,
+a),a.texture.generateMipmaps&&e&&r.generateMipmap(r.TEXTURE_2D);b?I.bindTexture(r.TEXTURE_CUBE_MAP,null):I.bindTexture(r.TEXTURE_2D,null);r.bindRenderbuffer(r.RENDERBUFFER,null);r.bindFramebuffer(r.FRAMEBUFFER,null)}a?(c=W.get(a),d=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,c=a.width,e=a.height,h=g=0):(d=null,c=pa,e=qa,g=na,h=oa);d!==za&&(r.bindFramebuffer(r.FRAMEBUFFER,d),r.viewport(g,h,c,e),za=d);b&&(d=W.get(a.texture),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,
+r.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,d.__webglTexture,0));Da=c;Ea=e};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!1===a instanceof THREE.WebGLRenderTarget)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else{var g=W.get(a).__webglFramebuffer;if(g){var h=!1;g!==za&&(r.bindFramebuffer(r.FRAMEBUFFER,g),h=!0);try{var k=a.texture;k.format!==THREE.RGBAFormat&&N(k.format)!==r.getParameter(r.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."):
+k.type===THREE.UnsignedByteType||N(k.type)===r.getParameter(r.IMPLEMENTATION_COLOR_READ_TYPE)||k.type===THREE.FloatType&&S.get("WEBGL_color_buffer_float")||k.type===THREE.HalfFloatType&&S.get("EXT_color_buffer_half_float")?r.checkFramebufferStatus(r.FRAMEBUFFER)===r.FRAMEBUFFER_COMPLETE?r.readPixels(b,c,d,e,N(k.format),N(k.type),f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."):console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.")}finally{h&&
+r.bindFramebuffer(r.FRAMEBUFFER,za)}}}};this.supportsFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' ).");return S.get("OES_texture_float")};this.supportsHalfFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).");return S.get("OES_texture_half_float")};this.supportsStandardDerivatives=function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");
+return S.get("OES_standard_derivatives")};this.supportsCompressedTextureS3TC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' ).");return S.get("WEBGL_compressed_texture_s3tc")};this.supportsCompressedTexturePVRTC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return S.get("WEBGL_compressed_texture_pvrtc")};this.supportsBlendMinMax=
+function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return S.get("EXT_blend_minmax")};this.supportsVertexTextures=function(){return ha.vertexTextures};this.supportsInstancedArrays=function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).");return S.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 $.enabled},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");$.enabled=a}},
+shadowMapType:{get:function(){return $.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.");$.type=a}},shadowMapCullFace:{get:function(){return $.cullFace},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");$.cullFace=a}},shadowMapDebug:{get:function(){return $.debug},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapDebug is now .shadowMap.debug.");$.debug=a}}})};
 THREE.WebGLRenderTarget=function(a,b,c){this.uuid=THREE.Math.generateUUID();this.width=a;this.height=b;c=c||{};void 0===c.minFilter&&(c.minFilter=THREE.LinearFilter);this.texture=new THREE.Texture(void 0,void 0,c.wrapS,c.wrapT,c.magFilter,c.minFilter,c.format,c.type,c.anisotropy);this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null};
 THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,get wrapS(){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.");return this.texture.wrapS},set wrapS(a){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.");this.texture.wrapS=a},get wrapT(){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.");return this.texture.wrapT},set wrapT(a){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.");this.texture.wrapT=a},
 get magFilter(){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.");return this.texture.magFilter},set magFilter(a){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.");this.texture.magFilter=a},get minFilter(){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.");return this.texture.minFilter},set minFilter(a){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.");this.texture.minFilter=a},get anisotropy(){console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.");
@@ -628,81 +631,79 @@ THREE.WebGLGeometries=function(a,b,c){function d(a){a=a.target;var h=g[a.id].att
 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){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 l=[],k=c.index,n=c.attributes;c=n.position;if(null!==k)for(var n={},k=k.array,p=0,m=k.length;p<m;p+=3){var q=k[p+0],t=k[p+1],s=k[p+2];e(n,q,t)&&l.push(q,t);e(n,t,s)&&l.push(t,s);e(n,s,q)&&l.push(s,q)}else for(k=n.position.array,p=0,m=k.length/3-1;p<m;p+=3)q=p+0,t=p+1,s=p+2,l.push(q,t,t,s,s,q);l=new THREE.BufferAttribute(new (65535<c.count?Uint32Array:Uint16Array)(l),1);d(l,a.ELEMENT_ARRAY_BUFFER);return g.wireframe=l};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 k in e)d(e[k],a.ARRAY_BUFFER);b=c.morphAttributes;for(k in b)for(var e=b[k],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,l=g.defines,k=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 s=0<d.gammaFactor?d.gammaFactor:1,u=a(l),x=h.createProgram();g instanceof THREE.RawShaderMaterial?d=l="":(l=["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 "+s,"#define MAX_DIR_LIGHTS "+
+function(c){var g=b.get(c);if(void 0!==g.wireframe)return g.wireframe;var l=[],k=c.index,m=c.attributes;c=m.position;if(null!==k)for(var m={},k=k.array,p=0,n=k.length;p<n;p+=3){var q=k[p+0],s=k[p+1],t=k[p+2];e(m,q,s)&&l.push(q,s);e(m,s,t)&&l.push(s,t);e(m,t,q)&&l.push(t,q)}else for(k=m.position.array,p=0,n=k.length/3-1;p<n;p+=3)q=p+0,s=p+1,t=p+2,l.push(q,s,s,t,t,q);l=new THREE.BufferAttribute(new (65535<c.count?Uint32Array:Uint16Array)(l),1);d(l,a.ELEMENT_ARRAY_BUFFER);return g.wireframe=l};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 k in e)d(e[k],a.ARRAY_BUFFER);b=c.morphAttributes;for(k in b)for(var e=b[k],m=0,p=e.length;m<p;m++)d(e[m],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,l=g.defines,k=g.__webglShader.vertexShader,m=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 n="ENVMAP_TYPE_CUBE",q="ENVMAP_MODE_REFLECTION",s="ENVMAP_BLENDING_MULTIPLY";
+if(f.envMap){switch(g.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:n="ENVMAP_TYPE_CUBE";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:n="ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:n="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 t=0<d.gammaFactor?d.gammaFactor:1,v=a(l),u=h.createProgram();g instanceof THREE.RawShaderMaterial?d=l="":(l=["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 "+t,"#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.displacementMap&&
 f.supportsVertexTextures?"#define USE_DISPLACEMENTMAP":"",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":"",0<f.pointLightShadows?"#define POINT_LIGHT_SHADOWS":"",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 "+s,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":"",0<f.pointLightShadows?"#define POINT_LIGHT_SHADOWS":"",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;
-k=THREE.WebGLShader(h,h.VERTEX_SHADER,l+k);n=THREE.WebGLShader(h,h.FRAGMENT_SHADER,n);h.attachShader(x,k);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(k);m=h.getShaderInfoLog(n);t=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)t=!1;t&&(this.diagnostics={runnable:q,material:g,programLog:f,vertexShader:{log:p,prefix:l},fragmentShader:{log:m,prefix:d}});h.deleteShader(k);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 D;this.getAttributes=function(){if(void 0===D){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)}D=a}return D};this.destroy=function(){h.deleteProgram(x);this.program=void 0};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=k;this.fragmentShader=n;return this}}();
+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 "+t,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 "+n:"",f.envMap?"#define "+q:"",f.envMap?"#define "+s:"",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":"",0<f.pointLightShadows?"#define POINT_LIGHT_SHADOWS":"",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"));m=d+m;
+k=THREE.WebGLShader(h,h.VERTEX_SHADER,l+k);m=THREE.WebGLShader(h,h.FRAGMENT_SHADER,m);h.attachShader(u,k);h.attachShader(u,m);void 0!==g.index0AttributeName?h.bindAttribLocation(u,0,g.index0AttributeName):!0===f.morphTargets&&h.bindAttribLocation(u,0,"position");h.linkProgram(u);f=h.getProgramInfoLog(u);p=h.getShaderInfoLog(k);n=h.getShaderInfoLog(m);s=q=!0;if(!1===h.getProgramParameter(u,h.LINK_STATUS))q=!1,console.error("THREE.WebGLProgram: shader error: ",h.getError(),"gl.VALIDATE_STATUS",h.getProgramParameter(u,
+h.VALIDATE_STATUS),"gl.getProgramInfoLog",f,p,n);else if(""!==f)console.warn("THREE.WebGLProgram: gl.getProgramInfoLog()",f);else if(""===p||""===n)s=!1;s&&(this.diagnostics={runnable:q,material:g,programLog:f,vertexShader:{log:p,prefix:l},fragmentShader:{log:n,prefix:d}});h.deleteShader(k);h.deleteShader(m);var w;this.getUniforms=function(){if(void 0===w){for(var a={},b=h.getProgramParameter(u,h.ACTIVE_UNIFORMS),c=0;c<b;c++){var d=h.getActiveUniform(u,c).name,e=h.getUniformLocation(u,d),f=d.lastIndexOf("[0]");
+-1!==f&&f===d.length-3&&(a[d.substr(0,f)]=e);a[d]=e}w=a}return w};var D;this.getAttributes=function(){if(void 0===D){for(var a={},b=h.getProgramParameter(u,h.ACTIVE_ATTRIBUTES),c=0;c<b;c++){var d=h.getActiveAttrib(u,c).name;a[d]=h.getAttribLocation(u,d)}D=a}return D};this.destroy=function(){h.deleteProgram(u);this.program=void 0};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=u;this.vertexShader=k;this.fragmentShader=m;return this}}();
 THREE.WebGLPrograms=function(a,b){var c=[],d={MeshDepthMaterial:"depth",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointsMaterial:"points"},e="precision supportsVertexTextures map envMap envMapMode lightMap aoMap emissiveMap bumpMap normalMap displacementMap specularMap alphaMap combine vertexColors fog useFog fogExp flatShading sizeAttenuation logarithmicDepthBuffer skinning maxBones useVertexTexture morphTargets morphNormals maxMorphTargets maxMorphNormals maxDirLights maxPointLights maxSpotLights maxHemiLights maxShadows shadowMapEnabled pointLightShadows shadowMapType shadowMapDebug alphaTest metal doubleSided flipSided".split(" ");this.getParameters=
-function(c,e,h,l){var k,n,p,m,q,t=d[c.type];k=q=m=p=n=0;for(var s=e.length;k<s;k++){var u=e[k];!1!==u.visible&&(u instanceof THREE.DirectionalLight&&n++,u instanceof THREE.PointLight&&p++,u instanceof THREE.SpotLight&&m++,u instanceof THREE.HemisphereLight&&q++)}for(var u=k=s=0,x=e.length;u<x;u++){var v=e[u];v.castShadow&&((v instanceof THREE.SpotLight||v instanceof THREE.DirectionalLight)&&s++,v instanceof THREE.PointLight&&(s++,k++))}e=s;b.floatVertexTextures&&l&&l.skeleton&&l.skeleton.useVertexTexture?
-s=1024:(s=Math.floor((b.maxVertexUniforms-20)/4),void 0!==l&&l instanceof THREE.SkinnedMesh&&(s=Math.min(l.skeleton.bones.length,s),s<l.skeleton.bones.length&&console.warn("WebGLRenderer: too many bones - "+l.skeleton.bones.length+", this GPU supports just "+s+" (try OpenGL instead of ANGLE)")));u=a.getPrecision();null!==c.precision&&(u=b.getMaxPrecision(c.precision),u!==c.precision&&console.warn("THREE.WebGLRenderer.initMaterial:",c.precision,"not supported, using",u,"instead."));return{shaderID:t,
-precision:u,supportsVertexTextures:b.vertexTextures,map:!!c.map,envMap:!!c.envMap,envMapMode:c.envMap&&c.envMap.mapping,lightMap:!!c.lightMap,aoMap:!!c.aoMap,emissiveMap:!!c.emissiveMap,bumpMap:!!c.bumpMap,normalMap:!!c.normalMap,displacementMap:!!c.displacementMap,specularMap:!!c.specularMap,alphaMap:!!c.alphaMap,combine:c.combine,vertexColors:c.vertexColors,fog:h,useFog:c.fog,fogExp:h instanceof THREE.FogExp2,flatShading:c.shading===THREE.FlatShading,sizeAttenuation:c.sizeAttenuation,logarithmicDepthBuffer:b.logarithmicDepthBuffer,
-skinning:c.skinning,maxBones:s,useVertexTexture:b.floatVertexTextures&&l&&l.skeleton&&l.skeleton.useVertexTexture,morphTargets:c.morphTargets,morphNormals:c.morphNormals,maxMorphTargets:a.maxMorphTargets,maxMorphNormals:a.maxMorphNormals,maxDirLights:n,maxPointLights:p,maxSpotLights:m,maxHemiLights:q,maxShadows:e,pointLightShadows:k,shadowMapEnabled:a.shadowMap.enabled&&l.receiveShadow&&0<e,shadowMapType:a.shadowMap.type,shadowMapDebug:a.shadowMap.debug,alphaTest:c.alphaTest,metal:c.metal,doubleSided:c.side===
-THREE.DoubleSide,flipSided:c.side===THREE.BackSide}};this.getProgramCode=function(a,b){var c=[];b.shaderID?c.push(b.shaderID):(c.push(a.fragmentShader),c.push(a.vertexShader));if(void 0!==a.defines)for(var d in a.defines)c.push(d),c.push(a.defines[d]);for(d=0;d<e.length;d++){var k=e[d];c.push(k);c.push(b[k])}return c.join()};this.acquireProgram=function(b,d,e){for(var l,k=0,n=c.length;k<n;k++){var p=c[k];if(p.code===e){l=p;++l.usedTimes;break}}void 0===l&&(l=new THREE.WebGLProgram(a,e,b,d),c.push(l));
+function(c,e,h,l){var k,m,p,n,q,s=d[c.type];k=q=n=p=m=0;for(var t=e.length;k<t;k++){var v=e[k];!1!==v.visible&&(v instanceof THREE.DirectionalLight&&m++,v instanceof THREE.PointLight&&p++,v instanceof THREE.SpotLight&&n++,v instanceof THREE.HemisphereLight&&q++)}for(var v=k=t=0,u=e.length;v<u;v++){var w=e[v];w.castShadow&&((w instanceof THREE.SpotLight||w instanceof THREE.DirectionalLight)&&t++,w instanceof THREE.PointLight&&(t++,k++))}e=t;b.floatVertexTextures&&l&&l.skeleton&&l.skeleton.useVertexTexture?
+t=1024:(t=Math.floor((b.maxVertexUniforms-20)/4),void 0!==l&&l instanceof THREE.SkinnedMesh&&(t=Math.min(l.skeleton.bones.length,t),t<l.skeleton.bones.length&&console.warn("WebGLRenderer: too many bones - "+l.skeleton.bones.length+", this GPU supports just "+t+" (try OpenGL instead of ANGLE)")));v=a.getPrecision();null!==c.precision&&(v=b.getMaxPrecision(c.precision),v!==c.precision&&console.warn("THREE.WebGLRenderer.initMaterial:",c.precision,"not supported, using",v,"instead."));return{shaderID:s,
+precision:v,supportsVertexTextures:b.vertexTextures,map:!!c.map,envMap:!!c.envMap,envMapMode:c.envMap&&c.envMap.mapping,lightMap:!!c.lightMap,aoMap:!!c.aoMap,emissiveMap:!!c.emissiveMap,bumpMap:!!c.bumpMap,normalMap:!!c.normalMap,displacementMap:!!c.displacementMap,specularMap:!!c.specularMap,alphaMap:!!c.alphaMap,combine:c.combine,vertexColors:c.vertexColors,fog:h,useFog:c.fog,fogExp:h instanceof THREE.FogExp2,flatShading:c.shading===THREE.FlatShading,sizeAttenuation:c.sizeAttenuation,logarithmicDepthBuffer:b.logarithmicDepthBuffer,
+skinning:c.skinning,maxBones:t,useVertexTexture:b.floatVertexTextures&&l&&l.skeleton&&l.skeleton.useVertexTexture,morphTargets:c.morphTargets,morphNormals:c.morphNormals,maxMorphTargets:a.maxMorphTargets,maxMorphNormals:a.maxMorphNormals,maxDirLights:m,maxPointLights:p,maxSpotLights:n,maxHemiLights:q,maxShadows:e,pointLightShadows:k,shadowMapEnabled:a.shadowMap.enabled&&l.receiveShadow&&0<e,shadowMapType:a.shadowMap.type,shadowMapDebug:a.shadowMap.debug,alphaTest:c.alphaTest,metal:c.metal,doubleSided:c.side===
+THREE.DoubleSide,flipSided:c.side===THREE.BackSide}};this.getProgramCode=function(a,b){var c=[];b.shaderID?c.push(b.shaderID):(c.push(a.fragmentShader),c.push(a.vertexShader));if(void 0!==a.defines)for(var d in a.defines)c.push(d),c.push(a.defines[d]);for(d=0;d<e.length;d++){var k=e[d];c.push(k);c.push(b[k])}return c.join()};this.acquireProgram=function(b,d,e){for(var l,k=0,m=c.length;k<m;k++){var p=c[k];if(p.code===e){l=p;++l.usedTimes;break}}void 0===l&&(l=new THREE.WebGLProgram(a,e,b,d),c.push(l));
 return l};this.releaseProgram=function(a){if(0===--a.usedTimes){var b=c.indexOf(a);c[b]=c[c.length-1];c.pop();a.destroy()}};this.programs=c};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(){function a(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,c,d){var e=a.geometry,f=null,f=m,g=a.customDepthMaterial;c&&(f=q,g=a.customDistanceMaterial);g?f=g:(a=a instanceof THREE.SkinnedMesh&&b.skinning,g=0,void 0!==e.morphTargets&&0<e.morphTargets.length&&b.morphTargets&&(g|=1),a&&(g|=2),f=f[g]);f.visible=b.visible;f.wireframe=b.wireframe;f.wireframeLinewidth=b.wireframeLinewidth;c&&void 0!==f.uniforms.lightPos&&f.uniforms.lightPos.value.copy(d);return f}function e(a,b){if(!1!==a.visible){(a instanceof
-THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.Points)&&a.castShadow&&(!1===a.frustumCulled||!0===h.intersectsObject(a))&&!0===a.material.visible&&(a.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld),p.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,l=new THREE.Matrix4;new THREE.Vector3;new THREE.Vector3;for(var k=new THREE.Vector3,n=new THREE.Vector3,p=[],m=Array(4),q=Array(4),t=[new THREE.Vector3(1,0,0),new THREE.Vector3(-1,
-0,0),new THREE.Vector3(0,0,1),new THREE.Vector3(0,0,-1),new THREE.Vector3(0,1,0),new THREE.Vector3(0,-1,0)],s=[new THREE.Vector3(0,1,0),new THREE.Vector3(0,1,0),new THREE.Vector3(0,1,0),new THREE.Vector3(0,1,0),new THREE.Vector3(0,0,1),new THREE.Vector3(0,0,-1)],u=[new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4],x=new THREE.Vector4,v=THREE.ShaderLib.depthRGBA,D=THREE.UniformsUtils.clone(v.uniforms),w=THREE.ShaderLib.distanceRGBA,A=THREE.UniformsUtils.clone(w.uniforms),
-B=0;4!==B;++B){var z=0!==(B&1),y=0!==(B&2),L=new THREE.ShaderMaterial({uniforms:D,vertexShader:v.vertexShader,fragmentShader:v.fragmentShader,morphTargets:z,skinning:y});L._shadowPass=!0;m[B]=L;z=new THREE.ShaderMaterial({uniforms:A,vertexShader:w.vertexShader,fragmentShader:w.fragmentShader,morphTargets:z,skinning:y});z._shadowPass=!0;q[B]=z}var G=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=THREE.PCFShadowMap;this.cullFace=THREE.CullFaceFront;this.render=function(m){var q,
-v;if(!1!==G.enabled&&(!1!==G.autoUpdate||!1!==G.needsUpdate)){g.clearColor(1,1,1,1);f.disable(g.BLEND);f.enable(g.CULL_FACE);g.frontFace(g.CCW);g.cullFace(G.cullFace===THREE.CullFaceFront?g.FRONT:g.BACK);f.setDepthTest(!0);a.getViewport(x);for(var w=0,D=b.length;w<D;w++){var A=b[w];if(!1!==A.castShadow){var z=A.shadow,y=z.camera,B=z.mapSize;if(A instanceof THREE.PointLight){q=6;v=!0;var H=B.x/4,L=B.y/2;u[0].set(2*H,L,H,L);u[1].set(0,L,H,L);u[2].set(3*H,L,H,L);u[3].set(H,L,H,L);u[4].set(3*H,0,H,L);
-u[5].set(H,0,H,L)}else q=1,v=!1;null===z.map&&(H=THREE.LinearFilter,G.type===THREE.PCFSoftShadowMap&&(H=THREE.NearestFilter),z.map=new THREE.WebGLRenderTarget(B.x,B.y,{minFilter:H,magFilter:H,format:THREE.RGBAFormat}),z.matrix=new THREE.Matrix4,A instanceof THREE.SpotLight&&(y.aspect=B.x/B.y),y.updateProjectionMatrix());B=z.map;z=z.matrix;n.setFromMatrixPosition(A.matrixWorld);y.position.copy(n);a.setRenderTarget(B);a.clear();for(B=0;B<q;B++)for(v?(k.copy(y.position),k.add(t[B]),y.up.copy(s[B]),y.lookAt(k),
-H=u[B],a.setViewport(H.x,H.y,H.z,H.w)):(k.setFromMatrixPosition(A.target.matrixWorld),y.lookAt(k)),y.updateMatrixWorld(),y.matrixWorldInverse.getInverse(y.matrixWorld),z.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),z.multiply(y.projectionMatrix),z.multiply(y.matrixWorldInverse),l.multiplyMatrices(y.projectionMatrix,y.matrixWorldInverse),h.setFromMatrix(l),p.length=0,e(m,y),H=0,L=p.length;H<L;H++){var F=p[H],W=c.update(F),U=F.material;if(U instanceof THREE.MeshFaceMaterial)for(var Y=W.groups,U=U.materials,
-ea=0,fa=Y.length;ea<fa;ea++){var da=Y[ea],$=U[da.materialIndex];!0===$.visible&&($=d(F,$,v,n),a.renderBufferDirect(y,b,null,W,$,F,da))}else $=d(F,U,v,n),a.renderBufferDirect(y,b,null,W,$,F,null)}a.resetGLState()}}a.setViewport(x.x,x.y,x.z,x.w);m=a.getClearColor();q=a.getClearAlpha();a.setClearColor(m,q);f.enable(g.BLEND);G.cullFace===THREE.CullFaceFront&&g.cullFace(g.BACK);a.resetGLState();G.needsUpdate=!1}}};
-THREE.WebGLState=function(a,b,c){var d=this,e=new Uint8Array(16),g=new Uint8Array(16),f=new Uint8Array(16),h={},l=null,k=null,n=null,p=null,m=null,q=null,t=null,s=null,u=null,x=null,v=null,D=null,w=null,A=null,B=null,z=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS),y=void 0,L={};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);
+THREE.WebGLShadowMap=function(a,b,c){function d(a,b,c,d){var e=a.geometry,f=null,f=n,g=a.customDepthMaterial;c&&(f=q,g=a.customDistanceMaterial);g?f=g:(a=a instanceof THREE.SkinnedMesh&&b.skinning,g=0,void 0!==e.morphTargets&&0<e.morphTargets.length&&b.morphTargets&&(g|=1),a&&(g|=2),f=f[g]);f.visible=b.visible;f.wireframe=b.wireframe;f.wireframeLinewidth=b.wireframeLinewidth;c&&void 0!==f.uniforms.lightPos&&f.uniforms.lightPos.value.copy(d);return f}function e(a,b){if(!1!==a.visible){(a instanceof
+THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.Points)&&a.castShadow&&(!1===a.frustumCulled||!0===h.intersectsObject(a))&&!0===a.material.visible&&(a.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,a.matrixWorld),p.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,l=new THREE.Matrix4;new THREE.Vector3;new THREE.Vector3;for(var k=new THREE.Vector3,m=new THREE.Vector3,p=[],n=Array(4),q=Array(4),s=[new THREE.Vector3(1,0,0),new THREE.Vector3(-1,
+0,0),new THREE.Vector3(0,0,1),new THREE.Vector3(0,0,-1),new THREE.Vector3(0,1,0),new THREE.Vector3(0,-1,0)],t=[new THREE.Vector3(0,1,0),new THREE.Vector3(0,1,0),new THREE.Vector3(0,1,0),new THREE.Vector3(0,1,0),new THREE.Vector3(0,0,1),new THREE.Vector3(0,0,-1)],v=[new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4],u=new THREE.Vector4,w=THREE.ShaderLib.depthRGBA,D=THREE.UniformsUtils.clone(w.uniforms),x=THREE.ShaderLib.distanceRGBA,B=THREE.UniformsUtils.clone(x.uniforms),
+y=0;4!==y;++y){var z=0!==(y&1),A=0!==(y&2),J=new THREE.ShaderMaterial({uniforms:D,vertexShader:w.vertexShader,fragmentShader:w.fragmentShader,morphTargets:z,skinning:A});J._shadowPass=!0;n[y]=J;z=new THREE.ShaderMaterial({uniforms:B,vertexShader:x.vertexShader,fragmentShader:x.fragmentShader,morphTargets:z,skinning:A});z._shadowPass=!0;q[y]=z}var F=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=THREE.PCFShadowMap;this.cullFace=THREE.CullFaceFront;this.render=function(n){var q,
+w;if(!1!==F.enabled&&(!1!==F.autoUpdate||!1!==F.needsUpdate)){g.clearColor(1,1,1,1);f.disable(g.BLEND);f.enable(g.CULL_FACE);g.frontFace(g.CCW);g.cullFace(F.cullFace===THREE.CullFaceFront?g.FRONT:g.BACK);f.setDepthTest(!0);a.getViewport(u);for(var x=0,D=b.length;x<D;x++){var y=b[x];if(!0===y.castShadow){var z=y.shadow,B=z.camera,A=z.mapSize;if(y instanceof THREE.PointLight){q=6;w=!0;var H=A.x/4,J=A.y/2;v[0].set(2*H,J,H,J);v[1].set(0,J,H,J);v[2].set(3*H,J,H,J);v[3].set(H,J,H,J);v[4].set(3*H,0,H,J);
+v[5].set(H,0,H,J)}else q=1,w=!1;null===z.map&&(H=THREE.LinearFilter,F.type===THREE.PCFSoftShadowMap&&(H=THREE.NearestFilter),z.map=new THREE.WebGLRenderTarget(A.x,A.y,{minFilter:H,magFilter:H,format:THREE.RGBAFormat}),z.matrix=new THREE.Matrix4,y instanceof THREE.SpotLight&&(B.aspect=A.x/A.y),B.updateProjectionMatrix());A=z.map;z=z.matrix;m.setFromMatrixPosition(y.matrixWorld);B.position.copy(m);a.setRenderTarget(A);a.clear();for(A=0;A<q;A++)for(w?(k.copy(B.position),k.add(s[A]),B.up.copy(t[A]),B.lookAt(k),
+H=v[A],a.setViewport(H.x,H.y,H.z,H.w)):(k.setFromMatrixPosition(y.target.matrixWorld),B.lookAt(k)),B.updateMatrixWorld(),B.matrixWorldInverse.getInverse(B.matrixWorld),z.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),z.multiply(B.projectionMatrix),z.multiply(B.matrixWorldInverse),l.multiplyMatrices(B.projectionMatrix,B.matrixWorldInverse),h.setFromMatrix(l),p.length=0,e(n,B),H=0,J=p.length;H<J;H++){var G=p[H],ia=c.update(G),U=G.material;if(U instanceof THREE.MeshFaceMaterial)for(var X=ia.groups,U=U.materials,
+da=0,ca=X.length;da<ca;da++){var ga=X[da],Z=U[ga.materialIndex];!0===Z.visible&&(Z=d(G,Z,w,m),a.renderBufferDirect(B,b,null,ia,Z,G,ga))}else Z=d(G,U,w,m),a.renderBufferDirect(B,b,null,ia,Z,G,null)}a.resetGLState()}}a.setViewport(u.x,u.y,u.z,u.w);n=a.getClearColor();q=a.getClearAlpha();a.setClearColor(n,q);f.enable(g.BLEND);F.cullFace===THREE.CullFaceFront&&g.cullFace(g.BACK);a.resetGLState();F.needsUpdate=!1}}};
+THREE.WebGLState=function(a,b,c){var d=this,e=new Uint8Array(16),g=new Uint8Array(16),f=new Uint8Array(16),h={},l=null,k=null,m=null,p=null,n=null,q=null,s=null,t=null,v=null,u=null,w=null,D=null,x=null,B=null,y=null,z=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS),A=void 0,J={};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(c){e[c]=1;0===g[c]&&(a.enableVertexAttribArray(c),g[c]=1);0!==f[c]&&(b.get("ANGLE_instanced_arrays").vertexAttribDivisorANGLE(c,0),f[c]=0)};this.enableAttributeAndDivisor=function(b,c,d){e[b]=1;0===g[b]&&(a.enableVertexAttribArray(b),g[b]=1);f[b]!==c&&(d.vertexAttribDivisorANGLE(b,c),f[b]=c)};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!==h[b]&&(a.enable(b),h[b]=!0)};this.disable=function(b){!1!==h[b]&&(a.disable(b),h[b]=!1)};this.getCompressedTextureFormats=function(){if(null===l&&(l=[],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++)l.push(c[d]);return l};this.setBlending=function(b,d,e,f,g,h,l){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;l=l||f;if(d!==n||g!==q)a.blendEquationSeparate(c(d),c(g)),n=d,q=g;if(e!==p||f!==m||h!==t||l!==s)a.blendFuncSeparate(c(e),c(f),c(h),c(l)),p=e,m=f,t=h,s=l}else s=t=q=m=p=n=null};this.setDepthFunc=function(b){if(u!==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);u=b}};this.setDepthTest=function(b){b?this.enable(a.DEPTH_TEST):this.disable(a.DEPTH_TEST)};this.setDepthWrite=function(b){x!==b&&(a.depthMask(b),x=b)};this.setColorWrite=function(b){v!==b&&(a.colorMask(b,b,b,b),v=b)};this.setFlipSided=
-function(b){D!==b&&(b?a.frontFace(a.CW):a.frontFace(a.CCW),D=b)};this.setLineWidth=function(b){b!==w&&(a.lineWidth(b),w=b)};this.setPolygonOffset=function(b,c,d){b?this.enable(a.POLYGON_OFFSET_FILL):this.disable(a.POLYGON_OFFSET_FILL);!b||A===c&&B===d||(a.polygonOffset(c,d),A=c,B=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+z-1);y!==b&&(a.activeTexture(b),y=b)};this.bindTexture=function(b,c){void 0===
-y&&d.activeTexture();var e=L[y];void 0===e&&(e={type:void 0,texture:void 0},L[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);h={};D=v=x=k=l=null}};
-THREE.LensFlarePlugin=function(a,b){var c,d,e,g,f,h,l,k,n,p,m=a.context,q=a.state,t,s,u,x,v,D;this.render=function(w,A,B,z){if(0!==b.length){w=new THREE.Vector3;var y=z/B,L=.5*B,G=.5*z,C=16/z,N=new THREE.Vector2(C*y,C),M=new THREE.Vector3(1,1,0),O=new THREE.Vector2(1,1);if(void 0===u){var C=new Float32Array([-1,-1,0,0,1,-1,1,0,1,1,1,1,-1,1,0,1]),K=new Uint16Array([0,1,2,0,2,3]);t=m.createBuffer();s=m.createBuffer();m.bindBuffer(m.ARRAY_BUFFER,t);m.bufferData(m.ARRAY_BUFFER,C,m.STATIC_DRAW);m.bindBuffer(m.ELEMENT_ARRAY_BUFFER,
-s);m.bufferData(m.ELEMENT_ARRAY_BUFFER,K,m.STATIC_DRAW);v=m.createTexture();D=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,D);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=(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}",
+a.ONE,a.ONE_MINUS_SRC_ALPHA)),k=b);if(b===THREE.CustomBlending){g=g||d;h=h||e;l=l||f;if(d!==m||g!==q)a.blendEquationSeparate(c(d),c(g)),m=d,q=g;if(e!==p||f!==n||h!==s||l!==t)a.blendFuncSeparate(c(e),c(f),c(h),c(l)),p=e,n=f,s=h,t=l}else t=s=q=n=p=m=null};this.setDepthFunc=function(b){if(v!==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);v=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){w!==b&&(a.colorMask(b,b,b,b),w=b)};this.setFlipSided=
+function(b){D!==b&&(b?a.frontFace(a.CW):a.frontFace(a.CCW),D=b)};this.setLineWidth=function(b){b!==x&&(a.lineWidth(b),x=b)};this.setPolygonOffset=function(b,c,d){b?this.enable(a.POLYGON_OFFSET_FILL):this.disable(a.POLYGON_OFFSET_FILL);!b||B===c&&y===d||(a.polygonOffset(c,d),B=c,y=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+z-1);A!==b&&(a.activeTexture(b),A=b)};this.bindTexture=function(b,c){void 0===
+A&&d.activeTexture();var e=J[A];void 0===e&&(e={type:void 0,texture:void 0},J[A]=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);h={};D=w=u=k=l=null}};
+THREE.LensFlarePlugin=function(a,b){var c,d,e,g,f,h,l,k,m,p,n=a.context,q=a.state,s,t,v,u,w,D;this.render=function(x,B,y,z){if(0!==b.length){x=new THREE.Vector3;var A=z/y,J=.5*y,F=.5*z,C=16/z,N=new THREE.Vector2(C*A,C),L=new THREE.Vector3(1,1,0),Q=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]),M=new Uint16Array([0,1,2,0,2,3]);s=n.createBuffer();t=n.createBuffer();n.bindBuffer(n.ARRAY_BUFFER,s);n.bufferData(n.ARRAY_BUFFER,C,n.STATIC_DRAW);n.bindBuffer(n.ELEMENT_ARRAY_BUFFER,
+t);n.bufferData(n.ELEMENT_ARRAY_BUFFER,M,n.STATIC_DRAW);w=n.createTexture();D=n.createTexture();q.bindTexture(n.TEXTURE_2D,w);n.texImage2D(n.TEXTURE_2D,0,n.RGB,16,16,0,n.RGB,n.UNSIGNED_BYTE,null);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.NEAREST);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.NEAREST);q.bindTexture(n.TEXTURE_2D,D);n.texImage2D(n.TEXTURE_2D,0,
+n.RGBA,16,16,0,n.RGBA,n.UNSIGNED_BYTE,null);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.NEAREST);n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.NEAREST);var C=(u=0<n.getParameter(n.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}"},
-K=m.createProgram(),E=m.createShader(m.FRAGMENT_SHADER),J=m.createShader(m.VERTEX_SHADER),Q="precision "+a.getPrecision()+" float;\n";m.shaderSource(E,Q+C.fragmentShader);m.shaderSource(J,Q+C.vertexShader);m.compileShader(E);m.compileShader(J);m.attachShader(K,E);m.attachShader(K,J);m.linkProgram(K);u=K;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");l=m.getUniformLocation(u,"rotation");k=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,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,s);q.disable(m.CULL_FACE);m.depthMask(!1);K=0;for(E=
-b.length;K<E;K++)if(C=16/z,N.set(C*y,C),J=b[K],w.set(J.matrixWorld.elements[12],J.matrixWorld.elements[13],J.matrixWorld.elements[14]),w.applyMatrix4(A.matrixWorldInverse),w.applyProjection(A.projectionMatrix),M.copy(w),O.x=M.x*L+L,O.y=M.y*G+G,x||0<O.x&&O.x<B&&0<O.y&&O.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,O.x-8,O.y-8,16,16,0);m.uniform1i(c,0);m.uniform2f(h,N.x,N.y);m.uniform3f(k,
-M.x,M.y,M.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,D);m.copyTexImage2D(m.TEXTURE_2D,0,m.RGBA,O.x-8,O.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);J.positionScreen.copy(M);J.customUpdateCallback?J.customUpdateCallback(J):J.updateLensFlares();m.uniform1i(c,2);q.enable(m.BLEND);for(var Q=
-0,T=J.lensFlares.length;Q<T;Q++){var H=J.lensFlares[Q];.001<H.opacity&&.001<H.scale&&(M.x=H.x,M.y=H.y,M.z=H.z,C=H.size*H.scale/z,N.x=C*y,N.y=C,m.uniform3f(k,M.x,M.y,M.z),m.uniform2f(h,N.x,N.y),m.uniform1f(l,H.rotation),m.uniform1f(g,H.opacity),m.uniform3f(f,H.color.r,H.color.g,H.color.b),q.setBlending(H.blending,H.blendEquation,H.blendSrc,H.blendDst),a.setTexture(H.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,l,k,n,p,m,q,t,s,u,x,v;function D(a,b){return a.z!==b.z?b.z-a.z:b.id-a.id}var w=a.context,A=a.state,B,z,y,L,G=new THREE.Vector3,C=new THREE.Quaternion,N=new THREE.Vector3;this.render=function(M,O){if(0!==b.length){if(void 0===y){var K=new Float32Array([-.5,-.5,0,0,.5,-.5,1,0,.5,.5,1,1,-.5,.5,0,1]),E=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,K,w.STATIC_DRAW);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,
-z);w.bufferData(w.ELEMENT_ARRAY_BUFFER,E,w.STATIC_DRAW);var K=w.createProgram(),E=w.createShader(w.VERTEX_SHADER),J=w.createShader(w.FRAGMENT_SHADER);w.shaderSource(E,["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(J,["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(E);w.compileShader(J);w.attachShader(K,E);w.attachShader(K,J);w.linkProgram(K);y=K;x=w.getAttribLocation(y,"position");v=w.getAttribLocation(y,"uv");c=w.getUniformLocation(y,"uvOffset");d=w.getUniformLocation(y,"uvScale");e=w.getUniformLocation(y,"rotation");g=w.getUniformLocation(y,"scale");f=w.getUniformLocation(y,"color");h=w.getUniformLocation(y,"map");l=w.getUniformLocation(y,"opacity");k=w.getUniformLocation(y,"modelViewMatrix");n=w.getUniformLocation(y,"projectionMatrix");p=
-w.getUniformLocation(y,"fogType");m=w.getUniformLocation(y,"fogDensity");q=w.getUniformLocation(y,"fogNear");t=w.getUniformLocation(y,"fogFar");s=w.getUniformLocation(y,"fogColor");u=w.getUniformLocation(y,"alphaTest");K=document.createElement("canvas");K.width=8;K.height=8;E=K.getContext("2d");E.fillStyle="white";E.fillRect(0,0,8,8);L=new THREE.Texture(K);L.needsUpdate=!0}w.useProgram(y);A.initAttributes();A.enableAttribute(x);A.enableAttribute(v);A.disableUnusedAttributes();A.disable(w.CULL_FACE);
-A.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,O.projectionMatrix.elements);A.activeTexture(w.TEXTURE0);w.uniform1i(h,0);E=K=0;(J=M.fog)?(w.uniform3f(s,J.color.r,J.color.g,J.color.b),J instanceof THREE.Fog?(w.uniform1f(q,J.near),w.uniform1f(t,J.far),w.uniform1i(p,1),E=K=1):J instanceof THREE.FogExp2&&(w.uniform1f(m,J.density),w.uniform1i(p,2),E=K=2)):
-(w.uniform1i(p,0),E=K=0);for(var J=0,Q=b.length;J<Q;J++){var T=b[J];T.modelViewMatrix.multiplyMatrices(O.matrixWorldInverse,T.matrixWorld);T.z=-T.modelViewMatrix.elements[14]}b.sort(D);for(var H=[],J=0,Q=b.length;J<Q;J++){var T=b[J],R=T.material;w.uniform1f(u,R.alphaTest);w.uniformMatrix4fv(k,!1,T.modelViewMatrix.elements);T.matrixWorld.decompose(G,C,N);H[0]=N.x;H[1]=N.y;T=0;M.fog&&R.fog&&(T=E);K!==T&&(w.uniform1i(p,T),K=T);null!==R.map?(w.uniform2f(c,R.map.offset.x,R.map.offset.y),w.uniform2f(d,
-R.map.repeat.x,R.map.repeat.y)):(w.uniform2f(c,0,0),w.uniform2f(d,1,1));w.uniform1f(l,R.opacity);w.uniform3f(f,R.color.r,R.color.g,R.color.b);w.uniform1f(e,R.rotation);w.uniform2fv(g,H);A.setBlending(R.blending,R.blendEquation,R.blendSrc,R.blendDst);A.setDepthTest(R.depthTest);A.setDepthWrite(R.depthWrite);R.map&&R.map.image&&R.map.image.width?a.setTexture(R.map,0):a.setTexture(L,0);w.drawElements(w.TRIANGLES,6,w.UNSIGNED_SHORT,0)}A.enable(w.CULL_FACE);a.resetGLState()}}};
+M=n.createProgram(),K=n.createShader(n.FRAGMENT_SHADER),E=n.createShader(n.VERTEX_SHADER),O="precision "+a.getPrecision()+" float;\n";n.shaderSource(K,O+C.fragmentShader);n.shaderSource(E,O+C.vertexShader);n.compileShader(K);n.compileShader(E);n.attachShader(M,K);n.attachShader(M,E);n.linkProgram(M);v=M;m=n.getAttribLocation(v,"position");p=n.getAttribLocation(v,"uv");c=n.getUniformLocation(v,"renderType");d=n.getUniformLocation(v,"map");e=n.getUniformLocation(v,"occlusionMap");g=n.getUniformLocation(v,
+"opacity");f=n.getUniformLocation(v,"color");h=n.getUniformLocation(v,"scale");l=n.getUniformLocation(v,"rotation");k=n.getUniformLocation(v,"screenPosition")}n.useProgram(v);q.initAttributes();q.enableAttribute(m);q.enableAttribute(p);q.disableUnusedAttributes();n.uniform1i(e,0);n.uniform1i(d,1);n.bindBuffer(n.ARRAY_BUFFER,s);n.vertexAttribPointer(m,2,n.FLOAT,!1,16,0);n.vertexAttribPointer(p,2,n.FLOAT,!1,16,8);n.bindBuffer(n.ELEMENT_ARRAY_BUFFER,t);q.disable(n.CULL_FACE);n.depthMask(!1);M=0;for(K=
+b.length;M<K;M++)if(C=16/z,N.set(C*A,C),E=b[M],x.set(E.matrixWorld.elements[12],E.matrixWorld.elements[13],E.matrixWorld.elements[14]),x.applyMatrix4(B.matrixWorldInverse),x.applyProjection(B.projectionMatrix),L.copy(x),Q.x=L.x*J+J,Q.y=L.y*F+F,u||0<Q.x&&Q.x<y&&0<Q.y&&Q.y<z){q.activeTexture(n.TEXTURE0);q.bindTexture(n.TEXTURE_2D,null);q.activeTexture(n.TEXTURE1);q.bindTexture(n.TEXTURE_2D,w);n.copyTexImage2D(n.TEXTURE_2D,0,n.RGB,Q.x-8,Q.y-8,16,16,0);n.uniform1i(c,0);n.uniform2f(h,N.x,N.y);n.uniform3f(k,
+L.x,L.y,L.z);q.disable(n.BLEND);q.enable(n.DEPTH_TEST);n.drawElements(n.TRIANGLES,6,n.UNSIGNED_SHORT,0);q.activeTexture(n.TEXTURE0);q.bindTexture(n.TEXTURE_2D,D);n.copyTexImage2D(n.TEXTURE_2D,0,n.RGBA,Q.x-8,Q.y-8,16,16,0);n.uniform1i(c,1);q.disable(n.DEPTH_TEST);q.activeTexture(n.TEXTURE1);q.bindTexture(n.TEXTURE_2D,w);n.drawElements(n.TRIANGLES,6,n.UNSIGNED_SHORT,0);E.positionScreen.copy(L);E.customUpdateCallback?E.customUpdateCallback(E):E.updateLensFlares();n.uniform1i(c,2);q.enable(n.BLEND);for(var O=
+0,T=E.lensFlares.length;O<T;O++){var H=E.lensFlares[O];.001<H.opacity&&.001<H.scale&&(L.x=H.x,L.y=H.y,L.z=H.z,C=H.size*H.scale/z,N.x=C*A,N.y=C,n.uniform3f(k,L.x,L.y,L.z),n.uniform2f(h,N.x,N.y),n.uniform1f(l,H.rotation),n.uniform1f(g,H.opacity),n.uniform3f(f,H.color.r,H.color.g,H.color.b),q.setBlending(H.blending,H.blendEquation,H.blendSrc,H.blendDst),a.setTexture(H.texture,1),n.drawElements(n.TRIANGLES,6,n.UNSIGNED_SHORT,0))}}q.enable(n.CULL_FACE);q.enable(n.DEPTH_TEST);n.depthMask(!0);a.resetGLState()}}};
+THREE.SpritePlugin=function(a,b){var c,d,e,g,f,h,l,k,m,p,n,q,s,t,v,u,w;function D(a,b){return a.z!==b.z?b.z-a.z:b.id-a.id}var x=a.context,B=a.state,y,z,A,J,F=new THREE.Vector3,C=new THREE.Quaternion,N=new THREE.Vector3;this.render=function(L,Q){if(0!==b.length){if(void 0===A){var M=new Float32Array([-.5,-.5,0,0,.5,-.5,1,0,.5,.5,1,1,-.5,.5,0,1]),K=new Uint16Array([0,1,2,0,2,3]);y=x.createBuffer();z=x.createBuffer();x.bindBuffer(x.ARRAY_BUFFER,y);x.bufferData(x.ARRAY_BUFFER,M,x.STATIC_DRAW);x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,
+z);x.bufferData(x.ELEMENT_ARRAY_BUFFER,K,x.STATIC_DRAW);var M=x.createProgram(),K=x.createShader(x.VERTEX_SHADER),E=x.createShader(x.FRAGMENT_SHADER);x.shaderSource(K,["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(E,["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(K);x.compileShader(E);x.attachShader(M,K);x.attachShader(M,E);x.linkProgram(M);A=M;u=x.getAttribLocation(A,"position");w=x.getAttribLocation(A,"uv");c=x.getUniformLocation(A,"uvOffset");d=x.getUniformLocation(A,"uvScale");e=x.getUniformLocation(A,"rotation");g=x.getUniformLocation(A,"scale");f=x.getUniformLocation(A,"color");h=x.getUniformLocation(A,"map");l=x.getUniformLocation(A,"opacity");k=x.getUniformLocation(A,"modelViewMatrix");m=x.getUniformLocation(A,"projectionMatrix");p=
+x.getUniformLocation(A,"fogType");n=x.getUniformLocation(A,"fogDensity");q=x.getUniformLocation(A,"fogNear");s=x.getUniformLocation(A,"fogFar");t=x.getUniformLocation(A,"fogColor");v=x.getUniformLocation(A,"alphaTest");M=document.createElement("canvas");M.width=8;M.height=8;K=M.getContext("2d");K.fillStyle="white";K.fillRect(0,0,8,8);J=new THREE.Texture(M);J.needsUpdate=!0}x.useProgram(A);B.initAttributes();B.enableAttribute(u);B.enableAttribute(w);B.disableUnusedAttributes();B.disable(x.CULL_FACE);
+B.enable(x.BLEND);x.bindBuffer(x.ARRAY_BUFFER,y);x.vertexAttribPointer(u,2,x.FLOAT,!1,16,0);x.vertexAttribPointer(w,2,x.FLOAT,!1,16,8);x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,z);x.uniformMatrix4fv(m,!1,Q.projectionMatrix.elements);B.activeTexture(x.TEXTURE0);x.uniform1i(h,0);K=M=0;(E=L.fog)?(x.uniform3f(t,E.color.r,E.color.g,E.color.b),E instanceof THREE.Fog?(x.uniform1f(q,E.near),x.uniform1f(s,E.far),x.uniform1i(p,1),K=M=1):E instanceof THREE.FogExp2&&(x.uniform1f(n,E.density),x.uniform1i(p,2),K=M=2)):
+(x.uniform1i(p,0),K=M=0);for(var E=0,O=b.length;E<O;E++){var T=b[E];T.modelViewMatrix.multiplyMatrices(Q.matrixWorldInverse,T.matrixWorld);T.z=-T.modelViewMatrix.elements[14]}b.sort(D);for(var H=[],E=0,O=b.length;E<O;E++){var T=b[E],R=T.material;x.uniform1f(v,R.alphaTest);x.uniformMatrix4fv(k,!1,T.modelViewMatrix.elements);T.matrixWorld.decompose(F,C,N);H[0]=N.x;H[1]=N.y;T=0;L.fog&&R.fog&&(T=K);M!==T&&(x.uniform1i(p,T),M=T);null!==R.map?(x.uniform2f(c,R.map.offset.x,R.map.offset.y),x.uniform2f(d,
+R.map.repeat.x,R.map.repeat.y)):(x.uniform2f(c,0,0),x.uniform2f(d,1,1));x.uniform1f(l,R.opacity);x.uniform3f(f,R.color.r,R.color.g,R.color.b);x.uniform1f(e,R.rotation);x.uniform2fv(g,H);B.setBlending(R.blending,R.blendEquation,R.blendSrc,R.blendDst);B.setDepthTest(R.depthTest);B.setDepthWrite(R.depthWrite);R.map&&R.map.image&&R.map.image.width?a.setTexture(R.map,0):a.setTexture(J,0);x.drawElements(x.TRIANGLES,6,x.UNSIGNED_SHORT,0)}B.enable(x.CULL_FACE);a.resetGLState()}}};
+THREE.CurveUtils={tangentQuadraticBezier:function(a,b,c,d){return 2*(1-a)*(c-b)+2*a*(d-c)},tangentCubicBezier:function(a,b,c,d,e){return-3*b*(1-a)*(1-a)+3*c*(1-a)*(1-a)-6*a*c*(1-a)+6*a*d*(1-a)-3*a*a*d+3*a*a*e},tangentSpline:function(a,b,c,d,e){return 6*a*a-6*a+(3*a*a-4*a+1)+(-6*a*a+6*a)+(3*a*a-2*a)},interpolate:function(a,b,c,d,e){a=.5*(c-a);d=.5*(d-b);var g=e*e;return(2*b-2*c+a+d)*e*g+(-3*b+3*c-2*a-d)*g+a*e+b}};
 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){function e(b){g.load(a[b],function(a){f.images[b]=a;h+=1;6===h&&(f.needsUpdate=!0,c&&c(f))},void 0,d)}var g=new THREE.ImageLoader;g.crossOrigin=this.crossOrigin;var f=new THREE.CubeTexture([],b),h=
-0;b=0;for(var l=a.length;b<l;++b)e(b);return f},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){function c(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,l=f.createImageData(d,e),k=l.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,s=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+t)]/255*b]);u.push([-1,-1,h[4*(m*d+t)]/255*b]);u.push([0,-1,h[4*(m*d+n)]/255*b]);u.push([1,-1,h[4*(m*d+s)]/255*b]);u.push([1,0,h[4*(p*d+s)]/255*b]);u.push([1,1,h[4*(q*d+s)]/255*b]);u.push([0,1,h[4*(q*d+n)]/255*
-b]);u.push([-1,1,h[4*(q*d+t)]/255*b]);m=[];t=u.length;for(q=0;q<t;q++){var s=u[q],v=u[(q+1)%t],s=[s[0]-x[0],s[1]-x[1],s[2]-x[2]],v=[v[0]-x[0],v[1]-x[1],v[2]-x[2]];m.push(c([s[1]*v[2]-s[2]*v[1],s[2]*v[0]-s[0]*v[2],s[0]*v[1]-s[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);k[x]=(u[0]+1)/2*255|0;k[x+1]=(u[1]+1)/2*255|0;k[x+2]=255*u[2]|0;k[x+3]=255}f.putImageData(l,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.ImageUtils={crossOrigin:void 0,loadTexture:function(a,b,c,d){console.warn("THREE.ImageUtils.loadTexture is being deprecated. Use THREE.TextureLoader() instead.");var e=new THREE.TextureLoader;e.setCrossOrigin(this.crossOrigin);a=e.load(a,c,void 0,d);b&&(a.mapping=b);return a},loadTextureCube:function(a,b,c,d){console.warn("THREE.ImageUtils.loadTextureCube is being deprecated. Use THREE.CubeTextureLoader() instead.");var e=new THREE.CubeTextureLoader;e.setCrossOrigin(this.crossOrigin);a=e.load(a,
+c,void 0,d);b&&(a.mapping=b);return a},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.")}};
 THREE.SceneUtils={createMultiMaterialObject:function(a,b){for(var c=new THREE.Group,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,l,k,n,p,m,q,t,s,u,x=b.glyphs[a]||b.glyphs["?"];if(x){if(x.o)for(b=x._cachedOutline||(x._cachedOutline=x.o.split(" ")),k=b.length,a=0;a<k;)switch(l=b[a++],l){case "m":l=b[a++]*c+d;n=b[a++]*c;e.moveTo(l,n);
-break;case "l":l=b[a++]*c+d;n=b[a++]*c;e.lineTo(l,n);break;case "q":l=b[a++]*c+d;n=b[a++]*c;q=b[a++]*c+d;t=b[a++]*c;e.quadraticCurveTo(q,t,l,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,l);THREE.Shape.Utils.b2(v,m,t,n)}break;case "b":if(l=b[a++]*c+d,n=b[a++]*c,q=b[a++]*c+d,t=b[a++]*c,s=b[a++]*c+d,u=b[a++]*c,e.bezierCurveTo(q,t,s,u,l,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,s,l),THREE.Shape.Utils.b3(v,
-m,t,u,n)}return{offset:x.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){function b(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=[],l,k,n;if(0<b(a))for(k=0;k<e;k++)f[k]=k;else for(k=0;k<e;k++)f[k]=e-1-k;var p=2*e;for(k=e-1;2<e;){if(0>=p--){console.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}l=k;e<=l&&(l=0);k=l+1;e<=k&&(k=0);n=k+1;e<=n&&(n=0);var m;a:{var q=m=void 0,t=void 0,s=void 0,u=
-void 0,x=void 0,v=void 0,D=void 0,w=void 0,q=a[f[l]].x,t=a[f[l]].y,s=a[f[k]].x,u=a[f[k]].y,x=a[f[n]].x,v=a[f[n]].y;if(1E-10>(s-q)*(v-t)-(u-t)*(x-q))m=!1;else{var A=void 0,B=void 0,z=void 0,y=void 0,L=void 0,G=void 0,C=void 0,N=void 0,M=void 0,O=void 0,M=N=C=w=D=void 0,A=x-s,B=v-u,z=q-x,y=t-v,L=s-q,G=u-t;for(m=0;m<e;m++)if(D=a[f[m]].x,w=a[f[m]].y,!(D===q&&w===t||D===s&&w===u||D===x&&w===v)&&(C=D-q,N=w-t,M=D-s,O=w-u,D-=x,w-=v,M=A*O-B*M,C=L*N-G*C,N=z*w-y*D,-1E-10<=M&&-1E-10<=N&&-1E-10<=C)){m=!1;break a}m=
-!0}}if(m){g.push([a[f[l]],a[f[k]],a[f[n]]]);h.push([f[l],f[k],f[n]]);l=k;for(n=k+1;n<e;l++,n++)f[l]=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.ShapeUtils={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;e<b;d=e++)c+=a[d].x*a[e].y-a[e].x*a[d].y;return.5*c},triangulate:function(){return function(a,b){var c=a.length;if(3>c)return null;var d=[],e=[],g=[],f,h,l;if(0<THREE.ShapeUtils.area(a))for(h=0;h<c;h++)e[h]=h;else for(h=0;h<c;h++)e[h]=c-1-h;var k=2*c;for(h=c-1;2<c;){if(0>=k--){console.warn("THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()");break}f=h;c<=f&&(f=0);h=f+1;c<=h&&(h=0);l=h+1;c<=l&&(l=0);var m;a:{var p=
+m=void 0,n=void 0,q=void 0,s=void 0,t=void 0,v=void 0,u=void 0,w=void 0,p=a[e[f]].x,n=a[e[f]].y,q=a[e[h]].x,s=a[e[h]].y,t=a[e[l]].x,v=a[e[l]].y;if(Number.EPSILON>(q-p)*(v-n)-(s-n)*(t-p))m=!1;else{var D=void 0,x=void 0,B=void 0,y=void 0,z=void 0,A=void 0,J=void 0,F=void 0,C=void 0,N=void 0,C=F=J=w=u=void 0,D=t-q,x=v-s,B=p-t,y=n-v,z=q-p,A=s-n;for(m=0;m<c;m++)if(u=a[e[m]].x,w=a[e[m]].y,!(u===p&&w===n||u===q&&w===s||u===t&&w===v)&&(J=u-p,F=w-n,C=u-q,N=w-s,u-=t,w-=v,C=D*N-x*C,J=z*F-A*J,F=B*w-y*u,C>=-Number.EPSILON&&
+F>=-Number.EPSILON&&J>=-Number.EPSILON)){m=!1;break a}m=!0}}if(m){d.push([a[e[f]],a[e[h]],a[e[l]]]);g.push([e[f],e[h],e[l]]);f=h;for(l=h+1;l<c;f++,l++)e[f]=e[l];c--;k=2*c}}return b?g:d}}(),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,m=a.x-d.x,p=a.y-d.y,z=h*k-g*l,A=h*m-g*p;if(Math.abs(z)>Number.EPSILON){if(0<z){if(0>A||A>
+z)return[];k=l*m-k*p;if(0>k||k>z)return[]}else{if(0<A||A<z)return[];k=l*m-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*m!==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?[]: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 Math.abs(a)>Number.EPSILON?(b=g*c-d*b,0<a?0<=e&&0<=b:0<=e||0<=b):0<e}var g,f,h,l,k,m={};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++)k=h[g].x+":"+h[g].y,void 0!==m[k]&&console.warn("THREE.Shape: Duplicate point",k),m[k]=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=[],m,p,y,z,A,J=[],F,C,N,L=0;for(m=b.length;L<m;L++)l.push(L);F=0;for(var Q=2*l.length;0<l.length;){Q--;if(0>Q){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(p=F;p<h.length;p++){y=h[p];m=-1;for(L=0;L<l.length;L++)if(z=l[L],A=y.x+":"+y.y+":"+z,void 0===J[A]){k=b[z];for(C=0;C<k.length;C++)if(z=k[C],c(p,C)&&!f(y,z)&&!g(y,z)){m=C;l.splice(L,1);
+F=h.slice(0,p+1);z=h.slice(p);C=k.slice(m);N=k.slice(0,m+1);h=F.concat(C).concat(N).concat(z);F=p;break}if(0<=m)break;J[A]=!0}if(0<=m)break}}return h}(a,b);var p=THREE.ShapeUtils.triangulate(g,!1);g=0;for(f=p.length;g<f;g++)for(l=p[g],h=0;3>h;h++)k=l[h].x+":"+l[h].y,k=m[k],void 0!==k&&(l[h]=k);return p.concat()},isClockWise:function(a){return 0>THREE.ShapeUtils.area(a)},b2:function(){return function(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}}(),b3:function(){return function(a,b,c,d,e){var g=
+1-a,f=1-a;return g*g*g*b+3*f*f*a*c+3*(1-a)*a*a*d+a*a*a*e}}()};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};
 THREE.Audio.prototype.play=function(){if(!0===this.isPlaying)console.warn("THREE.Audio: Audio is already playing.");else{var a=this.context.createBufferSource();a.buffer=this.source.buffer;a.loop=this.source.loop;a.onended=this.source.onended;a.start(0,this.startTime);a.playbackRate.value=this.playbackRate;this.isPlaying=!0;this.source=a;this.connect()}};THREE.Audio.prototype.pause=function(){this.source.stop();this.startTime=this.context.currentTime};
 THREE.Audio.prototype.stop=function(){this.source.stop();this.startTime=0};THREE.Audio.prototype.connect=function(){void 0!==this.filter?(this.source.connect(this.filter),this.filter.connect(this.panner)):this.source.connect(this.panner)};THREE.Audio.prototype.disconnect=function(){void 0!==this.filter?(this.source.disconnect(this.filter),this.filter.disconnect(this.panner)):this.source.disconnect(this.panner)};
@@ -713,116 +714,101 @@ THREE.AudioListener.prototype=Object.create(THREE.Object3D.prototype);THREE.Audi
 THREE.AudioListener.prototype.updateMatrixWorld=function(){var a=new THREE.Vector3,b=new THREE.Quaternion,c=new THREE.Vector3,d=new THREE.Vector3;return function(e){THREE.Object3D.prototype.updateMatrixWorld.call(this,e);e=this.context.listener;var g=this.up;this.matrixWorld.decompose(a,b,c);d.set(0,0,-1).applyQuaternion(b);e.setPosition(a.x,a.y,a.z);e.setOrientation(d.x,d.y,d.z,g.x,g.y,g.z)}}();THREE.Curve=function(){};
 THREE.Curve.prototype={constructor:THREE.Curve,getPoint:function(a){console.warn("THREE.Curve: Warning, getPoint() not implemented!");return null},getPointAt:function(a){a=this.getUtoTmapping(a);return this.getPoint(a)},getPoints:function(a){a||(a=5);var b,c=[];for(b=0;b<=a;b++)c.push(this.getPoint(b/a));return c},getSpacedPoints:function(a){a||(a=5);var b,c=[];for(b=0;b<=a;b++)c.push(this.getPointAt(b/a));return c},getLength:function(){var a=this.getLengths();return a[a.length-1]},getLengths:function(a){a||
 (a=this.__arcLengthDivisions?this.__arcLengthDivisions:200);if(this.cacheArcLengths&&this.cacheArcLengths.length===a+1&&!this.needsUpdate)return this.cacheArcLengths;this.needsUpdate=!1;var b=[],c,d=this.getPoint(0),e,g=0;b.push(0);for(e=1;e<=a;e++)c=this.getPoint(e/a),g+=c.distanceTo(d),b.push(g),d=c;return this.cacheArcLengths=b},updateArcLengths:function(){this.needsUpdate=!0;this.getLengths()},getUtoTmapping:function(a,b){var c=this.getLengths(),d=0,e=c.length,g;g=b?b:a*c[e-1];for(var f=0,h=e-
-1,l;f<=h;)if(d=Math.floor(f+(h-f)/2),l=c[d]-g,0>l)f=d+1;else if(0<l)h=d-1;else{h=d;break}d=h;if(c[d]===g)return d/(e-1);f=c[d];return c=(d+(g-f)/(c[d+1]-f))/(e-1)},getTangent:function(a){var b=a-1E-4;a+=1E-4;0>b&&(b=0);1<a&&(a=1);b=this.getPoint(b);return this.getPoint(a).clone().sub(b).normalize()},getTangentAt:function(a){a=this.getUtoTmapping(a);return this.getTangent(a)}};
-THREE.Curve.Utils={tangentQuadraticBezier:function(a,b,c,d){return 2*(1-a)*(c-b)+2*a*(d-c)},tangentCubicBezier:function(a,b,c,d,e){return-3*b*(1-a)*(1-a)+3*c*(1-a)*(1-a)-6*a*c*(1-a)+6*a*d*(1-a)-3*a*a*d+3*a*a*e},tangentSpline:function(a,b,c,d,e){return 6*a*a-6*a+(3*a*a-4*a+1)+(-6*a*a+6*a)+(3*a*a-2*a)},interpolate:function(a,b,c,d,e){a=.5*(c-a);d=.5*(d-b);var g=e*e;return(2*b-2*c+a+d)*e*g+(-3*b+3*c-2*a-d)*g+a*e+b}};
-THREE.Curve.create=function(a,b){a.prototype=Object.create(THREE.Curve.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};THREE.CurvePath=function(){this.curves=[];this.bends=[];this.autoClose=!1};THREE.CurvePath.prototype=Object.create(THREE.Curve.prototype);THREE.CurvePath.prototype.constructor=THREE.CurvePath;THREE.CurvePath.prototype.add=function(a){this.curves.push(a)};
+1,l;f<=h;)if(d=Math.floor(f+(h-f)/2),l=c[d]-g,0>l)f=d+1;else if(0<l)h=d-1;else{h=d;break}d=h;if(c[d]===g)return d/(e-1);f=c[d];return c=(d+(g-f)/(c[d+1]-f))/(e-1)},getTangent:function(a){var b=a-1E-4;a+=1E-4;0>b&&(b=0);1<a&&(a=1);b=this.getPoint(b);return this.getPoint(a).clone().sub(b).normalize()},getTangentAt:function(a){a=this.getUtoTmapping(a);return this.getTangent(a)}};THREE.Curve.Utils=THREE.CurveUtils;
+THREE.Curve.create=function(a,b){a.prototype=Object.create(THREE.Curve.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};THREE.CurvePath=function(){this.curves=[];this.autoClose=!1};THREE.CurvePath.prototype=Object.create(THREE.Curve.prototype);THREE.CurvePath.prototype.constructor=THREE.CurvePath;THREE.CurvePath.prototype.add=function(a){this.curves.push(a)};
 THREE.CurvePath.prototype.closePath=function(){var a=this.curves[0].getPoint(0),b=this.curves[this.curves.length-1].getPoint(1);a.equals(b)||this.curves.push(new THREE.LineCurve(b,a))};THREE.CurvePath.prototype.getPoint=function(a){for(var b=a*this.getLength(),c=this.getCurveLengths(),d=0;d<c.length;){if(c[d]>=b)return a=this.curves[d],b=1-(c[d]-b)/a.getLength(),a.getPointAt(b);d++}return null};THREE.CurvePath.prototype.getLength=function(){var a=this.getCurveLengths();return a[a.length-1]};
-THREE.CurvePath.prototype.getCurveLengths=function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[],b=0,c=0,d=this.curves.length;c<d;c++)b+=this.curves[c].getLength(),a.push(b);return this.cacheLengths=a};
-THREE.CurvePath.prototype.getBoundingBox=function(){var a=this.getPoints(),b,c,d,e,g,f;b=c=Number.NEGATIVE_INFINITY;e=g=Number.POSITIVE_INFINITY;for(var h=a[0]instanceof THREE.Vector3,l=h?new THREE.Vector3:new THREE.Vector2,k=0,n=a.length;k<n;k++){var p=a[k];p.x>b?b=p.x:p.x<e&&(e=p.x);p.y>c?c=p.y:p.y<g&&(g=p.y);h&&(p.z>d?d=p.z:p.z<f&&(f=p.z));l.add(p)}a={minX:e,minY:g,maxX:b,maxY:c};h&&(a.maxZ=d,a.minZ=f);return a};
-THREE.CurvePath.prototype.createPointsGeometry=function(a){a=this.getPoints(a,!0);return this.createGeometry(a)};THREE.CurvePath.prototype.createSpacedPointsGeometry=function(a){a=this.getSpacedPoints(a,!0);return this.createGeometry(a)};THREE.CurvePath.prototype.createGeometry=function(a){for(var b=new THREE.Geometry,c=0,d=a.length;c<d;c++){var e=a[c];b.vertices.push(new THREE.Vector3(e.x,e.y,e.z||0))}return b};THREE.CurvePath.prototype.addWrapPath=function(a){this.bends.push(a)};
-THREE.CurvePath.prototype.getTransformedPoints=function(a,b){var c=this.getPoints(a);b||(b=this.bends);for(var d=0,e=b.length;d<e;d++)c=this.getWrapPoints(c,b[d]);return c};THREE.CurvePath.prototype.getTransformedSpacedPoints=function(a,b){var c=this.getSpacedPoints(a);b||(b=this.bends);for(var d=0,e=b.length;d<e;d++)c=this.getWrapPoints(c,b[d]);return c};
-THREE.CurvePath.prototype.getWrapPoints=function(a,b){for(var c=this.getBoundingBox(),d=0,e=a.length;d<e;d++){var g=a[d],f=g.x,h=g.y,l=f/c.maxX,l=b.getUtoTmapping(l,f),f=b.getPoint(l),l=b.getTangent(l);l.set(-l.y,l.x).multiplyScalar(h);g.x=f.x+l.x;g.y=f.y+l.y}return a};THREE.Path=function(a){THREE.CurvePath.call(this);this.actions=[];a&&this.fromPoints(a)};THREE.Path.prototype=Object.create(THREE.CurvePath.prototype);THREE.Path.prototype.constructor=THREE.Path;
-THREE.PathActions={MOVE_TO:"moveTo",LINE_TO:"lineTo",QUADRATIC_CURVE_TO:"quadraticCurveTo",BEZIER_CURVE_TO:"bezierCurveTo",CSPLINE_THRU:"splineThru",ARC:"arc",ELLIPSE:"ellipse"};THREE.Path.prototype.fromPoints=function(a){this.moveTo(a[0].x,a[0].y);for(var b=1,c=a.length;b<c;b++)this.lineTo(a[b].x,a[b].y)};THREE.Path.prototype.moveTo=function(a,b){var c=Array.prototype.slice.call(arguments);this.actions.push({action:THREE.PathActions.MOVE_TO,args:c})};
-THREE.Path.prototype.lineTo=function(a,b){var c=Array.prototype.slice.call(arguments),d=this.actions[this.actions.length-1].args,d=new THREE.LineCurve(new THREE.Vector2(d[d.length-2],d[d.length-1]),new THREE.Vector2(a,b));this.curves.push(d);this.actions.push({action:THREE.PathActions.LINE_TO,args:c})};
-THREE.Path.prototype.quadraticCurveTo=function(a,b,c,d){var e=Array.prototype.slice.call(arguments),g=this.actions[this.actions.length-1].args,g=new THREE.QuadraticBezierCurve(new THREE.Vector2(g[g.length-2],g[g.length-1]),new THREE.Vector2(a,b),new THREE.Vector2(c,d));this.curves.push(g);this.actions.push({action:THREE.PathActions.QUADRATIC_CURVE_TO,args:e})};
-THREE.Path.prototype.bezierCurveTo=function(a,b,c,d,e,g){var f=Array.prototype.slice.call(arguments),h=this.actions[this.actions.length-1].args,h=new THREE.CubicBezierCurve(new THREE.Vector2(h[h.length-2],h[h.length-1]),new THREE.Vector2(a,b),new THREE.Vector2(c,d),new THREE.Vector2(e,g));this.curves.push(h);this.actions.push({action:THREE.PathActions.BEZIER_CURVE_TO,args:f})};
-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 l=this.actions[this.actions.length-1].args;this.absellipse(a+l[l.length-2],b+l[l.length-1],c,d,e,g,f,h)};THREE.Path.prototype.absellipse=function(a,b,c,d,e,g,f,h){var l=[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);l.push(a.x);l.push(a.y);this.actions.push({action:THREE.PathActions.ELLIPSE,args:l})};
+THREE.CurvePath.prototype.getCurveLengths=function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[],b=0,c=0,d=this.curves.length;c<d;c++)b+=this.curves[c].getLength(),a.push(b);return this.cacheLengths=a};THREE.CurvePath.prototype.createPointsGeometry=function(a){a=this.getPoints(a,!0);return this.createGeometry(a)};THREE.CurvePath.prototype.createSpacedPointsGeometry=function(a){a=this.getSpacedPoints(a,!0);return this.createGeometry(a)};
+THREE.CurvePath.prototype.createGeometry=function(a){for(var b=new THREE.Geometry,c=0,d=a.length;c<d;c++){var e=a[c];b.vertices.push(new THREE.Vector3(e.x,e.y,e.z||0))}return b};THREE.Path=function(a){THREE.CurvePath.call(this);this.actions=[];a&&this.fromPoints(a)};THREE.Path.prototype=Object.create(THREE.CurvePath.prototype);THREE.Path.prototype.constructor=THREE.Path;THREE.Path.prototype.fromPoints=function(a){this.moveTo(a[0].x,a[0].y);for(var b=1,c=a.length;b<c;b++)this.lineTo(a[b].x,a[b].y)};
+THREE.Path.prototype.moveTo=function(a,b){this.actions.push({action:"moveTo",args:[a,b]})};THREE.Path.prototype.lineTo=function(a,b){var c=this.actions[this.actions.length-1].args,c=new THREE.LineCurve(new THREE.Vector2(c[c.length-2],c[c.length-1]),new THREE.Vector2(a,b));this.curves.push(c);this.actions.push({action:"lineTo",args:[a,b]})};
+THREE.Path.prototype.quadraticCurveTo=function(a,b,c,d){var e=this.actions[this.actions.length-1].args,e=new THREE.QuadraticBezierCurve(new THREE.Vector2(e[e.length-2],e[e.length-1]),new THREE.Vector2(a,b),new THREE.Vector2(c,d));this.curves.push(e);this.actions.push({action:"quadraticCurveTo",args:[a,b,c,d]})};
+THREE.Path.prototype.bezierCurveTo=function(a,b,c,d,e,g){var f=this.actions[this.actions.length-1].args,f=new THREE.CubicBezierCurve(new THREE.Vector2(f[f.length-2],f[f.length-1]),new THREE.Vector2(a,b),new THREE.Vector2(c,d),new THREE.Vector2(e,g));this.curves.push(f);this.actions.push({action:"bezierCurveTo",args:[a,b,c,d,e,g]})};
+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:"splineThru",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 l=this.actions[this.actions.length-1].args;this.absellipse(a+l[l.length-2],b+l[l.length-1],c,d,e,g,f,h)};THREE.Path.prototype.absellipse=function(a,b,c,d,e,g,f,h){var l=[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);l.push(a.x);l.push(a.y);this.actions.push({action:"ellipse",args:l})};
 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;for(var c=[],d,e,g,f,h,l,k,n,p,m,q=0,t=this.actions.length;q<t;q++){p=this.actions[q];var s=p.args;switch(p.action){case THREE.PathActions.MOVE_TO:c.push(new THREE.Vector2(s[0],s[1]));break;case THREE.PathActions.LINE_TO:c.push(new THREE.Vector2(s[0],s[1]));break;case THREE.PathActions.QUADRATIC_CURVE_TO:d=s[2];e=s[3];h=s[0];l=s[1];0<c.length?(p=c[c.length-1],k=p.x,n=p.y):(p=this.actions[q-
-1].args,k=p[p.length-2],n=p[p.length-1]);for(s=1;s<=a;s++)m=s/a,p=THREE.Shape.Utils.b2(m,k,h,d),m=THREE.Shape.Utils.b2(m,n,l,e),c.push(new THREE.Vector2(p,m));break;case THREE.PathActions.BEZIER_CURVE_TO:d=s[4];e=s[5];h=s[0];l=s[1];g=s[2];f=s[3];0<c.length?(p=c[c.length-1],k=p.x,n=p.y):(p=this.actions[q-1].args,k=p[p.length-2],n=p[p.length-1]);for(s=1;s<=a;s++)m=s/a,p=THREE.Shape.Utils.b3(m,k,h,g,d),m=THREE.Shape.Utils.b3(m,n,l,f,e),c.push(new THREE.Vector2(p,m));break;case THREE.PathActions.CSPLINE_THRU:p=
-this.actions[q-1].args;m=[new THREE.Vector2(p[p.length-2],p[p.length-1])];p=a*s[0].length;m=m.concat(s[0]);m=new THREE.SplineCurve(m);for(s=1;s<=p;s++)c.push(m.getPointAt(s/p));break;case THREE.PathActions.ARC:d=s[0];e=s[1];l=s[2];g=s[3];p=s[4];h=!!s[5];k=p-g;n=2*a;for(s=1;s<=n;s++)m=s/n,h||(m=1-m),m=g+m*k,p=d+l*Math.cos(m),m=e+l*Math.sin(m),c.push(new THREE.Vector2(p,m));break;case THREE.PathActions.ELLIPSE:d=s[0];e=s[1];l=s[2];f=s[3];g=s[4];p=s[5];h=!!s[6];var u=s[7];k=p-g;n=2*a;var x,v;0!==u&&
-(x=Math.cos(u),v=Math.sin(u));for(s=1;s<=n;s++){m=s/n;h||(m=1-m);m=g+m*k;p=d+l*Math.cos(m);m=e+f*Math.sin(m);if(0!==u){var D=p;p=(D-d)*x-(m-e)*v+d;m=(D-d)*v+(m-e)*x+e}c.push(new THREE.Vector2(p,m))}}}q=c[c.length-1];1E-10>Math.abs(q.x-c[0].x)&&1E-10>Math.abs(q.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){for(var b=[],c=new THREE.Path,d=0,e=a.length;d<e;d++){var f=a[d],g=f.args,f=f.action;f===THREE.PathActions.MOVE_TO&&0!==c.actions.length&&(b.push(c),c=new THREE.Path);c[f].apply(c,g)}0!==c.actions.length&&b.push(c);return b}(this.actions);if(0===e.length)return[];if(!0===b)return c(e);var g,f,h,l=[];if(1===e.length)return f=e[0],h=new THREE.Shape,h.actions=f.actions,h.curves=f.curves,l.push(h),l;var k=!THREE.Shape.Utils.isClockWise(e[0].getPoints()),k=
-a?!k:k;h=[];var n=[],p=[],m=0,q;n[m]=void 0;p[m]=[];for(var t=0,s=e.length;t<s;t++)f=e[t],q=f.getPoints(),g=THREE.Shape.Utils.isClockWise(q),(g=a?!g:g)?(!k&&n[m]&&m++,n[m]={s:new THREE.Shape,p:q},n[m].s.actions=f.actions,n[m].s.curves=f.curves,k&&m++,p[m]=[]):p[m].push({h:f,p:q[0]});if(!n[0])return c(e);if(1<n.length){t=!1;f=[];e=0;for(g=n.length;e<g;e++)h[e]=[];e=0;for(g=n.length;e<g;e++)for(k=p[e],m=0;m<k.length;m++){q=k[m];for(var s=!0,u=0;u<n.length;u++)d(q.p,n[u].p)&&(e!==u&&f.push({froms:e,
-tos:u,hole:m}),s?(s=!1,h[u].push(q)):t=!0);s&&h[e].push(q)}0<f.length&&(t||(p=h))}t=0;for(e=n.length;t<e;t++)for(h=n[t].s,l.push(h),f=p[t],g=0,k=f.length;g<k;g++)h.holes.push(f[g].h);return l};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){for(var b=[],c=0,d=this.holes.length;c<d;c++)b[c]=this.holes[c].getTransformedPoints(a,this.bends);return b};THREE.Shape.prototype.getSpacedPointsHoles=function(a){for(var b=[],c=0,d=this.holes.length;c<d;c++)b[c]=this.holes[c].getTransformedSpacedPoints(a,this.bends);return b};
-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,y=h*n-g*p;if(1E-10<Math.abs(z)){if(0<z){if(0>y||y>z)return[];k=l*n-k*p;if(0>k||k>z)return[]}else{if(0<y||y<z)return[];k=l*n-k*p;if(0<k||k<z)return[]}if(0===k)return!f||0!==y&&y!==z?[a]:[];if(k===z)return!f||0!==y&&y!==z?[b]:[];if(0===
-y)return[d];if(y===z)return[e];f=k/z;return[{x:a.x+f*g,y:a.y+f*h}]}if(0!==y||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?[]:
-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,l,k,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++)k=h[g].x+":"+h[g].y,void 0!==n[k]&&console.warn("THREE.Shape: Duplicate point",k),n[k]=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,y,L=[],G,C,N,M=0;for(n=b.length;M<n;M++)l.push(M);G=0;for(var O=2*
-l.length;0<l.length;){O--;if(0>O){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(p=G;p<h.length;p++){B=h[p];n=-1;for(M=0;M<l.length;M++)if(z=l[M],y=B.x+":"+B.y+":"+z,void 0===L[y]){k=b[z];for(C=0;C<k.length;C++)if(z=k[C],c(p,C)&&!f(B,z)&&!g(B,z)){n=C;l.splice(M,1);G=h.slice(0,p+1);z=h.slice(p);C=k.slice(n);N=k.slice(0,n+1);h=G.concat(C).concat(N).concat(z);G=p;break}if(0<=n)break;L[y]=!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(l=p[g],h=0;3>h;h++)k=l[h].x+":"+l[h].y,k=n[k],void 0!==k&&(l[h]=k);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;
-THREE.QuadraticBezierCurve.prototype.getPoint=function(a){var b=new THREE.Vector2;b.x=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);return b};THREE.QuadraticBezierCurve.prototype.getTangent=function(a){var b=new THREE.Vector2;b.x=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Curve.Utils.tangentQuadraticBezier(a,this.v0.y,this.v1.y,this.v2.y);return b.normalize()};
-THREE.CubicBezierCurve=function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d};THREE.CubicBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.CubicBezierCurve.prototype.constructor=THREE.CubicBezierCurve;THREE.CubicBezierCurve.prototype.getPoint=function(a){var b;b=THREE.Shape.Utils.b3(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);a=THREE.Shape.Utils.b3(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);return new THREE.Vector2(b,a)};
-THREE.CubicBezierCurve.prototype.getTangent=function(a){var b;b=THREE.Curve.Utils.tangentCubicBezier(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);a=THREE.Curve.Utils.tangentCubicBezier(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);b=new THREE.Vector2(b,a);b.normalize();return b};THREE.SplineCurve=function(a){this.points=void 0==a?[]:a};THREE.SplineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.SplineCurve.prototype.constructor=THREE.SplineCurve;
-THREE.SplineCurve.prototype.getPoint=function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0===c?c:c-1],e=b[c],g=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=new THREE.Vector2;c.x=THREE.Curve.Utils.interpolate(d.x,e.x,g.x,b.x,a);c.y=THREE.Curve.Utils.interpolate(d.y,e.y,g.y,b.y,a);return c};
-THREE.EllipseCurve=function(a,b,c,d,e,g,f,h){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=g;this.aClockwise=f;this.aRotation=h||0};THREE.EllipseCurve.prototype=Object.create(THREE.Curve.prototype);THREE.EllipseCurve.prototype.constructor=THREE.EllipseCurve;
+THREE.Path.prototype.getPoints=function(a,b){a=a||12;for(var c=THREE.ShapeUtils.b2,d=THREE.ShapeUtils.b3,e=[],g,f,h,l,k,m,p,n,q,s,t=0,v=this.actions.length;t<v;t++){q=this.actions[t];var u=q.args;switch(q.action){case "moveTo":e.push(new THREE.Vector2(u[0],u[1]));break;case "lineTo":e.push(new THREE.Vector2(u[0],u[1]));break;case "quadraticCurveTo":g=u[2];f=u[3];k=u[0];m=u[1];0<e.length?(q=e[e.length-1],p=q.x,n=q.y):(q=this.actions[t-1].args,p=q[q.length-2],n=q[q.length-1]);for(u=1;u<=a;u++)s=u/a,
+q=c(s,p,k,g),s=c(s,n,m,f),e.push(new THREE.Vector2(q,s));break;case "bezierCurveTo":g=u[4];f=u[5];k=u[0];m=u[1];h=u[2];l=u[3];0<e.length?(q=e[e.length-1],p=q.x,n=q.y):(q=this.actions[t-1].args,p=q[q.length-2],n=q[q.length-1]);for(u=1;u<=a;u++)s=u/a,q=d(s,p,k,h,g),s=d(s,n,m,l,f),e.push(new THREE.Vector2(q,s));break;case "splineThru":q=this.actions[t-1].args;s=[new THREE.Vector2(q[q.length-2],q[q.length-1])];q=a*u[0].length;s=s.concat(u[0]);s=new THREE.SplineCurve(s);for(u=1;u<=q;u++)e.push(s.getPointAt(u/
+q));break;case "arc":g=u[0];f=u[1];m=u[2];h=u[3];q=u[4];k=!!u[5];p=q-h;n=2*a;for(u=1;u<=n;u++)s=u/n,k||(s=1-s),s=h+s*p,q=g+m*Math.cos(s),s=f+m*Math.sin(s),e.push(new THREE.Vector2(q,s));break;case "ellipse":g=u[0];f=u[1];m=u[2];l=u[3];h=u[4];q=u[5];k=!!u[6];var w=u[7];p=q-h;n=2*a;var D,x;0!==w&&(D=Math.cos(w),x=Math.sin(w));for(u=1;u<=n;u++){s=u/n;k||(s=1-s);s=h+s*p;q=g+m*Math.cos(s);s=f+l*Math.sin(s);if(0!==w){var B=q;q=(B-g)*D-(s-f)*x+g;s=(B-g)*x+(s-f)*D+f}e.push(new THREE.Vector2(q,s))}}}c=e[e.length-
+1];Math.abs(c.x-e[0].x)<Number.EPSILON&&Math.abs(c.y-e[0].y)<Number.EPSILON&&e.splice(e.length-1,1);b&&e.push(e[0]);return e};
+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(Math.abs(l)>Number.EPSILON){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=THREE.ShapeUtils.isClockWise,g=function(a){for(var b=[],c=new THREE.Path,d=0,e=a.length;d<e;d++){var f=a[d],g=f.args,f=f.action;"moveTo"===f&&0!==c.actions.length&&(b.push(c),c=new THREE.Path);c[f].apply(c,g)}0!==c.actions.length&&b.push(c);return b}(this.actions);if(0===g.length)return[];if(!0===b)return c(g);var f,h,l,k=[];if(1===g.length)return h=g[0],l=new THREE.Shape,l.actions=h.actions,l.curves=h.curves,k.push(l),k;var m=!e(g[0].getPoints()),m=a?!m:
+m;l=[];var p=[],n=[],q=0,s;p[q]=void 0;n[q]=[];for(var t=0,v=g.length;t<v;t++)h=g[t],s=h.getPoints(),f=e(s),(f=a?!f:f)?(!m&&p[q]&&q++,p[q]={s:new THREE.Shape,p:s},p[q].s.actions=h.actions,p[q].s.curves=h.curves,m&&q++,n[q]=[]):n[q].push({h:h,p:s[0]});if(!p[0])return c(g);if(1<p.length){t=!1;h=[];e=0;for(g=p.length;e<g;e++)l[e]=[];e=0;for(g=p.length;e<g;e++)for(f=n[e],m=0;m<f.length;m++){q=f[m];s=!0;for(v=0;v<p.length;v++)d(q.p,p[v].p)&&(e!==v&&h.push({froms:e,tos:v,hole:m}),s?(s=!1,l[v].push(q)):
+t=!0);s&&l[e].push(q)}0<h.length&&(t||(n=l))}t=0;for(e=p.length;t<e;t++)for(l=p[t].s,k.push(l),h=n[t],g=0,f=h.length;g<f;g++)l.holes.push(h[g].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){for(var b=[],c=0,d=this.holes.length;c<d;c++)b[c]=this.holes[c].getPoints(a);return b};THREE.Shape.prototype.extractAllPoints=function(a){return{shape:this.getPoints(a),holes:this.getPointsHoles(a)}};THREE.Shape.prototype.extractPoints=function(a){return this.extractAllPoints(a)};THREE.Shape.Utils=THREE.ShapeUtils;THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);
+THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)};THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()};THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);
+THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve;THREE.QuadraticBezierCurve.prototype.getPoint=function(a){var b=THREE.ShapeUtils.b2;return new THREE.Vector2(b(a,this.v0.x,this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y))};THREE.QuadraticBezierCurve.prototype.getTangent=function(a){var b=THREE.CurveUtils.tangentQuadraticBezier;return(new THREE.Vector2(b(a,this.v0.x,this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y))).normalize()};
+THREE.CubicBezierCurve=function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d};THREE.CubicBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.CubicBezierCurve.prototype.constructor=THREE.CubicBezierCurve;THREE.CubicBezierCurve.prototype.getPoint=function(a){var b=THREE.ShapeUtils.b3;return new THREE.Vector2(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y))};
+THREE.CubicBezierCurve.prototype.getTangent=function(a){var b=THREE.CurveUtils.tangentCubicBezier;return(new THREE.Vector2(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y))).normalize()};THREE.SplineCurve=function(a){this.points=void 0==a?[]:a};THREE.SplineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.SplineCurve.prototype.constructor=THREE.SplineCurve;
+THREE.SplineCurve.prototype.getPoint=function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0===c?c:c-1],e=b[c],g=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=THREE.CurveUtils.interpolate;return new THREE.Vector2(c(d.x,e.x,g.x,b.x,a),c(d.y,e.y,g.y,b.y,a))};THREE.EllipseCurve=function(a,b,c,d,e,g,f,h){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=g;this.aClockwise=f;this.aRotation=h||0};THREE.EllipseCurve.prototype=Object.create(THREE.Curve.prototype);
+THREE.EllipseCurve.prototype.constructor=THREE.EllipseCurve;
 THREE.EllipseCurve.prototype.getPoint=function(a){var b=this.aEndAngle-this.aStartAngle;0>b&&(b+=2*Math.PI);b>2*Math.PI&&(b-=2*Math.PI);b=!0===this.aClockwise?this.aEndAngle+(1-a)*(2*Math.PI-b):this.aStartAngle+a*b;a=this.aX+this.xRadius*Math.cos(b);var c=this.aY+this.yRadius*Math.sin(b);if(0!==this.aRotation){var b=Math.cos(this.aRotation),d=Math.sin(this.aRotation),e=a;a=(e-this.aX)*b-(c-this.aY)*d+this.aX;c=(e-this.aX)*d+(c-this.aY)*b+this.aY}return new THREE.Vector2(a,c)};
 THREE.ArcCurve=function(a,b,c,d,e,g){THREE.EllipseCurve.call(this,a,b,c,c,d,e,g)};THREE.ArcCurve.prototype=Object.create(THREE.EllipseCurve.prototype);THREE.ArcCurve.prototype.constructor=THREE.ArcCurve;THREE.LineCurve3=THREE.Curve.create(function(a,b){this.v1=a;this.v2=b},function(a){var b=new THREE.Vector3;b.subVectors(this.v2,this.v1);b.multiplyScalar(a);b.add(this.v1);return b});
-THREE.QuadraticBezierCurve3=THREE.Curve.create(function(a,b,c){this.v0=a;this.v1=b;this.v2=c},function(a){var b=new THREE.Vector3;b.x=THREE.Shape.Utils.b2(a,this.v0.x,this.v1.x,this.v2.x);b.y=THREE.Shape.Utils.b2(a,this.v0.y,this.v1.y,this.v2.y);b.z=THREE.Shape.Utils.b2(a,this.v0.z,this.v1.z,this.v2.z);return b});
-THREE.CubicBezierCurve3=THREE.Curve.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b=new THREE.Vector3;b.x=THREE.Shape.Utils.b3(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x);b.y=THREE.Shape.Utils.b3(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y);b.z=THREE.Shape.Utils.b3(a,this.v0.z,this.v1.z,this.v2.z,this.v3.z);return b});
-THREE.SplineCurve3=THREE.Curve.create(function(a){console.warn("THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3");this.points=void 0==a?[]:a},function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0==c?c:c-1],e=b[c],g=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=new THREE.Vector3;c.x=THREE.Curve.Utils.interpolate(d.x,e.x,g.x,b.x,a);c.y=THREE.Curve.Utils.interpolate(d.y,e.y,g.y,b.y,a);c.z=THREE.Curve.Utils.interpolate(d.z,e.z,g.z,
-b.z,a);return c});
-THREE.CatmullRomCurve3=function(){function a(){}var b=new THREE.Vector3,c=new a,d=new a,e=new a;a.prototype.init=function(a,b,c,d){this.c0=a;this.c1=c;this.c2=-3*a+3*b-2*c-d;this.c3=2*a-2*b+c+d};a.prototype.initNonuniformCatmullRom=function(a,b,c,d,e,n,p){a=((b-a)/e-(c-a)/(e+n)+(c-b)/n)*n;d=((c-b)/n-(d-b)/(n+p)+(d-c)/p)*n;this.init(b,c,a,d)};a.prototype.initCatmullRom=function(a,b,c,d,e){this.init(b,c,e*(c-a),e*(d-b))};a.prototype.calc=function(a){var b=a*a;return this.c0+this.c1*a+this.c2*b+this.c3*
-b*a};return THREE.Curve.create(function(a){this.points=a||[]},function(a){var f=this.points,h,l;l=f.length;2>l&&console.log("duh, you need at least 2 points");a*=l-1;h=Math.floor(a);a-=h;0===a&&h===l-1&&(h=l-2,a=1);var k,n,p;0===h?(b.subVectors(f[0],f[1]).add(f[0]),k=b):k=f[h-1];n=f[h];p=f[h+1];h+2<l?f=f[h+2]:(b.subVectors(f[l-1],f[l-2]).add(f[l-2]),f=b);if(void 0===this.type||"centripetal"===this.type||"chordal"===this.type){var m="chordal"===this.type?.5:.25;l=Math.pow(k.distanceToSquared(n),m);
-h=Math.pow(n.distanceToSquared(p),m);m=Math.pow(p.distanceToSquared(f),m);1E-4>h&&(h=1);1E-4>l&&(l=h);1E-4>m&&(m=h);c.initNonuniformCatmullRom(k.x,n.x,p.x,f.x,l,h,m);d.initNonuniformCatmullRom(k.y,n.y,p.y,f.y,l,h,m);e.initNonuniformCatmullRom(k.z,n.z,p.z,f.z,l,h,m)}else"catmullrom"===this.type&&(l=void 0!==this.tension?this.tension:.5,c.initCatmullRom(k.x,n.x,p.x,f.x,l),d.initCatmullRom(k.y,n.y,p.y,f.y,l),e.initCatmullRom(k.z,n.z,p.z,f.z,l));return new THREE.Vector3(c.calc(a),d.calc(a),e.calc(a))})}();
-THREE.ClosedSplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[]:a},function(a){var b=this.points;a*=b.length-0;var c=Math.floor(a);a-=c;var c=c+(0<c?0:(Math.floor(Math.abs(c)/b.length)+1)*b.length),d=b[(c-1)%b.length],e=b[c%b.length],g=b[(c+1)%b.length],b=b[(c+2)%b.length],c=new THREE.Vector3;c.x=THREE.Curve.Utils.interpolate(d.x,e.x,g.x,b.x,a);c.y=THREE.Curve.Utils.interpolate(d.y,e.y,g.y,b.y,a);c.z=THREE.Curve.Utils.interpolate(d.z,e.z,g.z,b.z,a);return c});
-THREE.BoxGeometry=function(a,b,c,d,e,g){function f(a,b,c,d,e,f,g,s){var u,x=h.widthSegments,v=h.heightSegments,D=e/2,w=f/2,A=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,y=e/x,L=f/v,G=new THREE.Vector3;G[u]=0<g?1:-1;for(e=0;e<z;e++)for(f=0;f<B;f++){var C=new THREE.Vector3;C[a]=(f*y-D)*c;C[b]=(e*L-w)*d;C[u]=g;h.vertices.push(C)}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),D=new THREE.Vector2((f+1)/x,1-e/v),w=new THREE.Face3(w+A,a+A,c+A),w.normal.copy(G),w.vertexNormals.push(G.clone(),G.clone(),G.clone()),w.materialIndex=s,h.faces.push(w),h.faceVertexUvs[0].push([d,g,D]),w=new THREE.Face3(a+A,b+A,c+A),w.normal.copy(G),w.vertexNormals.push(G.clone(),G.clone(),G.clone()),w.materialIndex=s,h.faces.push(w),
-h.faceVertexUvs[0].push([g.clone(),u,D.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.QuadraticBezierCurve3=THREE.Curve.create(function(a,b,c){this.v0=a;this.v1=b;this.v2=c},function(a){var b=THREE.ShapeUtils.b2;return new THREE.Vector3(b(a,this.v0.x,this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y),b(a,this.v0.z,this.v1.z,this.v2.z))});
+THREE.CubicBezierCurve3=THREE.Curve.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b=THREE.ShapeUtils.b3;return new THREE.Vector3(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y),b(a,this.v0.z,this.v1.z,this.v2.z,this.v3.z))});
+THREE.SplineCurve3=THREE.Curve.create(function(a){console.warn("THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3");this.points=void 0==a?[]:a},function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0==c?c:c-1],e=b[c],g=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=THREE.CurveUtils.interpolate;return new THREE.Vector3(c(d.x,e.x,g.x,b.x,a),c(d.y,e.y,g.y,b.y,a),c(d.z,e.z,g.z,b.z,a))});
+THREE.CatmullRomCurve3=function(){function a(){}var b=new THREE.Vector3,c=new a,d=new a,e=new a;a.prototype.init=function(a,b,c,d){this.c0=a;this.c1=c;this.c2=-3*a+3*b-2*c-d;this.c3=2*a-2*b+c+d};a.prototype.initNonuniformCatmullRom=function(a,b,c,d,e,m,p){a=((b-a)/e-(c-a)/(e+m)+(c-b)/m)*m;d=((c-b)/m-(d-b)/(m+p)+(d-c)/p)*m;this.init(b,c,a,d)};a.prototype.initCatmullRom=function(a,b,c,d,e){this.init(b,c,e*(c-a),e*(d-b))};a.prototype.calc=function(a){var b=a*a;return this.c0+this.c1*a+this.c2*b+this.c3*
+b*a};return THREE.Curve.create(function(a){this.points=a||[]},function(a){var f=this.points,h,l;l=f.length;2>l&&console.log("duh, you need at least 2 points");a*=l-1;h=Math.floor(a);a-=h;0===a&&h===l-1&&(h=l-2,a=1);var k,m,p;0===h?(b.subVectors(f[0],f[1]).add(f[0]),k=b):k=f[h-1];m=f[h];p=f[h+1];h+2<l?f=f[h+2]:(b.subVectors(f[l-1],f[l-2]).add(f[l-2]),f=b);if(void 0===this.type||"centripetal"===this.type||"chordal"===this.type){var n="chordal"===this.type?.5:.25;l=Math.pow(k.distanceToSquared(m),n);
+h=Math.pow(m.distanceToSquared(p),n);n=Math.pow(p.distanceToSquared(f),n);1E-4>h&&(h=1);1E-4>l&&(l=h);1E-4>n&&(n=h);c.initNonuniformCatmullRom(k.x,m.x,p.x,f.x,l,h,n);d.initNonuniformCatmullRom(k.y,m.y,p.y,f.y,l,h,n);e.initNonuniformCatmullRom(k.z,m.z,p.z,f.z,l,h,n)}else"catmullrom"===this.type&&(l=void 0!==this.tension?this.tension:.5,c.initCatmullRom(k.x,m.x,p.x,f.x,l),d.initCatmullRom(k.y,m.y,p.y,f.y,l),e.initCatmullRom(k.z,m.z,p.z,f.z,l));return new THREE.Vector3(c.calc(a),d.calc(a),e.calc(a))})}();
+THREE.ClosedSplineCurve3=THREE.Curve.create(function(a){this.points=void 0==a?[]:a},function(a){var b=this.points;a*=b.length-0;var c=Math.floor(a);a-=c;var c=c+(0<c?0:(Math.floor(Math.abs(c)/b.length)+1)*b.length),d=b[(c-1)%b.length],e=b[c%b.length],g=b[(c+1)%b.length],b=b[(c+2)%b.length],c=THREE.CurveUtils.interpolate;return new THREE.Vector3(c(d.x,e.x,g.x,b.x,a),c(d.y,e.y,g.y,b.y,a),c(d.z,e.z,g.z,b.z,a))});
+THREE.BoxGeometry=function(a,b,c,d,e,g){function f(a,b,c,d,e,f,g,t){var v,u=h.widthSegments,w=h.heightSegments,D=e/2,x=f/2,B=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",w=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)v="x",u=h.depthSegments;var y=u+1,z=w+1,A=e/u,J=f/w,F=new THREE.Vector3;F[v]=0<g?1:-1;for(e=0;e<z;e++)for(f=0;f<y;f++){var C=new THREE.Vector3;C[a]=(f*A-D)*c;C[b]=(e*J-x)*d;C[v]=g;h.vertices.push(C)}for(e=
+0;e<w;e++)for(f=0;f<u;f++)x=f+y*e,a=f+y*(e+1),b=f+1+y*(e+1),c=f+1+y*e,d=new THREE.Vector2(f/u,1-e/w),g=new THREE.Vector2(f/u,1-(e+1)/w),v=new THREE.Vector2((f+1)/u,1-(e+1)/w),D=new THREE.Vector2((f+1)/u,1-e/w),x=new THREE.Face3(x+B,a+B,c+B),x.normal.copy(F),x.vertexNormals.push(F.clone(),F.clone(),F.clone()),x.materialIndex=t,h.faces.push(x),h.faceVertexUvs[0].push([d,g,D]),x=new THREE.Face3(a+B,b+B,c+B),x.normal.copy(F),x.vertexNormals.push(F.clone(),F.clone(),F.clone()),x.materialIndex=t,h.faces.push(x),
+h.faceVertexUvs[0].push([g.clone(),v,D.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(){var a=this.parameters;return new THREE.BoxGeometry(a.width,a.height,a.depth,a.widthSegments,a.heightSegments,a.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};this.fromBufferGeometry(new THREE.CircleBufferGeometry(a,b,c,d))};
 THREE.CircleGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.CircleGeometry.prototype.constructor=THREE.CircleGeometry;THREE.CircleGeometry.prototype.clone=function(){var a=this.parameters;return new THREE.CircleGeometry(a.radius,a.segments,a.thetaStart,a.thetaLength)};
-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[2]=1;e[0]=.5;e[1]=.5;for(var h=0,l=3,k=2;h<=b;h++,l+=3,k+=2){var n=c+h/b*d;g[l]=a*Math.cos(n);g[l+1]=a*Math.sin(n);f[l+2]=1;e[k]=(g[l]/a+1)/2;e[k+1]=(g[l+1]/a+1)/2}c=
+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[2]=1;e[0]=.5;e[1]=.5;for(var h=0,l=3,k=2;h<=b;h++,l+=3,k+=2){var m=c+h/b*d;g[l]=a*Math.cos(m);g[l+1]=a*Math.sin(m);f[l+2]=1;e[k]=(g[l]/a+1)/2;e[k+1]=(g[l+1]/a+1)/2}c=
 [];for(l=1;l<=b;l++)c.push(l,l+1,0);this.setIndex(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=this.parameters;return new THREE.CircleBufferGeometry(a.radius,a.segments,a.thetaStart,a.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 l=c/2,k,n,p=[],m=[];for(n=0;n<=e;n++){var q=[],t=[],s=n/e,u=s*(b-a)+a;for(k=0;k<=d;k++){var x=k/d,v=new THREE.Vector3;v.x=u*Math.sin(x*h+
-f);v.y=-s*c+l;v.z=u*Math.cos(x*h+f);this.vertices.push(v);q.push(this.vertices.length-1);t.push(new THREE.Vector2(x,1-s))}p.push(q);m.push(t)}c=(b-a)/c;for(k=0;k<d;k++)for(0!==a?(f=this.vertices[p[0][k]].clone(),h=this.vertices[p[0][k+1]].clone()):(f=this.vertices[p[1][k]].clone(),h=this.vertices[p[1][k+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][k],t=p[n+1][k],s=p[n+1][k+1],u=p[n][k+1],x=f.clone(),v=f.clone(),
-D=h.clone(),w=h.clone(),A=m[n][k].clone(),B=m[n+1][k].clone(),z=m[n+1][k+1].clone(),y=m[n][k+1].clone();this.faces.push(new THREE.Face3(q,t,u,[x,v,w]));this.faceVertexUvs[0].push([A,B,y]);this.faces.push(new THREE.Face3(t,s,u,[v.clone(),D,w.clone()]));this.faceVertexUvs[0].push([B.clone(),z,y.clone()])}if(!1===g&&0<a)for(this.vertices.push(new THREE.Vector3(0,l,0)),k=0;k<d;k++)q=p[0][k],t=p[0][k+1],s=this.vertices.length-1,x=new THREE.Vector3(0,1,0),v=new THREE.Vector3(0,1,0),D=new THREE.Vector3(0,
-1,0),A=m[0][k].clone(),B=m[0][k+1].clone(),z=new THREE.Vector2(B.x,0),this.faces.push(new THREE.Face3(q,t,s,[x,v,D],void 0,1)),this.faceVertexUvs[0].push([A,B,z]);if(!1===g&&0<b)for(this.vertices.push(new THREE.Vector3(0,-l,0)),k=0;k<d;k++)q=p[e][k+1],t=p[e][k],s=this.vertices.length-1,x=new THREE.Vector3(0,-1,0),v=new THREE.Vector3(0,-1,0),D=new THREE.Vector3(0,-1,0),A=m[e][k+1].clone(),B=m[e][k].clone(),z=new THREE.Vector2(B.x,1),this.faces.push(new THREE.Face3(q,t,s,[x,v,D],void 0,2)),this.faceVertexUvs[0].push([A,
-B,z]);this.computeFaceNormals()};THREE.CylinderGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.CylinderGeometry.prototype.constructor=THREE.CylinderGeometry;THREE.CylinderGeometry.prototype.clone=function(){var a=this.parameters;return new THREE.CylinderGeometry(a.radiusTop,a.radiusBottom,a.height,a.radialSegments,a.heightSegments,a.openEnded,a.thetaStart,a.thetaLength)};
-THREE.EdgesGeometry=function(a,b){function c(a,b){return a-b}THREE.BufferGeometry.call(this);var d=Math.cos(THREE.Math.degToRad(void 0!==b?b:1)),e=[0,0],g={},f=["a","b","c"],h;a instanceof THREE.BufferGeometry?(h=new THREE.Geometry,h.fromBufferGeometry(a)):h=a.clone();h.mergeVertices();h.computeFaceNormals();var l=h.vertices;h=h.faces;for(var k=0,n=h.length;k<n;k++)for(var p=h[k],m=0;3>m;m++){e[0]=p[f[m]];e[1]=p[f[(m+1)%3]];e.sort(c);var q=e.toString();void 0===g[q]?g[q]={vert1:e[0],vert2:e[1],face1:k,
+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 l=c/2,k,m,p=[],n=[];for(m=0;m<=e;m++){var q=[],s=[],t=m/e,v=t*(b-a)+a;for(k=0;k<=d;k++){var u=k/d,w=new THREE.Vector3;w.x=v*Math.sin(u*h+
+f);w.y=-t*c+l;w.z=v*Math.cos(u*h+f);this.vertices.push(w);q.push(this.vertices.length-1);s.push(new THREE.Vector2(u,1-t))}p.push(q);n.push(s)}c=(b-a)/c;for(k=0;k<d;k++)for(0!==a?(f=this.vertices[p[0][k]].clone(),h=this.vertices[p[0][k+1]].clone()):(f=this.vertices[p[1][k]].clone(),h=this.vertices[p[1][k+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(),m=0;m<e;m++){var q=p[m][k],s=p[m+1][k],t=p[m+1][k+1],v=p[m][k+1],u=f.clone(),w=f.clone(),
+D=h.clone(),x=h.clone(),B=n[m][k].clone(),y=n[m+1][k].clone(),z=n[m+1][k+1].clone(),A=n[m][k+1].clone();this.faces.push(new THREE.Face3(q,s,v,[u,w,x]));this.faceVertexUvs[0].push([B,y,A]);this.faces.push(new THREE.Face3(s,t,v,[w.clone(),D,x.clone()]));this.faceVertexUvs[0].push([y.clone(),z,A.clone()])}if(!1===g&&0<a)for(this.vertices.push(new THREE.Vector3(0,l,0)),k=0;k<d;k++)q=p[0][k],s=p[0][k+1],t=this.vertices.length-1,u=new THREE.Vector3(0,1,0),w=new THREE.Vector3(0,1,0),D=new THREE.Vector3(0,
+1,0),B=n[0][k].clone(),y=n[0][k+1].clone(),z=new THREE.Vector2(y.x,0),this.faces.push(new THREE.Face3(q,s,t,[u,w,D],void 0,1)),this.faceVertexUvs[0].push([B,y,z]);if(!1===g&&0<b)for(this.vertices.push(new THREE.Vector3(0,-l,0)),k=0;k<d;k++)q=p[e][k+1],s=p[e][k],t=this.vertices.length-1,u=new THREE.Vector3(0,-1,0),w=new THREE.Vector3(0,-1,0),D=new THREE.Vector3(0,-1,0),B=n[e][k+1].clone(),y=n[e][k].clone(),z=new THREE.Vector2(y.x,1),this.faces.push(new THREE.Face3(q,s,t,[u,w,D],void 0,2)),this.faceVertexUvs[0].push([B,
+y,z]);this.computeFaceNormals()};THREE.CylinderGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.CylinderGeometry.prototype.constructor=THREE.CylinderGeometry;THREE.CylinderGeometry.prototype.clone=function(){var a=this.parameters;return new THREE.CylinderGeometry(a.radiusTop,a.radiusBottom,a.height,a.radialSegments,a.heightSegments,a.openEnded,a.thetaStart,a.thetaLength)};
+THREE.EdgesGeometry=function(a,b){function c(a,b){return a-b}THREE.BufferGeometry.call(this);var d=Math.cos(THREE.Math.degToRad(void 0!==b?b:1)),e=[0,0],g={},f=["a","b","c"],h;a instanceof THREE.BufferGeometry?(h=new THREE.Geometry,h.fromBufferGeometry(a)):h=a.clone();h.mergeVertices();h.computeFaceNormals();var l=h.vertices;h=h.faces;for(var k=0,m=h.length;k<m;k++)for(var p=h[k],n=0;3>n;n++){e[0]=p[f[n]];e[1]=p[f[(n+1)%3]];e.sort(c);var q=e.toString();void 0===g[q]?g[q]={vert1:e[0],vert2:e[1],face1:k,
 face2:void 0}:g[q].face2=k}e=[];for(q in g)if(f=g[q],void 0===f.face2||h[f.face1].normal.dot(h[f.face2].normal)<=d)k=l[f.vert1],e.push(k.x),e.push(k.y),e.push(k.z),k=l[f.vert2],e.push(k.x),e.push(k.y),e.push(k.z);this.addAttribute("position",new THREE.BufferAttribute(new Float32Array(e),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(F=a.length;0<=--F;){c=F;d=F-1;0>d&&(d=a.length-1);for(var e=0,f=q+2*n,e=0;e<f;e++){var g=T*e,h=T*(e+1),k=b+c+g,g=b+d+g,l=b+d+h,h=b+c+h,k=k+G,g=g+G,l=l+G,h=h+G;L.faces.push(new THREE.Face3(k,g,h));L.faces.push(new THREE.Face3(g,l,h));k=x.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+=G;b+=G;c+=G;L.faces.push(new THREE.Face3(a,b,c));a=x.generateTopUV(L,a,b,c);L.faceVertexUvs[0].push(a)}var h=void 0!==b.amount?b.amount:100,l=void 0!==b.bevelThickness?b.bevelThickness:6,k=void 0!==b.bevelSize?b.bevelSize:l-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,
-s,u=!1,x=void 0!==b.UVGenerator?b.UVGenerator:THREE.ExtrudeGeometry.WorldUVGenerator,v,D,w,A;t&&(s=t.getSpacedPoints(q),u=!0,p=!1,v=void 0!==b.frames?b.frames:new THREE.TubeGeometry.FrenetFrames(t,q,!1),D=new THREE.Vector3,w=new THREE.Vector3,A=new THREE.Vector3);p||(k=l=n=0);var B,z,y,L=this,G=this.vertices.length,t=a.extractPoints(m),m=t.shape,C=t.holes;if(t=!THREE.Shape.Utils.isClockWise(m)){m=m.reverse();z=0;for(y=C.length;z<y;z++)B=C[z],THREE.Shape.Utils.isClockWise(B)&&(C[z]=B.reverse());t=
-!1}var N=THREE.Shape.Utils.triangulateShape(m,C),M=m;z=0;for(y=C.length;z<y;z++)B=C[z],m=m.concat(B);var O,K,E,J,Q,T=m.length,H,R=N.length,t=[],F=0;E=M.length;O=E-1;for(K=F+1;F<E;F++,O++,K++)O===E&&(O=0),K===E&&(K=0),t[F]=d(M[F],M[O],M[K]);var W=[],U,Y=t.concat();z=0;for(y=C.length;z<y;z++){B=C[z];U=[];F=0;E=B.length;O=E-1;for(K=F+1;F<E;F++,O++,K++)O===E&&(O=0),K===E&&(K=0),U[F]=d(B[F],B[O],B[K]);W.push(U);Y=Y.concat(U)}for(O=0;O<n;O++){E=O/n;J=l*(1-E);K=k*Math.sin(E*Math.PI/2);F=0;for(E=M.length;F<
-E;F++)Q=c(M[F],t[F],K),g(Q.x,Q.y,-J);z=0;for(y=C.length;z<y;z++)for(B=C[z],U=W[z],F=0,E=B.length;F<E;F++)Q=c(B[F],U[F],K),g(Q.x,Q.y,-J)}K=k;for(F=0;F<T;F++)Q=p?c(m[F],Y[F],K):m[F],u?(w.copy(v.normals[0]).multiplyScalar(Q.x),D.copy(v.binormals[0]).multiplyScalar(Q.y),A.copy(s[0]).add(w).add(D),g(A.x,A.y,A.z)):g(Q.x,Q.y,0);for(E=1;E<=q;E++)for(F=0;F<T;F++)Q=p?c(m[F],Y[F],K):m[F],u?(w.copy(v.normals[E]).multiplyScalar(Q.x),D.copy(v.binormals[E]).multiplyScalar(Q.y),A.copy(s[E]).add(w).add(D),g(A.x,A.y,
-A.z)):g(Q.x,Q.y,h/q*E);for(O=n-1;0<=O;O--){E=O/n;J=l*(1-E);K=k*Math.sin(E*Math.PI/2);F=0;for(E=M.length;F<E;F++)Q=c(M[F],t[F],K),g(Q.x,Q.y,h+J);z=0;for(y=C.length;z<y;z++)for(B=C[z],U=W[z],F=0,E=B.length;F<E;F++)Q=c(B[F],U[F],K),u?g(Q.x,Q.y+s[q-1].y,s[q-1].x+J):g(Q.x,Q.y,h+J)}(function(){if(p){var a;a=0*T;for(F=0;F<R;F++)H=N[F],f(H[2]+a,H[1]+a,H[0]+a);a=q+2*n;a*=T;for(F=0;F<R;F++)H=N[F],f(H[0]+a,H[1]+a,H[2]+a)}else{for(F=0;F<R;F++)H=N[F],f(H[2],H[1],H[0]);for(F=0;F<R;F++)H=N[F],f(H[0]+T*q,H[1]+T*
-q,H[2]+T*q)}})();(function(){var a=0;e(M,a);a+=M.length;z=0;for(y=C.length;z<y;z++)B=C[z],e(B,a),a+=B.length})()};
+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(Math.abs(d*g-e*f)>Number.EPSILON){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,d>Number.EPSILON?
+f>Number.EPSILON&&(a=!0):d<-Number.EPSILON?f<-Number.EPSILON&&(a=!0):Math.sign(e)===Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(G=a.length;0<=--G;){c=G;d=G-1;0>d&&(d=a.length-1);for(var e=0,f=q+2*m,e=0;e<f;e++){var g=T*e,h=T*(e+1),k=b+c+g,g=b+d+g,l=b+d+h,h=b+c+h,k=k+F,g=g+F,l=l+F,h=h+F;J.faces.push(new THREE.Face3(k,g,h,null,null,1));J.faces.push(new THREE.Face3(g,l,h,null,null,1));k=u.generateSideWallUV(J,
+k,g,l,h);J.faceVertexUvs[0].push([k[0],k[1],k[3]]);J.faceVertexUvs[0].push([k[1],k[2],k[3]])}}}function g(a,b,c){J.vertices.push(new THREE.Vector3(a,b,c))}function f(a,b,c){a+=F;b+=F;c+=F;J.faces.push(new THREE.Face3(a,b,c,null,null,0));a=u.generateTopUV(J,a,b,c);J.faceVertexUvs[0].push(a)}var h=void 0!==b.amount?b.amount:100,l=void 0!==b.bevelThickness?b.bevelThickness:6,k=void 0!==b.bevelSize?b.bevelSize:l-2,m=void 0!==b.bevelSegments?b.bevelSegments:3,p=void 0!==b.bevelEnabled?b.bevelEnabled:!0,
+n=void 0!==b.curveSegments?b.curveSegments:12,q=void 0!==b.steps?b.steps:1,s=b.extrudePath,t,v=!1,u=void 0!==b.UVGenerator?b.UVGenerator:THREE.ExtrudeGeometry.WorldUVGenerator,w,D,x,B;s&&(t=s.getSpacedPoints(q),v=!0,p=!1,w=void 0!==b.frames?b.frames:new THREE.TubeGeometry.FrenetFrames(s,q,!1),D=new THREE.Vector3,x=new THREE.Vector3,B=new THREE.Vector3);p||(k=l=m=0);var y,z,A,J=this,F=this.vertices.length,s=a.extractPoints(n),n=s.shape,C=s.holes;if(s=!THREE.ShapeUtils.isClockWise(n)){n=n.reverse();
+z=0;for(A=C.length;z<A;z++)y=C[z],THREE.ShapeUtils.isClockWise(y)&&(C[z]=y.reverse());s=!1}var N=THREE.ShapeUtils.triangulateShape(n,C),L=n;z=0;for(A=C.length;z<A;z++)y=C[z],n=n.concat(y);var Q,M,K,E,O,T=n.length,H,R=N.length,s=[],G=0;K=L.length;Q=K-1;for(M=G+1;G<K;G++,Q++,M++)Q===K&&(Q=0),M===K&&(M=0),s[G]=d(L[G],L[Q],L[M]);var ia=[],U,X=s.concat();z=0;for(A=C.length;z<A;z++){y=C[z];U=[];G=0;K=y.length;Q=K-1;for(M=G+1;G<K;G++,Q++,M++)Q===K&&(Q=0),M===K&&(M=0),U[G]=d(y[G],y[Q],y[M]);ia.push(U);X=
+X.concat(U)}for(Q=0;Q<m;Q++){K=Q/m;E=l*(1-K);M=k*Math.sin(K*Math.PI/2);G=0;for(K=L.length;G<K;G++)O=c(L[G],s[G],M),g(O.x,O.y,-E);z=0;for(A=C.length;z<A;z++)for(y=C[z],U=ia[z],G=0,K=y.length;G<K;G++)O=c(y[G],U[G],M),g(O.x,O.y,-E)}M=k;for(G=0;G<T;G++)O=p?c(n[G],X[G],M):n[G],v?(x.copy(w.normals[0]).multiplyScalar(O.x),D.copy(w.binormals[0]).multiplyScalar(O.y),B.copy(t[0]).add(x).add(D),g(B.x,B.y,B.z)):g(O.x,O.y,0);for(K=1;K<=q;K++)for(G=0;G<T;G++)O=p?c(n[G],X[G],M):n[G],v?(x.copy(w.normals[K]).multiplyScalar(O.x),
+D.copy(w.binormals[K]).multiplyScalar(O.y),B.copy(t[K]).add(x).add(D),g(B.x,B.y,B.z)):g(O.x,O.y,h/q*K);for(Q=m-1;0<=Q;Q--){K=Q/m;E=l*(1-K);M=k*Math.sin(K*Math.PI/2);G=0;for(K=L.length;G<K;G++)O=c(L[G],s[G],M),g(O.x,O.y,h+E);z=0;for(A=C.length;z<A;z++)for(y=C[z],U=ia[z],G=0,K=y.length;G<K;G++)O=c(y[G],U[G],M),v?g(O.x,O.y+t[q-1].y,t[q-1].x+E):g(O.x,O.y,h+E)}(function(){if(p){var a;a=0*T;for(G=0;G<R;G++)H=N[G],f(H[2]+a,H[1]+a,H[0]+a);a=q+2*m;a*=T;for(G=0;G<R;G++)H=N[G],f(H[0]+a,H[1]+a,H[2]+a)}else{for(G=
+0;G<R;G++)H=N[G],f(H[2],H[1],H[0]);for(G=0;G<R;G++)H=N[G],f(H[0]+T*q,H[1]+T*q,H[2]+T*q)}})();(function(){var a=0;e(L,a);a+=L.length;z=0;for(A=C.length;z<A;z++)y=C[z],e(y,a),a+=y.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 l=e.shape,k=e.holes;if(!THREE.Shape.Utils.isClockWise(l))for(l=l.reverse(),e=0,g=k.length;e<g;e++)f=k[e],THREE.Shape.Utils.isClockWise(f)&&(k[e]=f.reverse());var n=THREE.Shape.Utils.triangulateShape(l,k);e=0;for(g=k.length;e<g;e++)f=k[e],
-l=l.concat(f);k=l.length;g=n.length;for(e=0;e<k;e++)f=l[e],this.vertices.push(new THREE.Vector3(f.x,f.y,0));for(e=0;e<g;e++)k=n[e],l=k[0]+h,f=k[1]+h,k=k[2]+h,this.faces.push(new THREE.Face3(l,f,k,null,null,c)),this.faceVertexUvs[0].push(d.generateTopUV(this,l,f,k))};
-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 l=c+f*g*d,k=Math.cos(l),n=Math.sin(l),l=0,p=a.length;l<p;l++){var m=a[l],q=new THREE.Vector3;q.x=k*m.x-n*m.y;q.y=n*m.x+k*m.y;q.z=m.z;this.vertices.push(q)}c=a.length;f=0;for(h=b;f<h;f++)for(l=0,p=a.length-1;l<p;l++){b=n=l+c*f;d=n+c;var k=n+1+c,n=n+1,m=f*g,q=l*e,t=
-m+g,s=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,s)]);this.faces.push(new THREE.Face3(d,k,n));this.faceVertexUvs[0].push([new THREE.Vector2(t,q),new THREE.Vector2(t,s),new THREE.Vector2(m,s)])}this.mergeVertices();this.computeFaceNormals();this.computeVertexNormals()};THREE.LatheGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.LatheGeometry.prototype.constructor=THREE.LatheGeometry;
+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 l=e.shape,k=e.holes;if(!THREE.ShapeUtils.isClockWise(l))for(l=l.reverse(),e=0,g=k.length;e<g;e++)f=k[e],THREE.ShapeUtils.isClockWise(f)&&(k[e]=f.reverse());var m=THREE.ShapeUtils.triangulateShape(l,k);e=0;for(g=k.length;e<g;e++)f=k[e],l=l.concat(f);
+k=l.length;g=m.length;for(e=0;e<k;e++)f=l[e],this.vertices.push(new THREE.Vector3(f.x,f.y,0));for(e=0;e<g;e++)k=m[e],l=k[0]+h,f=k[1]+h,k=k[2]+h,this.faces.push(new THREE.Face3(l,f,k,null,null,c)),this.faceVertexUvs[0].push(d.generateTopUV(this,l,f,k))};
+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 l=c+f*g*d,k=Math.cos(l),m=Math.sin(l),l=0,p=a.length;l<p;l++){var n=a[l],q=new THREE.Vector3;q.x=k*n.x-m*n.y;q.y=m*n.x+k*n.y;q.z=n.z;this.vertices.push(q)}c=a.length;f=0;for(h=b;f<h;f++)for(l=0,p=a.length-1;l<p;l++){b=m=l+c*f;d=m+c;var k=m+1+c,m=m+1,n=f*g,q=l*e,s=
+n+g,t=q+e;this.faces.push(new THREE.Face3(b,d,m));this.faceVertexUvs[0].push([new THREE.Vector2(n,q),new THREE.Vector2(s,q),new THREE.Vector2(n,t)]);this.faces.push(new THREE.Face3(d,k,m));this.faceVertexUvs[0].push([new THREE.Vector2(s,q),new THREE.Vector2(s,t),new THREE.Vector2(n,t)])}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(){var a=this.parameters;return new THREE.PlaneGeometry(a.width,a.height,a.widthSegments,a.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,l=a/c,k=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*k-g,s=0;s<f;s++)b[p]=s*l-e,b[p+1]=-t,a[p+2]=1,n[m]=s/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(s=0;s<c;s++)g=s+f*(q+1),h=s+1+f*(q+1),l=s+1+f*q,e[p]=s+f*q,e[p+1]=g,e[p+2]=l,e[p+3]=g,e[p+4]=h,e[p+5]=l,p+=6;this.setIndex(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=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,l=a/c,k=b/d;b=new Float32Array(f*h*3);a=new Float32Array(f*h*3);for(var m=new Float32Array(f*h*2),p=0,n=0,q=0;q<h;q++)for(var s=q*k-g,t=0;t<f;t++)b[p]=t*l-e,b[p+1]=-s,a[p+2]=1,m[n]=t/c,m[n+1]=1-q/d,p+=3,n+=2;p=0;e=new (65535<b.length/3?Uint32Array:Uint16Array)(c*
+d*6);for(q=0;q<d;q++)for(t=0;t<c;t++)g=t+f*(q+1),h=t+1+f*(q+1),l=t+1+f*q,e[p]=t+f*q,e[p+1]=g,e[p+2]=l,e[p+3]=g,e[p+4]=h,e[p+5]=l,p+=6;this.setIndex(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(m,2))};THREE.PlaneBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.PlaneBufferGeometry.prototype.constructor=THREE.PlaneBufferGeometry;
 THREE.PlaneBufferGeometry.prototype.clone=function(){var a=this.parameters;return new THREE.PlaneBufferGeometry(a.width,a.height,a.widthSegments,a.heightSegments)};
-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=[],l=a,k=(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=l*Math.cos(p);n.y=l*Math.sin(p);this.vertices.push(n);h.push(new THREE.Vector2((n.x/b+1)/2,
-(n.y/b+1)/2))}l+=k}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,k=p+c+1,n=p+c+2,this.faces.push(new THREE.Face3(g,k,n,[b.clone(),b.clone(),b.clone()])),this.faceVertexUvs[0].push([h[g].clone(),h[k].clone(),h[n].clone()]),g=p,k=p+c+2,n=p+1,this.faces.push(new THREE.Face3(g,k,n,[b.clone(),b.clone(),b.clone()])),this.faceVertexUvs[0].push([h[g].clone(),h[k].clone(),h[n].clone()]);this.computeFaceNormals();this.boundingSphere=new THREE.Sphere(new THREE.Vector3,l)};
+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=[],l=a,k=(b-a)/d;for(a=0;a<d+1;a++){for(f=0;f<c+1;f++){var m=new THREE.Vector3,p=e+f/c*g;m.x=l*Math.cos(p);m.y=l*Math.sin(p);this.vertices.push(m);h.push(new THREE.Vector2((m.x/b+1)/2,
+(m.y/b+1)/2))}l+=k}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,k=p+c+1,m=p+c+2,this.faces.push(new THREE.Face3(g,k,m,[b.clone(),b.clone(),b.clone()])),this.faceVertexUvs[0].push([h[g].clone(),h[k].clone(),h[m].clone()]),g=p,k=p+c+2,m=p+1,this.faces.push(new THREE.Face3(g,k,m,[b.clone(),b.clone(),b.clone()])),this.faceVertexUvs[0].push([h[g].clone(),h[k].clone(),h[m].clone()]);this.computeFaceNormals();this.boundingSphere=new THREE.Sphere(new THREE.Vector3,l)};
 THREE.RingGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.RingGeometry.prototype.constructor=THREE.RingGeometry;THREE.RingGeometry.prototype.clone=function(){var a=this.parameters;return new THREE.RingGeometry(a.innerRadius,a.outerRadius,a.thetaSegments,a.phiSegments,a.thetaStart,a.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(){var a=this.parameters;return new THREE.SphereGeometry(a.radius,a.widthSegments,a.heightSegments,a.phiStart,a.phiLength,a.thetaStart,a.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,l=(b+1)*(c+1),k=new THREE.BufferAttribute(new Float32Array(3*l),3),n=new THREE.BufferAttribute(new Float32Array(3*
-l),3),l=new THREE.BufferAttribute(new Float32Array(2*l),2),p=0,m=[],q=new THREE.Vector3,t=0;t<=c;t++){for(var s=[],u=t/c,x=0;x<=b;x++){var v=x/b,D=-a*Math.cos(d+v*e)*Math.sin(g+u*f),w=a*Math.cos(g+u*f),A=a*Math.sin(d+v*e)*Math.sin(g+u*f);q.set(D,w,A).normalize();k.setXYZ(p,D,w,A);n.setXYZ(p,q.x,q.y,q.z);l.setXY(p,v,1-u);s.push(p);p++}m.push(s)}d=[];for(t=0;t<c;t++)for(x=0;x<b;x++)e=m[t][x+1],f=m[t][x],p=m[t+1][x],q=m[t+1][x+1],(0!==t||0<g)&&d.push(e,f,q),(t!==c-1||h<Math.PI)&&d.push(f,p,q);this.setIndex(new (65535<
-k.count?THREE.Uint32Attribute:THREE.Uint16Attribute)(d,1));this.addAttribute("position",k);this.addAttribute("normal",n);this.addAttribute("uv",l);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=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,l=(b+1)*(c+1),k=new THREE.BufferAttribute(new Float32Array(3*l),3),m=new THREE.BufferAttribute(new Float32Array(3*
+l),3),l=new THREE.BufferAttribute(new Float32Array(2*l),2),p=0,n=[],q=new THREE.Vector3,s=0;s<=c;s++){for(var t=[],v=s/c,u=0;u<=b;u++){var w=u/b,D=-a*Math.cos(d+w*e)*Math.sin(g+v*f),x=a*Math.cos(g+v*f),B=a*Math.sin(d+w*e)*Math.sin(g+v*f);q.set(D,x,B).normalize();k.setXYZ(p,D,x,B);m.setXYZ(p,q.x,q.y,q.z);l.setXY(p,w,1-v);t.push(p);p++}n.push(t)}d=[];for(s=0;s<c;s++)for(u=0;u<b;u++)e=n[s][u+1],f=n[s][u],p=n[s+1][u],q=n[s+1][u+1],(0!==s||0<g)&&d.push(e,f,q),(s!==c-1||h<Math.PI)&&d.push(f,p,q);this.setIndex(new (65535<
+k.count?THREE.Uint32Attribute:THREE.Uint16Attribute)(d,1));this.addAttribute("position",k);this.addAttribute("normal",m);this.addAttribute("uv",l);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=this.parameters;return new THREE.SphereBufferGeometry(a.radius,a.widthSegments,a.heightSegments,a.phiStart,a.phiLength,a.thetaStart,a.thetaLength)};
-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;
-THREE.TorusGeometry=function(a,b,c,d,e){THREE.Geometry.call(this);this.type="TorusGeometry";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};a=a||100;b=b||40;c=c||8;d=d||6;e=e||2*Math.PI;for(var g=new THREE.Vector3,f=[],h=[],l=0;l<=c;l++)for(var k=0;k<=d;k++){var n=k/d*e,p=l/c*Math.PI*2;g.x=a*Math.cos(n);g.y=a*Math.sin(n);var m=new THREE.Vector3;m.x=(a+b*Math.cos(p))*Math.cos(n);m.y=(a+b*Math.cos(p))*Math.sin(n);m.z=b*Math.sin(p);this.vertices.push(m);f.push(new THREE.Vector2(k/
-d,l/c));h.push(m.clone().sub(g).normalize())}for(l=1;l<=c;l++)for(k=1;k<=d;k++)a=(d+1)*l+k-1,b=(d+1)*(l-1)+k-1,e=(d+1)*(l-1)+k,g=(d+1)*l+k,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=function(a,b,c,d,e){THREE.Geometry.call(this);this.type="TorusGeometry";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};a=a||100;b=b||40;c=c||8;d=d||6;e=e||2*Math.PI;for(var g=new THREE.Vector3,f=[],h=[],l=0;l<=c;l++)for(var k=0;k<=d;k++){var m=k/d*e,p=l/c*Math.PI*2;g.x=a*Math.cos(m);g.y=a*Math.sin(m);var n=new THREE.Vector3;n.x=(a+b*Math.cos(p))*Math.cos(m);n.y=(a+b*Math.cos(p))*Math.sin(m);n.z=b*Math.sin(p);this.vertices.push(n);f.push(new THREE.Vector2(k/
+d,l/c));h.push(n.clone().sub(g).normalize())}for(l=1;l<=c;l++)for(k=1;k<=d;k++)a=(d+1)*l+k-1,b=(d+1)*(l-1)+k-1,e=(d+1)*(l-1)+k,g=(d+1)*l+k,m=new THREE.Face3(a,b,g,[h[a].clone(),h[b].clone(),h[g].clone()]),this.faces.push(m),this.faceVertexUvs[0].push([f[a].clone(),f[b].clone(),f[g].clone()]),m=new THREE.Face3(b,e,g,[h[b].clone(),h[e].clone(),h[g].clone()]),this.faces.push(m),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(){var a=this.parameters;return new THREE.TorusGeometry(a.radius,a.tube,a.radialSegments,a.tubularSegments,a.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 l=Array(c),k=new THREE.Vector3,n=new THREE.Vector3,p=new THREE.Vector3,m=0;m<c;++m){l[m]=
-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);k.subVectors(q,t);n.addVectors(q,t);p.crossVectors(k,n);n.crossVectors(p,k);p.normalize();n.normalize();for(q=0;q<d;++q){var s=q/d*2*Math.PI,u=-b*Math.cos(s),s=b*Math.sin(s),x=new THREE.Vector3;x.x=t.x+u*n.x+s*p.x;x.y=t.y+u*n.y+s*p.y;x.z=t.z+u*n.z+s*p.z;l[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=l[m][q],b=l[e][q],e=l[e][g],g=l[m][g],f=new THREE.Vector2(m/c,q/d),k=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,k,p]),this.faces.push(new THREE.Face3(b,e,g)),this.faceVertexUvs[0].push([k.clone(),n,p.clone()]);this.computeFaceNormals();this.computeVertexNormals()};THREE.TorusKnotGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.TorusKnotGeometry.prototype.constructor=THREE.TorusKnotGeometry;
+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 l=Array(c),k=new THREE.Vector3,m=new THREE.Vector3,p=new THREE.Vector3,n=0;n<c;++n){l[n]=
+Array(d);var q=n/c*2*e*Math.PI,s=h(q,g,e,a,f),q=h(q+.01,g,e,a,f);k.subVectors(q,s);m.addVectors(q,s);p.crossVectors(k,m);m.crossVectors(p,k);p.normalize();m.normalize();for(q=0;q<d;++q){var t=q/d*2*Math.PI,v=-b*Math.cos(t),t=b*Math.sin(t),u=new THREE.Vector3;u.x=s.x+v*m.x+t*p.x;u.y=s.y+v*m.y+t*p.y;u.z=s.z+v*m.z+t*p.z;l[n][q]=this.vertices.push(u)-1}}for(n=0;n<c;++n)for(q=0;q<d;++q)e=(n+1)%c,g=(q+1)%d,a=l[n][q],b=l[e][q],e=l[e][g],g=l[n][g],f=new THREE.Vector2(n/c,q/d),k=new THREE.Vector2((n+1)/c,
+q/d),m=new THREE.Vector2((n+1)/c,(q+1)/d),p=new THREE.Vector2(n/c,(q+1)/d),this.faces.push(new THREE.Face3(a,b,g)),this.faceVertexUvs[0].push([f,k,p]),this.faces.push(new THREE.Face3(b,e,g)),this.faceVertexUvs[0].push([k.clone(),m,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(){var a=this.parameters;return new THREE.TorusKnotGeometry(a.radius,a.tube,a.radialSegments,a.tubularSegments,a.p,a.q,a.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,taper:g};b=b||64;c=c||1;d=d||8;e=e||!1;g=g||THREE.TubeGeometry.NoTaper;var f=[],h,l,k=b+1,n,p,m,q,t,s=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<k;u++)for(f[u]=[],n=u/(k-1),t=a.getPointAt(n),h=x[u],l=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),s.copy(t),s.x+=q*h.x+p*l.x,s.y+=q*h.y+p*l.y,s.z+=q*h.z+p*l.z,f[u][n]=this.vertices.push(new THREE.Vector3(s.x,s.y,s.z))-1;for(u=0;u<b;u++)for(n=0;n<d;n++)g=e?(u+1)%b:u+1,k=(n+1)%d,a=f[u][n],c=f[g][n],g=f[g][k],k=f[u][k],s=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,k)),this.faceVertexUvs[0].push([s,x,h]),this.faces.push(new THREE.Face3(c,
-g,k)),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.prototype.clone=function(){return new this.constructor(this.parameters.path,this.parameters.segments,this.parameters.radius,this.parameters.radialSegments,this.parameters.closed,this.parameters.taper)};THREE.TubeGeometry.NoTaper=function(a){return 1};
+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,taper:g};b=b||64;c=c||1;d=d||8;e=e||!1;g=g||THREE.TubeGeometry.NoTaper;var f=[],h,l,k=b+1,m,p,n,q,s,t=new THREE.Vector3,v,u,w;v=new THREE.TubeGeometry.FrenetFrames(a,b,e);u=v.normals;w=v.binormals;this.tangents=v.tangents;this.normals=u;this.binormals=w;for(v=0;v<k;v++)for(f[v]=[],m=v/(k-1),s=a.getPointAt(m),h=u[v],l=w[v],n=c*g(m),m=0;m<
+d;m++)p=m/d*2*Math.PI,q=-n*Math.cos(p),p=n*Math.sin(p),t.copy(s),t.x+=q*h.x+p*l.x,t.y+=q*h.y+p*l.y,t.z+=q*h.z+p*l.z,f[v][m]=this.vertices.push(new THREE.Vector3(t.x,t.y,t.z))-1;for(v=0;v<b;v++)for(m=0;m<d;m++)g=e?(v+1)%b:v+1,k=(m+1)%d,a=f[v][m],c=f[g][m],g=f[g][k],k=f[v][k],t=new THREE.Vector2(v/b,m/d),u=new THREE.Vector2((v+1)/b,m/d),w=new THREE.Vector2((v+1)/b,(m+1)/d),h=new THREE.Vector2(v/b,(m+1)/d),this.faces.push(new THREE.Face3(a,c,k)),this.faceVertexUvs[0].push([t,u,h]),this.faces.push(new THREE.Face3(c,
+g,k)),this.faceVertexUvs[0].push([u.clone(),w,h.clone()]);this.computeFaceNormals();this.computeVertexNormals()};THREE.TubeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.TubeGeometry.prototype.constructor=THREE.TubeGeometry;THREE.TubeGeometry.prototype.clone=function(){return new this.constructor(this.parameters.path,this.parameters.segments,this.parameters.radius,this.parameters.radialSegments,this.parameters.closed,this.parameters.taper)};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,l=new THREE.Matrix4;b+=1;var k,n,p;this.tangents=e;this.normals=g;this.binormals=f;for(k=0;k<b;k++)n=k/(b-1),e[k]=a.getTangentAt(n),e[k].normalize();g[0]=new THREE.Vector3;f[0]=new THREE.Vector3;a=Number.MAX_VALUE;k=Math.abs(e[0].x);n=Math.abs(e[0].y);p=Math.abs(e[0].z);k<=a&&(a=k,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(k=1;k<b;k++)g[k]=g[k-1].clone(),f[k]=f[k-1].clone(),h.crossVectors(e[k-1],e[k]),1E-4<h.length()&&(h.normalize(),d=Math.acos(THREE.Math.clamp(e[k-1].dot(e[k]),-1,1)),g[k].applyMatrix4(l.makeRotationAxis(h,d))),f[k].crossVectors(e[k],g[k]);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),k=1;k<b;k++)g[k].applyMatrix4(l.makeRotationAxis(e[k],d*k)),f[k].crossVectors(e[k],g[k])};
-THREE.PolyhedronGeometry=function(a,b,c,d){function e(a){var b=a.normalize().clone();b.index=l.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);l.faces.push(d);u.copy(a).add(b).add(c).divideScalar(3);d=Math.atan2(u.z,-u.x);l.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(l.vertices[a.a]),f=e(l.vertices[a.b]),h=e(l.vertices[a.c]),k=[],m=a.materialIndex,n=0;n<=c;n++){k[n]=[];for(var p=e(d.clone().lerp(h,n/c)),q=e(f.clone().lerp(h,n/c)),s=c-n,t=0;t<=s;t++)k[n][t]=0===t&&n===c?p:e(p.clone().lerp(q,t/s))}for(n=0;n<c;n++)for(t=0;t<2*(c-n)-1;t++)d=Math.floor(t/2),0===t%2?g(k[n][d+1],k[n+1][d],k[n][d],m):g(k[n][d+1],k[n+1][d+1],k[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 l=this,k=0,n=a.length;k<n;k+=3)e(new THREE.Vector3(a[k],a[k+1],a[k+2]));a=this.vertices;for(var p=[],m=k=0,n=b.length;k<n;k+=3,m++){var q=a[b[k]],t=a[b[k+1]],s=a[b[k+2]];p[m]=new THREE.Face3(q.index,t.index,s.index,[q.clone(),t.clone(),s.clone()],void 0,m)}for(var u=new THREE.Vector3,k=0,n=p.length;k<n;k++)f(p[k],d);k=0;for(n=this.faceVertexUvs[0].length;k<
-n;k++)b=this.faceVertexUvs[0][k],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));k=0;for(n=this.vertices.length;k<n;k++)this.vertices[k].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.TubeGeometry.FrenetFrames=function(a,b,c){var d=new THREE.Vector3,e=[],g=[],f=[],h=new THREE.Vector3,l=new THREE.Matrix4;b+=1;var k,m,p;this.tangents=e;this.normals=g;this.binormals=f;for(k=0;k<b;k++)m=k/(b-1),e[k]=a.getTangentAt(m),e[k].normalize();g[0]=new THREE.Vector3;f[0]=new THREE.Vector3;a=Number.MAX_VALUE;k=Math.abs(e[0].x);m=Math.abs(e[0].y);p=Math.abs(e[0].z);k<=a&&(a=k,d.set(1,0,0));m<=a&&(a=m,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(k=1;k<b;k++)g[k]=g[k-1].clone(),f[k]=f[k-1].clone(),h.crossVectors(e[k-1],e[k]),h.length()>Number.EPSILON&&(h.normalize(),d=Math.acos(THREE.Math.clamp(e[k-1].dot(e[k]),-1,1)),g[k].applyMatrix4(l.makeRotationAxis(h,d))),f[k].crossVectors(e[k],g[k]);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),k=1;k<b;k++)g[k].applyMatrix4(l.makeRotationAxis(e[k],d*k)),f[k].crossVectors(e[k],g[k])};
+THREE.PolyhedronGeometry=function(a,b,c,d){function e(a){var b=a.normalize().clone();b.index=l.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);l.faces.push(d);v.copy(a).add(b).add(c).divideScalar(3);d=Math.atan2(v.z,-v.x);l.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(l.vertices[a.a]),f=e(l.vertices[a.b]),h=e(l.vertices[a.c]),k=[],n=a.materialIndex,m=0;m<=c;m++){k[m]=[];for(var p=e(d.clone().lerp(h,m/c)),q=e(f.clone().lerp(h,m/c)),s=c-m,t=0;t<=s;t++)k[m][t]=0===t&&m===c?p:e(p.clone().lerp(q,t/s))}for(m=0;m<c;m++)for(t=0;t<2*(c-m)-1;t++)d=Math.floor(t/2),0===t%2?g(k[m][d+1],k[m+1][d],k[m][d],n):g(k[m][d+1],k[m+1][d+1],k[m+1][d],n)}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 l=this,k=0,m=a.length;k<m;k+=3)e(new THREE.Vector3(a[k],a[k+1],a[k+2]));a=this.vertices;for(var p=[],n=k=0,m=b.length;k<m;k+=3,n++){var q=a[b[k]],s=a[b[k+1]],t=a[b[k+2]];p[n]=new THREE.Face3(q.index,s.index,t.index,[q.clone(),s.clone(),t.clone()],void 0,n)}for(var v=new THREE.Vector3,k=0,m=p.length;k<m;k++)f(p[k],d);k=0;for(m=this.faceVertexUvs[0].length;k<
+m;k++)b=this.faceVertexUvs[0][k],d=b[0].x,a=b[1].x,p=b[2].x,n=Math.max(d,a,p),q=Math.min(d,a,p),.9<n&&.1>q&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>p&&(b[2].x+=1));k=0;for(m=this.vertices.length;k<m;k++)this.vertices[k].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(){var a=this.parameters;return new THREE.PolyhedronGeometry(a.vertices,a.indices,a.radius,a.detail)};
 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,
 12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b}};THREE.DodecahedronGeometry.prototype=Object.create(THREE.PolyhedronGeometry.prototype);THREE.DodecahedronGeometry.prototype.constructor=THREE.DodecahedronGeometry;THREE.DodecahedronGeometry.prototype.clone=function(){var a=this.parameters;return new THREE.DodecahedronGeometry(a.radius,a.detail)};
@@ -830,10 +816,10 @@ THREE.IcosahedronGeometry=function(a,b){var c=(1+Math.sqrt(5))/2;THREE.Polyhedro
 THREE.IcosahedronGeometry.prototype.constructor=THREE.IcosahedronGeometry;THREE.IcosahedronGeometry.prototype.clone=function(){var a=this.parameters;return new THREE.IcosahedronGeometry(a.radius,a.detail)};THREE.OctahedronGeometry=function(a,b){THREE.PolyhedronGeometry.call(this,[1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b}};THREE.OctahedronGeometry.prototype=Object.create(THREE.PolyhedronGeometry.prototype);
 THREE.OctahedronGeometry.prototype.constructor=THREE.OctahedronGeometry;THREE.OctahedronGeometry.prototype.clone=function(){var a=this.parameters;return new THREE.OctahedronGeometry(a.radius,a.detail)};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=this.parameters;return new THREE.TetrahedronGeometry(a.radius,a.detail)};
-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,l,k,n=b+1;for(f=0;f<=c;f++)for(k=f/c,h=0;h<=b;h++)l=h/b,l=a(l,k),d.push(l);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,k=(f+1)*n+h+1,l=(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,l)),g.push([p,m,t]),e.push(new THREE.Face3(d,k,l)),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){function b(a,b){return a-b}THREE.BufferGeometry.call(this);var c=[0,0],d={},e=["a","b","c"];if(a instanceof THREE.Geometry){var g=a.vertices,f=a.faces,h=0,l=new Uint32Array(6*f.length);a=0;for(var k=f.length;a<k;a++)for(var n=f[a],p=0;3>p;p++){c[0]=n[e[p]];c[1]=n[e[(p+1)%3]];c.sort(b);var m=c.toString();void 0===d[m]&&(l[2*h]=c[0],l[2*h+1]=c[1],d[m]=!0,h++)}c=new Float32Array(6*h);a=0;for(k=h;a<k;a++)for(p=0;2>p;p++)d=g[l[2*a+p]],h=6*a+3*p,c[h+0]=d.x,c[h+1]=d.y,
-c[h+2]=d.z;this.addAttribute("position",new THREE.BufferAttribute(c,3))}else if(a instanceof THREE.BufferGeometry){if(null!==a.index){k=a.index.array;g=a.attributes.position;e=a.drawcalls;h=0;0===e.length&&a.addGroup(0,k.length);l=new Uint32Array(2*k.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++)c[0]=k[a+p],c[1]=k[a+(p+1)%3],c.sort(b),m=c.toString(),void 0===d[m]&&(l[2*h]=c[0],l[2*h+1]=c[1],d[m]=!0,h++)}c=new Float32Array(6*h);a=0;for(k=
+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,l,k,m=b+1;for(f=0;f<=c;f++)for(k=f/c,h=0;h<=b;h++)l=h/b,l=a(l,k),d.push(l);var p,n,q,s;for(f=0;f<c;f++)for(h=0;h<b;h++)a=f*m+h,d=f*m+h+1,k=(f+1)*m+h+1,l=(f+1)*m+h,p=new THREE.Vector2(h/b,f/c),n=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,l)),g.push([p,n,s]),e.push(new THREE.Face3(d,k,l)),g.push([n.clone(),q,s.clone()]);this.computeFaceNormals();this.computeVertexNormals()};THREE.ParametricGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ParametricGeometry.prototype.constructor=THREE.ParametricGeometry;
+THREE.WireframeGeometry=function(a){function b(a,b){return a-b}THREE.BufferGeometry.call(this);var c=[0,0],d={},e=["a","b","c"];if(a instanceof THREE.Geometry){var g=a.vertices,f=a.faces,h=0,l=new Uint32Array(6*f.length);a=0;for(var k=f.length;a<k;a++)for(var m=f[a],p=0;3>p;p++){c[0]=m[e[p]];c[1]=m[e[(p+1)%3]];c.sort(b);var n=c.toString();void 0===d[n]&&(l[2*h]=c[0],l[2*h+1]=c[1],d[n]=!0,h++)}c=new Float32Array(6*h);a=0;for(k=h;a<k;a++)for(p=0;2>p;p++)d=g[l[2*a+p]],h=6*a+3*p,c[h+0]=d.x,c[h+1]=d.y,
+c[h+2]=d.z;this.addAttribute("position",new THREE.BufferAttribute(c,3))}else if(a instanceof THREE.BufferGeometry){if(null!==a.index){k=a.index.array;g=a.attributes.position;e=a.drawcalls;h=0;0===e.length&&a.addGroup(0,k.length);l=new Uint32Array(2*k.length);f=0;for(m=e.length;f<m;++f){a=e[f];p=a.start;n=a.count;a=p;for(var q=p+n;a<q;a+=3)for(p=0;3>p;p++)c[0]=k[a+p],c[1]=k[a+(p+1)%3],c.sort(b),n=c.toString(),void 0===d[n]&&(l[2*h]=c[0],l[2*h+1]=c[1],d[n]=!0,h++)}c=new Float32Array(6*h);a=0;for(k=
 h;a<k;a++)for(p=0;2>p;p++)h=6*a+3*p,d=l[2*a+p],c[h+0]=g.getX(d),c[h+1]=g.getY(d),c[h+2]=g.getZ(d)}else for(g=a.attributes.position.array,h=g.length/3,l=h/3,c=new Float32Array(6*h),a=0,k=l;a<k;a++)for(p=0;3>p;p++)h=18*a+6*p,l=9*a+3*p,c[h+0]=g[l],c[h+1]=g[l+1],c[h+2]=g[l+2],d=9*a+(p+1)%3*3,c[h+3]=g[d],c[h+4]=g[d+1],c[h+5]=g[d+2];this.addAttribute("position",new THREE.BufferAttribute(c,3))}};THREE.WireframeGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);
 THREE.WireframeGeometry.prototype.constructor=THREE.WireframeGeometry;THREE.AxisHelper=function(a){a=a||1;var b=new Float32Array([0,0,0,a,0,0,0,0,0,0,a,0,0,0,0,0,0,a]),c=new Float32Array([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1]);a=new THREE.BufferGeometry;a.addAttribute("position",new THREE.BufferAttribute(b,3));a.addAttribute("color",new THREE.BufferAttribute(c,3));b=new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors});THREE.LineSegments.call(this,a,b)};THREE.AxisHelper.prototype=Object.create(THREE.LineSegments.prototype);
 THREE.AxisHelper.prototype.constructor=THREE.AxisHelper;
@@ -855,7 +841,7 @@ THREE.DirectionalLightHelper.prototype.update=function(){var a=new THREE.Vector3
 THREE.EdgesHelper=function(a,b,c){b=void 0!==b?b:16777215;THREE.LineSegments.call(this,new THREE.EdgesGeometry(a.geometry,c),new THREE.LineBasicMaterial({color:b}));this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.EdgesHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper;
 THREE.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=0;c=this.object.geometry;c instanceof THREE.Geometry?b=c.faces.length:console.warn("THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.");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.FaceNormalsHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.FaceNormalsHelper.prototype.constructor=THREE.FaceNormalsHelper;
-THREE.FaceNormalsHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Matrix3;return function(){this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);for(var d=this.object.matrixWorld,e=this.geometry.attributes.position,g=this.object.geometry,f=g.vertices,g=g.faces,h=0,l=0,k=g.length;l<k;l++){var n=g[l],p=n.normal;a.copy(f[n.a]).add(f[n.b]).add(f[n.c]).divideScalar(3).applyMatrix4(d);b.copy(p).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);
+THREE.FaceNormalsHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Matrix3;return function(){this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);for(var d=this.object.matrixWorld,e=this.geometry.attributes.position,g=this.object.geometry,f=g.vertices,g=g.faces,h=0,l=0,k=g.length;l<k;l++){var m=g[l],p=m.normal;a.copy(f[m.a]).add(f[m.b]).add(f[m.c]).divideScalar(3).applyMatrix4(d);b.copy(p).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);
 e.setXYZ(h,a.x,a.y,a.z);h+=1;e.setXYZ(h,b.x,b.y,b.z);h+=1}e.needsUpdate=!0;return this}}();
 THREE.GridHelper=function(a,b){var c=new THREE.Geometry,d=new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors});this.color1=new THREE.Color(4473924);this.color2=new THREE.Color(8947848);for(var e=-a;e<=a;e+=b){c.vertices.push(new THREE.Vector3(-a,0,e),new THREE.Vector3(a,0,e),new THREE.Vector3(e,0,-a),new THREE.Vector3(e,0,a));var g=0===e?this.color1:this.color2;c.colors.push(g,g,g,g)}THREE.LineSegments.call(this,c,d)};THREE.GridHelper.prototype=Object.create(THREE.LineSegments.prototype);
 THREE.GridHelper.prototype.constructor=THREE.GridHelper;THREE.GridHelper.prototype.setColors=function(a,b){this.color1.set(a);this.color2.set(b);this.geometry.colorsNeedUpdate=!0};
@@ -871,8 +857,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,l=f.faces,k=f=0,n=l.length;k<n;k++)for(var p=l[k],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.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,l=f.faces,k=f=0,m=l.length;k<m;k++)for(var p=l[k],n=0,q=p.vertexNormals.length;n<q;n++){var s=p.vertexNormals[n];a.copy(h[p[d[n]]]).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,n=f=0,q=d.count;n<q;n++)a.set(d.getX(n),d.getY(n),d.getZ(n)).applyMatrix4(e),b.set(h.getX(n),h.getY(n),h.getZ(n)),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(a){THREE.Object3D.call(this);this.material=a;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 - 16
docs/api/math/Math.html

@@ -16,23 +16,14 @@
 
 		<h2>Methods</h2>
 
-		<h3>[method:Float clamp]( [page:Float x], [page:Float a], [page:Float b] )</h3>
+		<h3>[method:Float clamp]( [page:Float value], [page:Float min], [page:Float max] )</h3>
 		<div>
-		x — Value to be clamped.<br />
-		a — Minimum value<br />
-		b — Maximum value.
+		value — Value to be clamped.<br />
+		min — Minimum value<br />
+		max — Maximum value.
 		</div>
 		<div>
-		Clamps the *x* to be between *a* and *b*.
-		</div>
-
-		<h3>[method:Float clampBottom]( [page:Float x], [page:Float a] )</h3>
-		<div>
-		x — Value to be clamped.<br />
-		a — Minimum value
-		</div>
-		<div>
-		Clamps the *x* to be larger than *a*.
+		Clamps the *value* to be between *min* and *max*.
 		</div>
 
 		<h3>[method:Float mapLinear]( [page:Float x], [page:Float a1], [page:Float a2], [page:Float b1], [page:Float b2] )</h3>
@@ -97,7 +88,7 @@
 		</div>
 		<div>
 		Returns a value between 0-1 that represents the percentage that x has moved between min and max, but smoothed or slowed down the closer X is to the min and max.<br/><br/>
-		
+
 		[link:http://en.wikipedia.org/wiki/Smoothstep Wikipedia]
 		</div>
 
@@ -110,7 +101,7 @@
 		<div>
 		Returns a value between 0-1. It works the same as smoothstep, but more smooth.
 		</div>
-		
+
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 1 - 0
docs/index.html

@@ -417,5 +417,6 @@
 			].join('\n'));
 
 		</script>
+		<script src="../build/three.min.js"></script> <!-- console sandbox -->
 	</body>
 </html>

+ 1 - 0
editor/css/dark.css

@@ -86,6 +86,7 @@ input.Number {
 	#menubar .menu.right {
 		float: right;
 		cursor: auto;
+		padding-right: 0px;
 		text-align: right;
 	}
 

+ 1 - 0
editor/css/light.css

@@ -79,6 +79,7 @@ input.Number {
 	#menubar .menu.right {
 		float: right;
 		cursor: auto;
+		padding-right: 0px;
 		text-align: right;
 	}
 

+ 7 - 16
editor/index.html

@@ -176,10 +176,8 @@
 			var sidebar = new Sidebar( editor );
 			document.body.appendChild( sidebar.dom );
 
-			/*
-			var dialog = new UI.Dialog();
-			document.body.appendChild( dialog.dom );
-			*/
+			var modal = new UI.Modal();
+			document.body.appendChild( modal.dom );
 
 			//
 
@@ -246,18 +244,11 @@
 				signals.scriptChanged.add( saveState );
 				signals.historyChanged.add( saveState );
 
-				/*
-				var showDialog = function ( content ) {
+				signals.showModal.add( function ( content ) {
 
-					dialog.clear();
+					modal.show( content );
 
-					dialog.add( content );
-					dialog.showModal();
-
-				};
-
-				signals.showDialog.add( showDialog );
-				*/
+				} );
 
 			} );
 
@@ -315,11 +306,11 @@
 
 			}, false );
 
-			var onWindowResize = function ( event ) {
+			function onWindowResize( event ) {
 
 				editor.signals.windowResize.dispatch();
 
-			};
+			}
 
 			window.addEventListener( 'resize', onWindowResize, false );
 

+ 1 - 9
editor/js/Editor.js

@@ -19,7 +19,7 @@ var Editor = function () {
 
 		// actions
 
-		// showDialog: new SIGNALS.Signal(),
+		showModal: new SIGNALS.Signal(),
 
 		// notifications
 
@@ -105,14 +105,6 @@ Editor.prototype = {
 
 	},
 
-	/*
-	showDialog: function ( value ) {
-
-		this.signals.showDialog.dispatch( value );
-
-	},
-	*/
-
 	//
 
 	setScene: function ( scene ) {

+ 21 - 21
editor/js/Menubar.File.js

@@ -86,8 +86,13 @@ Menubar.File = function ( editor ) {
 		}
 
 		var output = geometry.toJSON();
-		output = JSON.stringify( output, null, '\t' );
-		output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+
+		try {
+			output = JSON.stringify( output, null, '\t' );
+			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+		} catch ( e ) {
+			output = JSON.stringify( output );
+		}
 
 		exportString( output, 'geometry.json' );
 
@@ -111,8 +116,13 @@ Menubar.File = function ( editor ) {
 		}
 
 		var output = object.toJSON();
-		output = JSON.stringify( output, null, '\t' );
-		output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+
+		try {
+			output = JSON.stringify( output, null, '\t' );
+			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+		} catch ( e ) {
+			output = JSON.stringify( output );
+		}
 
 		exportString( output, 'model.json' );
 
@@ -127,8 +137,13 @@ Menubar.File = function ( editor ) {
 	option.onClick( function () {
 
 		var output = editor.scene.toJSON();
-		output = JSON.stringify( output, null, '\t' );
-		output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+
+		try {
+			output = JSON.stringify( output, null, '\t' );
+			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
+		} catch ( e ) {
+			output = JSON.stringify( output );
+		}
 
 		exportString( output, 'scene.json' );
 
@@ -260,21 +275,6 @@ Menubar.File = function ( editor ) {
 	} );
 	options.add( option );
 
-	/*
-	// Test
-
-	var option = new UI.Panel();
-	option.setClass( 'option' );
-	option.setTextContent( 'Test' );
-	option.onClick( function () {
-
-		var text = new UI.Text( 'blah' );
-		editor.showDialog( text );
-
-	} );
-	options.add( option );
-	*/
-
 
 	//
 

+ 10 - 6
editor/js/Menubar.Status.js

@@ -23,23 +23,27 @@ Menubar.Status = function ( editor ) {
 	} );
 	container.add( checkbox );
 
-	var title = new UI.Panel();
-	title.setClass( 'title' );
-	title.setTextContent( 'Autosave' );
-	container.add( title );
+	var text = new UI.Text( 'autosave' );
+	text.setClass( 'title' );
+	container.add( text );
 
 	editor.signals.savingStarted.add( function () {
 
-		title.setTextDecoration( 'underline' );
+		text.setTextDecoration( 'underline' );
 
 	} );
 
 	editor.signals.savingFinished.add( function () {
 
-		title.setTextDecoration( 'none' );
+		text.setTextDecoration( 'none' );
 
 	} );
 
+	var version = new UI.Text( 'r' + THREE.REVISION );
+	version.setClass( 'title' );
+	version.setOpacity( 0.5 );
+	container.add( version );
+
 	return container;
 
 };

+ 2 - 2
editor/js/Sidebar.Object3D.js

@@ -253,7 +253,7 @@ Sidebar.Object3D = function ( editor ) {
 	var objectCastShadow = new UI.Checkbox().onChange( update );
 
 	objectCastShadowSpan.add( objectCastShadow );
-	objectCastShadowSpan.add( new UI.Text( 'cast' ) );
+	objectCastShadowSpan.add( new UI.Text( 'cast' ).setMarginLeft( '3px' ) );
 
 	objectShadowRow.add( objectCastShadowSpan );
 
@@ -261,7 +261,7 @@ Sidebar.Object3D = function ( editor ) {
 	var objectReceiveShadow = new UI.Checkbox().onChange( update );
 
 	objectReceiveShadowSpan.add( objectReceiveShadow );
-	objectReceiveShadowSpan.add( new UI.Text( 'receive' ) );
+	objectReceiveShadowSpan.add( new UI.Text( 'receive' ).setMarginLeft( '3px' ) );
 
 	objectShadowRow.add( objectReceiveShadowSpan );
 

+ 2 - 2
editor/js/Sidebar.Project.js

@@ -85,7 +85,7 @@ Sidebar.Project = function ( editor ) {
 	} );
 
 	rendererAntialiasSpan.add( rendererAntialias );
-	rendererAntialiasSpan.add( new UI.Text( 'antialias' ) );
+	rendererAntialiasSpan.add( new UI.Text( 'antialias' ).setMarginLeft( '3px' ) );
 
 	rendererPropertiesRow.add( rendererAntialiasSpan );
 
@@ -100,7 +100,7 @@ Sidebar.Project = function ( editor ) {
 	} );
 
 	rendererShadowsSpan.add( rendererShadows );
-	rendererShadowsSpan.add( new UI.Text( 'shadows' ) );
+	rendererShadowsSpan.add( new UI.Text( 'shadows' ).setMarginLeft( '3px' ) );
 
 	rendererPropertiesRow.add( rendererShadowsSpan );
 

+ 7 - 8
editor/js/Toolbar.js

@@ -37,22 +37,21 @@ var Toolbar = function ( editor ) {
 
 	// grid
 
-	var grid = new UI.Number( 25 ).onChange( update );
-	grid.dom.style.width = '42px';
+	var grid = new UI.Number( 25 ).setWidth( '40px' ).onChange( update );
 	buttons.add( new UI.Text( 'Grid: ' ) );
 	buttons.add( grid );
 
-	var snap = new UI.Checkbox( false ).onChange( update );
+	var snap = new UI.Checkbox( false ).onChange( update ).setMarginLeft( '10px' );
 	buttons.add( snap );
-	buttons.add( new UI.Text( 'snap' ) );
+	buttons.add( new UI.Text( 'snap' ).setMarginLeft( '3px' ) );
 
-	var local = new UI.Checkbox( false ).onChange( update );
+	var local = new UI.Checkbox( false ).onChange( update ).setMarginLeft( '10px' );
 	buttons.add( local );
-	buttons.add( new UI.Text( 'local' ) );
+	buttons.add( new UI.Text( 'local' ).setMarginLeft( '3px' ) );
 
-	var showGrid = new UI.Checkbox().onChange( update ).setValue( true );
+	var showGrid = new UI.Checkbox().onChange( update ).setValue( true ).setMarginLeft( '10px' );
 	buttons.add( showGrid );
-	buttons.add( new UI.Text( 'show' ) );
+	buttons.add( new UI.Text( 'show' ).setMarginLeft( '3px' ) );
 
 	function update() {
 

+ 33 - 22
editor/js/libs/ui.js

@@ -1014,47 +1014,58 @@ UI.Button.prototype.setLabel = function ( value ) {
 };
 
 
-// Dialog
+// Modal
 
-UI.Dialog = function ( value ) {
+UI.Modal = function ( value ) {
 
 	var scope = this;
 
-	var dom = document.createElement( 'dialog' );
+	var dom = document.createElement( 'div' );
 
-	if ( dom.showModal === undefined ) {
+	dom.style.position = 'absolute';
+	dom.style.width = '100%';
+	dom.style.height = '100%';
+	dom.style.backgroundColor = 'rgba(0,0,0,0.5)';
+	dom.style.display = 'none';
+	dom.style.alignItems = 'center';
+	dom.style.justifyContent = 'center';
+	dom.addEventListener( 'click', function ( event ) {
 
-		// fallback
+		scope.hide();
 
-		dom = document.createElement( 'div' );
-		dom.style.display = 'none';
+	} );
 
-		dom.showModal = function () {
+	this.dom = dom;
 
-			dom.style.position = 'absolute';
-			dom.style.left = '100px';
-			dom.style.top = '100px';
-			dom.style.zIndex = 1;
-			dom.style.display = '';
+	this.container = new UI.Panel();
+	this.container.dom.style.width = '200px';
+	this.container.dom.style.padding = '20px';
+	this.container.dom.style.backgroundColor = '#ffffff';
+	this.container.dom.style.boxShadow = '0px 5px 10px rgba(0,0,0,0.5)';
 
-		};
+	this.add( this.container );
 
-	}
+	return this;
 
-	dom.className = 'Dialog';
+};
 
-	this.dom = dom;
+UI.Modal.prototype = Object.create( UI.Element.prototype );
+UI.Modal.prototype.constructor = UI.Modal;
+
+UI.Modal.prototype.show = function ( content ) {
+
+	this.container.clear();
+	this.container.add( content );
+
+	this.dom.style.display = 'flex';
 
 	return this;
 
 };
 
-UI.Dialog.prototype = Object.create( UI.Panel.prototype );
-UI.Dialog.prototype.constructor = UI.Dialog;
-
-UI.Dialog.prototype.showModal = function () {
+UI.Modal.prototype.hide = function () {
 
-	this.dom.showModal();
+	this.dom.style.display = 'none';
 
 	return this;
 

+ 8 - 4
examples/canvas_geometry_text.html

@@ -23,8 +23,8 @@
 
 		<script src="js/libs/stats.min.js"></script>
 
-		<!-- load the font file from canvas-text -->
-
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 		<script src="fonts/helvetiker_regular.typeface.js"></script>
 
 
@@ -90,8 +90,12 @@
 				text3d.computeBoundingBox();
 				var centerOffset = -0.5 * ( text3d.boundingBox.max.x - text3d.boundingBox.min.x );
 
-				var textMaterial = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } );
-				text = new THREE.Mesh( text3d, textMaterial );
+				var material = new THREE.MeshFaceMaterial( [
+					new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } ),
+					new THREE.MeshBasicMaterial( { color: 0x000000, overdraw: 0.5 } )
+				] );
+
+				text = new THREE.Mesh( text3d, material );
 
 				text.position.x = centerOffset;
 				text.position.y = 100;

+ 2 - 0
examples/index.html

@@ -190,6 +190,7 @@
 		var files = {
 			"webgl": [
 				"webgl_animation_cloth",
+				"webgl_animation_scene",
 				"webgl_animation_skinning_blending",
 				"webgl_animation_skinning_morph",
 				"webgl_camera",
@@ -348,6 +349,7 @@
 				"webgl_postprocessing_godrays",
 				"webgl_postprocessing_ssao",
 				"webgl_raycast_texture",
+				"webgl_read_float_buffer",
 				"webgl_rtt",
 				"webgl_sandbox",
 				"webgl_shader",

+ 0 - 0
src/extras/geometries/TextGeometry.js → examples/js/geometries/TextGeometry.js


+ 6 - 1
examples/js/loaders/ColladaLoader2.js

@@ -468,7 +468,12 @@ THREE.ColladaLoader.prototype = {
 					function pushVector( i ) {
 
 						var index = indices[ i + offset ] * 3;
-						array.push( source[ index + 0 ], source[ index + 1 ], source[ index + 2 ] );
+
+						if ( asset.upAxis === 'Z_UP' ) {
+							array.push( source[ index + 0 ], source[ index + 2 ], - source[ index + 1 ] );
+						} else {
+							array.push( source[ index + 0 ], source[ index + 1 ], source[ index + 2 ] );
+						}
 
 					}
 

+ 146 - 32
examples/js/loaders/VRMLLoader.js

@@ -44,10 +44,14 @@ THREE.VRMLLoader.prototype = {
 
 		this.crossOrigin = value;
 
+		THREE.ImageUtils.crossOrigin = value;
+
 	},
 
 	parse: function ( data ) {
 
+		var texturePath = this.texturePath || '';
+
 		var parseV1 = function ( lines, scene ) {
 
 			console.warn( 'VRML V1.0 not supported yet' );
@@ -58,6 +62,7 @@ THREE.VRMLLoader.prototype = {
 
 			var defines = {};
 			var float_pattern = /(\b|\-|\+)([\d\.e]+)/;
+			var float2_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
 			var float3_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
 
 			/**
@@ -239,10 +244,10 @@ THREE.VRMLLoader.prototype = {
 						this.points = [];
 						break;
 					case 'coordIndex':
+					case 'texCoordIndex':
 						this.recordingFieldname = fieldName;
 						this.isRecordingFaces = true;
 						this.indexes = [];
-						break;
 				}
 
 				if ( this.isRecordingFaces ) {
@@ -287,12 +292,14 @@ THREE.VRMLLoader.prototype = {
 					if ( /]/.exec( line ) ) {
 
 						this.isRecordingFaces = false;
-						node.coordIndex = this.indexes;
+						node[this.recordingFieldname] = this.indexes;
 
 					}
 
 				} else if ( this.isRecordingPoints ) {
 
+					if ( node.nodeType == 'Coordinate' )
+
 					while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
 
 						point = {
@@ -305,6 +312,19 @@ THREE.VRMLLoader.prototype = {
 
 					}
 
+					if ( node.nodeType == 'TextureCoordinate' )
+
+					while ( null !== ( parts = float2_pattern.exec( line ) ) ) {
+
+						point = {
+							x: parseFloat( parts[ 1 ] ),
+							y: parseFloat( parts[ 2 ] )
+						};
+
+						this.points.push( point );
+
+					}
+
 					// end
 					if ( /]/.exec( line ) ) {
 
@@ -505,7 +525,7 @@ THREE.VRMLLoader.prototype = {
 
 					}
 
-					if ( matches = /([^\s]*){1}\s?{/.exec( line ) ) {
+					if ( matches = /([^\s]*){1}(?:\s+)?{/.exec( line ) ) {
 
 						// first subpattern should match the Node name
 
@@ -637,7 +657,7 @@ THREE.VRMLLoader.prototype = {
 
 					if ( /DEF/.exec( data.string ) ) {
 
-						object.name = /DEF (\w+)/.exec( data.string )[ 1 ];
+						object.name = /DEF\s+(\w+)/.exec( data.string )[ 1 ];
 
 						defines[ object.name ] = object;
 
@@ -710,7 +730,7 @@ THREE.VRMLLoader.prototype = {
 
 						var geometry = new THREE.Geometry();
 
-						var indexes;
+						var indexes, uvIndexes, uvs;
 
 						for ( var i = 0, j = data.children.length; i < j; i ++ ) {
 
@@ -718,53 +738,102 @@ THREE.VRMLLoader.prototype = {
 
 							var vec;
 
+							if ( 'TextureCoordinate' === child.nodeType ) {
+
+								uvs = child.points;
+
+							}
+
+
 							if ( 'Coordinate' === child.nodeType ) {
 
-								for ( var k = 0, l = child.points.length; k < l; k ++ ) {
+								if ( child.points ) {
+
+									for ( var k = 0, l = child.points.length; k < l; k ++ ) {
 
-									var point = child.points[ k ];
+										var point = child.points[ k ];
 
-									vec = new THREE.Vector3( point.x, point.y, point.z );
+										vec = new THREE.Vector3( point.x, point.y, point.z );
 
-									geometry.vertices.push( vec );
+										geometry.vertices.push( vec );
+
+									}
 
 								}
 
-								break;
+								if ( child.string.indexOf ( 'DEF' ) > -1 ) {
 
-							}
+									var name = /DEF\s+(\w+)/.exec( child.string )[ 1 ];
 
-						}
+									defines[ name ] = geometry.vertices;
 
-						var skip = 0;
+								}
+
+								if ( child.string.indexOf ( 'USE' ) > -1 ) {
 
-						// read this: http://math.hws.edu/eck/cs424/notes2013/16_Threejs_Advanced.html
-						for ( var i = 0, j = data.coordIndex.length; i < j; i ++ ) {
+									var defineKey = /USE\s+(\w+)/.exec( child.string )[ 1 ];
 
-							indexes = data.coordIndex[ i ];
+									geometry.vertices = defines[ defineKey ];
+								}
 
-							// vrml support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
-							skip = 0;
+							}
 
-							// todo: this is the time to check if the faces are ordered ccw or not (cw)
+						}
 
-							// Face3 only works with triangles, but IndexedFaceSet allows shapes with more then three vertices, build them of triangles
-							while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) {
+						var skip = 0;
 
-								var face = new THREE.Face3(
-									indexes[ 0 ],
-									indexes[ skip + 1 ],
-									indexes[ skip + 2 ],
-									null // normal, will be added later
-									// todo: pass in the color, if a color index is present
-								);
+						// some shapes only have vertices for use in other shapes
+						if ( data.coordIndex ) {
+
+							// read this: http://math.hws.edu/eck/cs424/notes2013/16_Threejs_Advanced.html
+							for ( var i = 0, j = data.coordIndex.length; i < j; i ++ ) {
+
+								indexes = data.coordIndex[ i ]; if ( data.texCoordIndex ) uvIndexes = data.texCoordIndex[ i ];
+
+								// vrml support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
+								skip = 0;
+
+								// Face3 only works with triangles, but IndexedFaceSet allows shapes with more then three vertices, build them of triangles
+								while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) {
+
+									var face = new THREE.Face3(
+										indexes[ 0 ],
+										indexes[ skip + (data.ccw ? 1 : 2) ],
+										indexes[ skip + (data.ccw ? 2 : 1) ],
+										null // normal, will be added later
+										// todo: pass in the color, if a color index is present
+									);
+
+									if ( uvs && uvIndexes ) {
+										geometry.faceVertexUvs [0].push( [
+											new THREE.Vector2 (
+												uvs[ uvIndexes[ 0 ] ].x ,
+												uvs[ uvIndexes[ 0 ] ].y
+											) ,
+											new THREE.Vector2 (
+												uvs[ uvIndexes[ skip + (data.ccw ? 1 : 2) ] ].x ,
+												uvs[ uvIndexes[ skip + (data.ccw ? 1 : 2) ] ].y
+											) ,
+											new THREE.Vector2 (
+												uvs[ uvIndexes[ skip + (data.ccw ? 2 : 1) ] ].x ,
+												uvs[ uvIndexes[ skip + (data.ccw ? 2 : 1) ] ].y
+											)
+										] );
+									}
+
+									skip ++;
+
+									geometry.faces.push( face );
 
-								skip ++;
+								}
 
-								geometry.faces.push( face );
 
 							}
 
+						} else {
+
+							// do not add dummy mesh to the scene
+							parent.parent.remove( parent );
 
 						}
 
@@ -850,8 +919,19 @@ THREE.VRMLLoader.prototype = {
 
 							parent.material = material;
 
-							// material found, stop looping
-							break;
+						}
+
+						if ( 'ImageTexture' === child.nodeType ) {
+
+							var textureName = /"([^"]+)"/.exec(child.children[ 0 ]);
+
+							if (textureName) {
+
+								parent.material.name = textureName[ 1 ];
+
+								parent.material.map = THREE.ImageUtils.loadTexture (texturePath + textureName[ 1 ]);
+
+							}
 
 						}
 
@@ -879,6 +959,40 @@ THREE.VRMLLoader.prototype = {
 
 		var lines = data.split( '\n' );
 
+		// some lines do not have breaks
+		for (var i = lines.length -1; i > -1; i--) {
+
+			// split lines with {..{ or {..[ - some have both
+			if (/{.*[{\[]/.test (lines[i])) {
+				var parts = lines[i].split ('{').join ('{\n').split ('\n');
+				parts.unshift(1);
+				parts.unshift(i);
+				lines.splice.apply(lines, parts);
+			} else
+
+			// split lines with ]..}
+			if (/\].*}/.test (lines[i])) {
+				var parts = lines[i].split (']').join (']\n').split ('\n');
+				parts.unshift(1);
+				parts.unshift(i);
+				lines.splice.apply(lines, parts);
+			}
+
+			// split lines with }..}
+			if (/}.*}/.test (lines[i])) {
+				var parts = lines[i].split ('}').join ('}\n').split ('\n');
+				parts.unshift(1);
+				parts.unshift(i);
+				lines.splice.apply(lines, parts);
+			}
+
+			// force the parser to create Coordinate node for empty coords
+			// coord USE something -> coord USE something Coordinate {}
+			if((lines[i].indexOf ('coord') > -1) && (lines[i].indexOf ('[') < 0) && (lines[i].indexOf ('{') < 0)) {
+				lines[i] += ' Coordinate {}';
+			}
+		}
+
 		var header = lines.shift();
 
 		if ( /V1.0/.exec( header ) ) {

File diff suppressed because it is too large
+ 716 - 258
examples/js/loaders/sea3d/SEA3D.js


File diff suppressed because it is too large
+ 244 - 152
examples/js/loaders/sea3d/SEA3DLoader.js


+ 1 - 1
examples/js/renderers/CSS3DRenderer.js

@@ -98,7 +98,7 @@ THREE.CSS3DRenderer = function () {
 
 	var epsilon = function ( value ) {
 
-		return Math.abs( value ) < 0.000001 ? 0 : value;
+		return Math.abs( value ) < Number.EPSILON ? 0 : value;
 
 	};
 

+ 1 - 1
examples/js/renderers/CSS3DStereoRenderer.js

@@ -145,7 +145,7 @@ THREE.CSS3DStereoRenderer = function () {
 
 	var epsilon = function ( value ) {
 
-		return Math.abs( value ) < 0.000001 ? 0 : value;
+		return Math.abs( value ) < Number.EPSILON ? 0 : value;
 
 	};
 

+ 13 - 204
src/extras/FontUtils.js → examples/js/utils/FontUtils.js

@@ -109,6 +109,9 @@ THREE.FontUtils = {
 
 		var pts = [];
 
+		var b2 = THREE.ShapeUtils.b2;
+		var b3 = THREE.ShapeUtils.b3;
+
 		var i, i2, divisions,
 			outline, action, length,
 			scaleX, scaleY,
@@ -174,8 +177,8 @@ THREE.FontUtils = {
 						for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
 
 							var t = i2 / divisions;
-							THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx );
-							THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy );
+							b2( t, cpx0, cpx1, cpx );
+							b2( t, cpy0, cpy1, cpy );
 
 						}
 
@@ -187,12 +190,12 @@ THREE.FontUtils = {
 
 					// Cubic Bezier Curve
 
-					cpx  = outline[ i ++ ] *  scaleX + offset;
-					cpy  = outline[ i ++ ] *  scaleY;
-					cpx1 = outline[ i ++ ] *  scaleX + offset;
-					cpy1 = outline[ i ++ ] *  scaleY;
-					cpx2 = outline[ i ++ ] *  scaleX + offset;
-					cpy2 = outline[ i ++ ] *  scaleY;
+					cpx  = outline[ i ++ ] * scaleX + offset;
+					cpy  = outline[ i ++ ] * scaleY;
+					cpx1 = outline[ i ++ ] * scaleX + offset;
+					cpy1 = outline[ i ++ ] * scaleY;
+					cpx2 = outline[ i ++ ] * scaleX + offset;
+					cpy2 = outline[ i ++ ] * scaleY;
 
 					path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
 
@@ -206,8 +209,8 @@ THREE.FontUtils = {
 						for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
 
 							var t = i2 / divisions;
-							THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx );
-							THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy );
+							b3( t, cpx0, cpx1, cpx2, cpx );
+							b3( t, cpy0, cpy1, cpy2, cpy );
 
 						}
 
@@ -267,200 +270,6 @@ THREE.FontUtils.generateShapes = function ( text, parameters ) {
 
 };
 
-
-/**
- * This code is a quick port of code written in C++ which was submitted to
- * flipcode.com by John W. Ratcliff  // July 22, 2000
- * See original code and more information here:
- * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
- *
- * ported to actionscript by Zevan Rosser
- * www.actionsnippet.com
- *
- * ported to javascript by Joshua Koo
- * http://www.lab4games.net/zz85/blog
- *
- */
-
-
-( function ( namespace ) {
-
-	var EPSILON = 0.0000000001;
-
-	// takes in an contour array and returns
-
-	function process( contour, indices ) {
-
-		var n = contour.length;
-
-		if ( n < 3 ) return null;
-
-		var result = [],
-			verts = [],
-			vertIndices = [];
-
-		/* we want a counter-clockwise polygon in verts */
-
-		var u, v, w;
-
-		if ( area( contour ) > 0.0 ) {
-
-			for ( v = 0; v < n; v ++ ) verts[ v ] = v;
-
-		} else {
-
-			for ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;
-
-		}
-
-		var nv = n;
-
-		/*  remove nv - 2 vertices, creating 1 triangle every time */
-
-		var count = 2 * nv;   /* error detection */
-
-		for ( v = nv - 1; nv > 2; ) {
-
-			/* if we loop, it is probably a non-simple polygon */
-
-			if ( ( count -- ) <= 0 ) {
-
-				//** Triangulate: ERROR - probable bad polygon!
-
-				//throw ( "Warning, unable to triangulate polygon!" );
-				//return null;
-				// Sometimes warning is fine, especially polygons are triangulated in reverse.
-				console.warn( 'THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()' );
-
-				if ( indices ) return vertIndices;
-				return result;
-
-			}
-
-			/* three consecutive vertices in current polygon, <u,v,w> */
-
-			u = v; 	 	if ( nv <= u ) u = 0;     /* previous */
-			v = u + 1;  if ( nv <= v ) v = 0;     /* new v    */
-			w = v + 1;  if ( nv <= w ) w = 0;     /* next     */
-
-			if ( snip( contour, u, v, w, nv, verts ) ) {
-
-				var a, b, c, s, t;
-
-				/* true names of the vertices */
-
-				a = verts[ u ];
-				b = verts[ v ];
-				c = verts[ w ];
-
-				/* output Triangle */
-
-				result.push( [ contour[ a ],
-					contour[ b ],
-					contour[ c ] ] );
-
-
-				vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );
-
-				/* remove v from the remaining polygon */
-
-				for ( s = v, t = v + 1; t < nv; s ++, t ++ ) {
-
-					verts[ s ] = verts[ t ];
-
-				}
-
-				nv --;
-
-				/* reset error detection counter */
-
-				count = 2 * nv;
-
-			}
-
-		}
-
-		if ( indices ) return vertIndices;
-		return result;
-
-	}
-
-	// calculate area of the contour polygon
-
-	function area( contour ) {
-
-		var n = contour.length;
-		var a = 0.0;
-
-		for ( var p = n - 1, q = 0; q < n; p = q ++ ) {
-
-			a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
-
-		}
-
-		return a * 0.5;
-
-	}
-
-	function snip( contour, u, v, w, n, verts ) {
-
-		var p;
-		var ax, ay, bx, by;
-		var cx, cy, px, py;
-
-		ax = contour[ verts[ u ] ].x;
-		ay = contour[ verts[ u ] ].y;
-
-		bx = contour[ verts[ v ] ].x;
-		by = contour[ verts[ v ] ].y;
-
-		cx = contour[ verts[ w ] ].x;
-		cy = contour[ verts[ w ] ].y;
-
-		if ( EPSILON > ( ( ( bx - ax ) * ( cy - ay ) ) - ( ( by - ay ) * ( cx - ax ) ) ) ) return false;
-
-		var aX, aY, bX, bY, cX, cY;
-		var apx, apy, bpx, bpy, cpx, cpy;
-		var cCROSSap, bCROSScp, aCROSSbp;
-
-		aX = cx - bx;  aY = cy - by;
-		bX = ax - cx;  bY = ay - cy;
-		cX = bx - ax;  cY = by - ay;
-
-		for ( p = 0; p < n; p ++ ) {
-
-			px = contour[ verts[ p ] ].x;
-			py = contour[ verts[ p ] ].y;
-
-			if ( ( ( px === ax ) && ( py === ay ) ) ||
-				 ( ( px === bx ) && ( py === by ) ) ||
-				 ( ( px === cx ) && ( py === cy ) ) )	continue;
-
-			apx = px - ax;  apy = py - ay;
-			bpx = px - bx;  bpy = py - by;
-			cpx = px - cx;  cpy = py - cy;
-
-			// see if p is inside triangle abc
-
-			aCROSSbp = aX * bpy - aY * bpx;
-			cCROSSap = cX * apy - cY * apx;
-			bCROSScp = bX * cpy - bY * cpx;
-
-			if ( ( aCROSSbp >= - EPSILON ) && ( bCROSScp >= - EPSILON ) && ( cCROSSap >= - EPSILON ) ) return false;
-
-		}
-
-		return true;
-
-	}
-
-	namespace.Triangulate = process;
-	namespace.Triangulate.area = area;
-
-	return namespace;
-
-} )( THREE.FontUtils );
-
 // To use the typeface.js face files, hook up the API
 
 THREE.typeface_js = { faces: THREE.FontUtils.faces, loadFace: THREE.FontUtils.loadFace };

+ 136 - 0
examples/js/utils/ImageUtils.js

@@ -0,0 +1,136 @@
+/**
+ * @author alteredq / http://alteredqualia.com/
+ * @author mrdoob / http://mrdoob.com/
+ * @author Daosheng Mu / https://github.com/DaoshengMu/
+ */
+
+THREE.ImageUtils = {
+
+	getNormalMap: function ( image, depth ) {
+
+		// Adapted from http://www.paulbrunt.co.uk/lab/heightnormal/
+
+		function cross( a, b ) {
+
+			return [ a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ], a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ], a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ] ];
+
+		}
+
+		function subtract( a, b ) {
+
+			return [ a[ 0 ] - b[ 0 ], a[ 1 ] - b[ 1 ], a[ 2 ] - b[ 2 ] ];
+
+		}
+
+		function normalize( a ) {
+
+			var l = Math.sqrt( a[ 0 ] * a[ 0 ] + a[ 1 ] * a[ 1 ] + a[ 2 ] * a[ 2 ] );
+			return [ a[ 0 ] / l, a[ 1 ] / l, a[ 2 ] / l ];
+
+		}
+
+		depth = depth | 1;
+
+		var width = image.width;
+		var height = image.height;
+
+		var canvas = document.createElement( 'canvas' );
+		canvas.width = width;
+		canvas.height = height;
+
+		var context = canvas.getContext( '2d' );
+		context.drawImage( image, 0, 0 );
+
+		var data = context.getImageData( 0, 0, width, height ).data;
+		var imageData = context.createImageData( width, height );
+		var output = imageData.data;
+
+		for ( var x = 0; x < width; x ++ ) {
+
+			for ( var y = 0; y < height; y ++ ) {
+
+				var ly = y - 1 < 0 ? 0 : y - 1;
+				var uy = y + 1 > height - 1 ? height - 1 : y + 1;
+				var lx = x - 1 < 0 ? 0 : x - 1;
+				var ux = x + 1 > width - 1 ? width - 1 : x + 1;
+
+				var points = [];
+				var origin = [ 0, 0, data[ ( y * width + x ) * 4 ] / 255 * depth ];
+				points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] );
+				points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] );
+				points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] );
+				points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] );
+				points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] );
+				points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] );
+				points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] );
+				points.push( [ - 1, 1, data[ ( uy * width + lx ) * 4 ] / 255 * depth ] );
+
+				var normals = [];
+				var num_points = points.length;
+
+				for ( var i = 0; i < num_points; i ++ ) {
+
+					var v1 = points[ i ];
+					var v2 = points[ ( i + 1 ) % num_points ];
+					v1 = subtract( v1, origin );
+					v2 = subtract( v2, origin );
+					normals.push( normalize( cross( v1, v2 ) ) );
+
+				}
+
+				var normal = [ 0, 0, 0 ];
+
+				for ( var i = 0; i < normals.length; i ++ ) {
+
+					normal[ 0 ] += normals[ i ][ 0 ];
+					normal[ 1 ] += normals[ i ][ 1 ];
+					normal[ 2 ] += normals[ i ][ 2 ];
+
+				}
+
+				normal[ 0 ] /= normals.length;
+				normal[ 1 ] /= normals.length;
+				normal[ 2 ] /= normals.length;
+
+				var idx = ( y * width + x ) * 4;
+
+				output[ idx ] = ( ( normal[ 0 ] + 1.0 ) / 2.0 * 255 ) | 0;
+				output[ idx + 1 ] = ( ( normal[ 1 ] + 1.0 ) / 2.0 * 255 ) | 0;
+				output[ idx + 2 ] = ( normal[ 2 ] * 255 ) | 0;
+				output[ idx + 3 ] = 255;
+
+			}
+
+		}
+
+		context.putImageData( imageData, 0, 0 );
+
+		return canvas;
+
+	},
+
+	generateDataTexture: function ( width, height, color ) {
+
+		var size = width * height;
+		var data = new Uint8Array( 3 * size );
+
+		var r = Math.floor( color.r * 255 );
+		var g = Math.floor( color.g * 255 );
+		var b = Math.floor( color.b * 255 );
+
+		for ( var i = 0; i < size; i ++ ) {
+
+			data[ i * 3 ] 	   = r;
+			data[ i * 3 + 1 ] = g;
+			data[ i * 3 + 2 ] = b;
+
+		}
+
+		var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
+		texture.needsUpdate = true;
+
+		return texture;
+
+	}
+
+};

+ 3 - 0
examples/webgl_camera_logarithmicdepthbuffer.html

@@ -91,6 +91,9 @@
 
 		<script src="../build/three.min.js"></script>
 		<script src="js/libs/stats.min.js"></script>
+
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 		<script src="fonts/helvetiker_regular.typeface.js"></script>
 
 		<script>

+ 2 - 0
examples/webgl_custom_attributes_lines.html

@@ -36,6 +36,8 @@
 
 		<script src="../build/three.min.js"></script>
 
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 		<script src="fonts/helvetiker_bold.typeface.js"></script>
 
 		<script type="x-shader/x-vertex" id="vertexshader">

+ 9 - 7
examples/webgl_geometry_normals.html

@@ -18,6 +18,9 @@
 		<script src="../build/three.min.js"></script>
 		<script src="js/controls/OrbitControls.js"></script>
 		<script src="js/libs/stats.min.js"></script>
+
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 		<script src="fonts/helvetiker_regular.typeface.js"></script>
 
 		<script>
@@ -141,15 +144,15 @@
 				}
 
 				dropdown += '</select>';
-			
+
 				var text =
 					'Drag to spin THREE.' + params.type +
 				 	'<br>' +
 					'<br>Geometry: ' + dropdown + ' <a href="#" onclick="nextGeometry();return false;">next</a>';
 
 				text +=
-					'<br><br><font color="3333FF">Blue Arrows: Face Normals</font>' + 
-					'<br><font color="FF3333">Red Arrows: Vertex Normals before Geometry.mergeVertices</font>' + 
+					'<br><br><font color="3333FF">Blue Arrows: Face Normals</font>' +
+					'<br><font color="FF3333">Red Arrows: Vertex Normals before Geometry.mergeVertices</font>' +
 					'<br>Black Arrows: Vertex Normals after Geometry.mergeVertices';
 
 				info.innerHTML = text;
@@ -231,7 +234,7 @@
 						.add( geometry.vertices[ face.c ] )
 						.divideScalar( 3 );
 
-					var arrow = new THREE.ArrowHelper( 
+					var arrow = new THREE.ArrowHelper(
 							face.normal,
 							centroid,
 							normalLength,
@@ -245,7 +248,7 @@
 						continue;
 					}
 					for( var v = 0, vl = face.vertexNormals.length; v < vl; v ++ ) {
-						var arrow = new THREE.ArrowHelper( 
+						var arrow = new THREE.ArrowHelper(
 								face.vertexNormals[ v ],
 								originalGeometry.vertices[ face[ fvNames[ v ] ] ],
 								normalLength,
@@ -260,7 +263,7 @@
 						continue;
 					}
 					for( var v = 0, vl = face.vertexNormals.length; v < vl; v ++ ) {
-						var arrow = new THREE.ArrowHelper( 
+						var arrow = new THREE.ArrowHelper(
 								face.vertexNormals[ v ],
 								mesh.geometry.vertices[ face[ fvNames[ v ] ] ],
 								normalLength,
@@ -346,4 +349,3 @@
 
 	</body>
 </html>
-

+ 3 - 2
examples/webgl_geometry_spline_editor.html

@@ -66,7 +66,7 @@
 				camera.position.z = 1000;
 				scene.add( camera );
 
-				scene.add( new THREE.AmbientLight( 0xcccccc ) );
+				scene.add( new THREE.AmbientLight( 0xf0f0f0 ) );
 				var light = new THREE.SpotLight( 0xffffff, 1.5 );
 				light.position.set( 0, 1500, 200 );
 				light.castShadow = true;
@@ -74,6 +74,7 @@
 				light.shadowCameraFar = camera.far;
 				light.shadowCameraFov = 70;
 				light.shadowBias = -0.000222;
+				light.shadowDarkness = 0.25;
 				light.shadowMapWidth = 1024;
 				light.shadowMapHeight = 1024;
 				scene.add( light );
@@ -81,7 +82,7 @@
 
 				var planeGeometry = new THREE.PlaneGeometry( 2000, 2000 );
 				planeGeometry.rotateX( - Math.PI / 2 );
-				var planeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff } );
+				var planeMaterial = new THREE.MeshBasicMaterial( { color: 0xeeeeee } );
 
 				var plane = new THREE.Mesh( planeGeometry, planeMaterial );
 				plane.position.y = -200;

+ 2 - 2
examples/webgl_geometry_text.html

@@ -55,7 +55,8 @@
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
-		<!-- load the font files -->
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 
 		<script src="fonts/gentilis_bold.typeface.js"></script>
 		<script src="fonts/gentilis_regular.typeface.js"></script>
@@ -67,7 +68,6 @@
 		<script src="fonts/droid/droid_sans_bold.typeface.js"></script>
 		<script src="fonts/droid/droid_serif_regular.typeface.js"></script>
 		<script src="fonts/droid/droid_serif_bold.typeface.js"></script>
-		<!-- todo async loader for fonts -->
 
 		<script>
 

+ 2 - 4
examples/webgl_geometry_text2.html

@@ -56,7 +56,8 @@
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
-		<!-- load the font files -->
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 
 		<script src="fonts/gentilis_bold.typeface.js"></script>
 		<script src="fonts/gentilis_regular.typeface.js"></script>
@@ -69,9 +70,6 @@
 		<script src="fonts/droid/droid_serif_regular.typeface.js"></script>
 		<script src="fonts/droid/droid_serif_bold.typeface.js"></script>
 
-		<!-- todo async loader for fonts -->
-
-
 		<!-- replace built-in triangulation with PnlTri.js -->
 		<script src="js/libs/pnltri.min.js"></script>
 		<script>

+ 1 - 3
examples/webgl_materials_bumpmap.html

@@ -97,12 +97,10 @@
 
 				spotLight = new THREE.SpotLight( 0xffffbb, 2 );
 				spotLight.position.set( 0.5, 0, 1 );
-				scene.add( spotLight );
-
 				spotLight.position.multiplyScalar( 700 );
+				scene.add( spotLight );
 
 				spotLight.castShadow = true;
-				spotLight.onlyShadow = true;
 				// spotLight.shadowCameraVisible = true;
 
 				spotLight.shadowMapWidth = 2048;

+ 1 - 1
examples/webgl_materials_bumpmap_skin.html

@@ -108,7 +108,7 @@
 				scene.add( new THREE.AmbientLight( 0x333344 ) );
 
 				directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
-				directionalLight.position.set( 500, - 250, 500 );
+				directionalLight.position.set( 500, 0, 500 );
 
 				directionalLight.castShadow = true;
 				//directionalLight.shadowCameraVisible = true;

+ 6 - 5
examples/webgl_materials_lightmap.html

@@ -99,10 +99,11 @@
 
 				// LIGHTS
 
-				var hemiLight = new THREE.HemisphereLight( 0xaabbff, 0x040404, 0.3 );
-
-				hemiLight.position.y = 500;
-				scene.add( hemiLight );
+				var light = new THREE.DirectionalLight( 0xaabbff, 0.3 );
+				light.position.x = 300;
+				light.position.y = 250;
+				light.position.z = -500;
+				scene.add( light );
 
 				// SKYDOME
 
@@ -114,7 +115,7 @@
 					offset:		 { type: "f", value: 400 },
 					exponent:	 { type: "f", value: 0.6 }
 				};
-				uniforms.topColor.value.copy( hemiLight.color );
+				uniforms.topColor.value.copy( light.color );
 
 				var skyGeo = new THREE.SphereGeometry( 4000, 32, 15 );
 				var skyMat = new THREE.ShaderMaterial( {

+ 2 - 0
examples/webgl_modifier_subdivision.html

@@ -20,6 +20,8 @@
 		<script src="js/modifiers/SubdivisionModifier.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 		<script src="fonts/helvetiker_regular.typeface.js"></script>
 
 		<script>

+ 2 - 0
examples/webgl_modifier_tessellation.html

@@ -47,6 +47,8 @@
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 		<script src="fonts/helvetiker_bold.typeface.js"></script>
 
 		<script type="x-shader/x-vertex" id="vertexshader">

+ 83 - 85
examples/webgl_octree.html

@@ -19,12 +19,12 @@
 		<script type="text/javascript" src="js/Octree.js"></script>
 		<script>
 
-			var camera, 
-				scene, 
+			var camera,
+				scene,
 				renderer,
 				octree,
-				geometry, 
-				material, 
+				geometry,
+				material,
 				mesh,
 				meshes = [],
 				meshesSearch = [],
@@ -34,8 +34,8 @@
 				radiusMaxHalf = radiusMax * 0.5,
 				radiusSearch = 400,
 				searchMesh,
-				baseR = 255, baseG = 0, baseB = 255,
-				foundR = 0, foundG = 255, foundB = 0,
+				base = new THREE.Color( 0xff00ff ),
+				found = new THREE.Color( 0x00ff00 ),
 				adding = true,
 				rayCaster = new THREE.Raycaster(),
 				origin = new THREE.Vector3(),
@@ -45,7 +45,7 @@
 			animate();
 
 			function init() {
-			
+
 				// standard three scene, camera, renderer
 
 				scene = new THREE.Scene();
@@ -58,9 +58,9 @@
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
-			
+
 				// create octree
-				
+
 				octree = new THREE.Octree( {
 					// when undeferred = true, objects are inserted immediately
 					// instead of being deferred until next octree.update() call
@@ -76,17 +76,17 @@
 					// pass the scene to visualize the octree
 					scene: scene
 				} );
-			
+
 				// create object to show search radius and add to scene
-			
+
 				searchMesh = new THREE.Mesh(
 					new THREE.SphereGeometry( radiusSearch ),
 					new THREE.MeshBasicMaterial( { color: 0x00FF00, transparent: true, opacity: 0.4 } )
 				);
 				scene.add( searchMesh );
-				
+
 				// info
-				
+
 				var info = document.createElement( 'div' );
 				info.style.position = 'absolute';
 				info.style.top = '0';
@@ -103,168 +103,166 @@
 
 				// note: three.js includes requestAnimationFrame shim
 				requestAnimationFrame( animate );
-			
+
 				// modify octree structure by adding/removing objects
-			
+
 				modifyOctree();
-			
+
 				// search octree at random location
-			
+
 				searchOctree();
-			
+
 				// render results
-			
+
 				render();
-				
+
 				// update octree to add deferred objects
-				
+
 				octree.update();
 
 			}
-		
+
+			var geometry = new THREE.BoxGeometry( 50, 50, 50 );
+
 			function modifyOctree() {
-			
+
 				// if is adding objects to octree
-			
+
 				if ( adding === true ) {
-				
+
 					// create new object
-				
-					geometry = new THREE.BoxGeometry( 50, 50, 50 );
-					material = new THREE.MeshBasicMaterial();
-					material.color.setRGB( baseR, baseG, baseB );
-				
-					mesh = new THREE.Mesh( geometry, material );
-				
+
+					mesh = new THREE.Line( geometry, new THREE.MeshBasicMaterial( { color: new THREE.Color( base ) } ) );
+
 					// give new object a random position in radius
-				
+
 					mesh.position.set(
 						Math.random() * radiusMax - radiusMaxHalf,
 						Math.random() * radiusMax - radiusMaxHalf,
 						Math.random() * radiusMax - radiusMaxHalf
 					);
-				
+
 					// add new object to octree and scene
-				
+
 					octree.add( mesh );
 					scene.add( mesh );
-				
+
 					// store object for later
-				
+
 					meshes.push( mesh );
-				
+
 					// if at max, stop adding
-				
+
 					if ( meshes.length === meshCountMax ) {
-					
+
 						adding = false;
-					
+
 					}
-				
+
 				}
 				// else remove objects from octree
 				else {
-				
+
 					// get object
-				
+
 					mesh = meshes.shift();
-				
+
 					// remove from scene and octree
-				
+
 					scene.remove( mesh );
 					octree.remove( mesh );
-				
+
 					// if no more objects, start adding
-				
+
 					if ( meshes.length === 0 ) {
-					
+
 						adding = true;
-					
+
 					}
-				
+
 				}
-			
+
 				/*
-			
+
 				// octree details to console
-			
+
 				console.log( ' OCTREE: ', octree );
 				console.log( ' ... depth ', octree.depth, ' vs depth end?', octree.depth_end() );
 				console.log( ' ... num nodes: ', octree.node_count_end() );
 				console.log( ' ... total objects: ', octree.object_count_end(), ' vs tree objects length: ', octree.objects.length );
-			
+
 				// print full octree structure to console
-			
+
 				octree.to_console();
-			
+
 				*/
-			
+
 			}
-		
+
 			function searchOctree() {
-			
+
 				var i, il;
-			
+
 				// revert previous search objects to base color
-			
+
 				for ( i = 0, il = meshesSearch.length; i < il; i++ ) {
-				
-					meshesSearch[ i ].object.material.color.setRGB( baseR, baseG, baseB );
-				
+
+					meshesSearch[ i ].object.material.color.copy( base );
+
 				}
-			
+
 				// new search position
 				searchMesh.position.set(
 					Math.random() * radiusMax - radiusMaxHalf,
 					Math.random() * radiusMax - radiusMaxHalf,
 					Math.random() * radiusMax - radiusMaxHalf
 				);
-			
+
 				// record start time
-			
+
 				var timeStart = Date.now();
-			
+
 				// search octree from search mesh position with search radius
 				// optional third parameter: boolean, if should sort results by object when using faces in octree
 				// optional fourth parameter: vector3, direction of search when using ray (assumes radius is distance/far of ray)
-			
+
 				origin.copy( searchMesh.position );
 				direction.set( Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1 ).normalize();
 				rayCaster.set( origin, direction );
 				meshesSearch = octree.search( rayCaster.ray.origin, radiusSearch, true, rayCaster.ray.direction );
 				var intersections = rayCaster.intersectOctreeObjects( meshesSearch );
-			
+
 				// record end time
-			
+
 				var timeEnd = Date.now();
-			
+
 				// set color of all meshes found in search
-			
+
 				for ( i = 0, il = meshesSearch.length; i < il; i++ ) {
-				
-					meshesSearch[ i ].object.material.color.setRGB( foundR, foundG, foundB );
-				
+
+					meshesSearch[ i ].object.material.color.copy( found );
+
 				}
-			
+
 				/*
-			
+
 				// results to console
-			
+
 				console.log( 'OCTREE: ', octree );
 				console.log( '... searched ', meshes.length, ' and found ', meshesSearch.length, ' with intersections ', intersections.length, ' and took ', ( timeEnd - timeStart ), ' ms ' );
-			
+
 				*/
-			
+
 			}
-		
+
 			function render() {
-	
+
 				var timer = - Date.now() / 5000;
 
 				camera.position.x = Math.cos( timer ) * 10000;
 				camera.position.z = Math.sin( timer ) * 10000;
 				camera.lookAt( scene.position );
-		
+
 				renderer.render( scene, camera );
 
 			}

+ 2 - 2
examples/webgl_shaders_vector.html

@@ -29,8 +29,8 @@
 
 		<script src="js/libs/stats.min.js"></script>
 
-		<!-- load the font file from canvas-text -->
-
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 		<script src="fonts/helvetiker_regular.typeface.js"></script>
 
 		<script type="x-shader/x-fragment" id="fs">

+ 2 - 0
examples/webgl_shadowmap.html

@@ -41,6 +41,8 @@
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 		<script src="fonts/helvetiker_bold.typeface.js"></script>
 
 		<script>

+ 2 - 0
examples/webgl_shadowmap_performance.html

@@ -40,6 +40,8 @@
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 
+		<script src="js/geometries/TextGeometry.js"></script>
+		<script src="js/utils/FontUtils.js"></script>
 		<script src="fonts/helvetiker_bold.typeface.js"></script>
 
 		<script>

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "three.js",
-  "version": "0.72.0",
+  "version": "0.73.0",
   "description": "JavaScript 3D library",
   "main": "build/three.js",
   "directories": {

+ 11 - 1
src/Three.js

@@ -2,7 +2,7 @@
  * @author mrdoob / http://mrdoob.com/
  */
 
-var THREE = { REVISION: '73dev' };
+var THREE = { REVISION: '73' };
 
 //
 
@@ -90,6 +90,16 @@ if ( self.performance.now === undefined ) {
 
 }
 
+//
+
+if ( Number.EPSILON === undefined ) {
+
+	Number.EPSILON = Math.pow( 2, -52 );
+
+}
+
+//
+
 if ( Math.sign === undefined ) {
 
 	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign

+ 1 - 1
src/animation/KeyframeTrack.js

@@ -163,7 +163,7 @@ THREE.KeyframeTrack.prototype = {
 				return;
 			}
 
-			if ( ( typeof currKey.time ) !== 'number' || Number.isNaN( currKey.time ) ) {
+			if ( ( typeof currKey.time ) !== 'number' || isNaN( currKey.time ) ) {
 				console.error( "  key.time is not a valid number", this, i, currKey );
 				return;
 			}

+ 39 - 0
src/core/Channels.js

@@ -0,0 +1,39 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.Channels = function () {
+
+	this.mask = 1;
+
+};
+
+THREE.Channels.prototype = {
+
+	constructor: THREE.Channels,
+
+	set: function ( channel ) {
+
+		this.mask = 1 << channel;
+
+	},
+
+	enable: function ( channel ) {
+
+		this.mask |= 1 << channel;
+
+	},
+
+	toggle: function ( channel ) {
+
+		this.mask ^= 1 << channel;
+
+	},
+
+	disable: function ( channel ) {
+
+		this.mask &= ~ ( 1 << channel );
+
+	}
+
+};

+ 1 - 0
src/core/Object3D.js

@@ -16,6 +16,7 @@ THREE.Object3D = function () {
 	this.type = 'Object3D';
 
 	this.parent = null;
+	this.channels = new THREE.Channels();
 	this.children = [];
 
 	this.up = THREE.Object3D.DefaultUp.clone();

+ 49 - 0
src/extras/CurveUtils.js

@@ -0,0 +1,49 @@
+/**
+ * @author zz85 / http://www.lab4games.net/zz85/blog
+ */
+
+THREE.CurveUtils = {
+
+	tangentQuadraticBezier: function ( t, p0, p1, p2 ) {
+
+		return 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );
+
+	},
+
+	// Puay Bing, thanks for helping with this derivative!
+
+	tangentCubicBezier: function ( t, p0, p1, p2, p3 ) {
+
+		return - 3 * p0 * ( 1 - t ) * ( 1 - t )  +
+			3 * p1 * ( 1 - t ) * ( 1 - t ) - 6 * t * p1 * ( 1 - t ) +
+			6 * t *  p2 * ( 1 - t ) - 3 * t * t * p2 +
+			3 * t * t * p3;
+
+	},
+
+	tangentSpline: function ( t, p0, p1, p2, p3 ) {
+
+		// To check if my formulas are correct
+
+		var h00 = 6 * t * t - 6 * t; 	// derived from 2t^3 − 3t^2 + 1
+		var h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t
+		var h01 = - 6 * t * t + 6 * t; 	// − 2t3 + 3t2
+		var h11 = 3 * t * t - 2 * t;	// t3 − t2
+
+		return h00 + h10 + h01 + h11;
+
+	},
+
+	// Catmull-Rom
+
+	interpolate: function( p0, p1, p2, p3, t ) {
+
+		var v0 = ( p2 - p0 ) * 0.5;
+		var v1 = ( p3 - p1 ) * 0.5;
+		var t2 = t * t;
+		var t3 = t * t2;
+		return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
+
+	}
+
+};

+ 11 - 175
src/extras/ImageUtils.js

@@ -10,66 +10,29 @@ THREE.ImageUtils = {
 
 	loadTexture: function ( url, mapping, onLoad, onError ) {
 
-		var loader = new THREE.ImageLoader();
-		loader.crossOrigin = this.crossOrigin;
+		console.warn( 'THREE.ImageUtils.loadTexture is being deprecated. Use THREE.TextureLoader() instead.' );
 
-		var texture = new THREE.Texture( undefined, mapping );
+		var loader = new THREE.TextureLoader();
+		loader.setCrossOrigin( this.crossOrigin );
 
-		loader.load( url, function ( image ) {
+		var texture = loader.load( url, onLoad, undefined, onError );
 
-			texture.image = image;
-			texture.needsUpdate = true;
-
-			if ( onLoad ) onLoad( texture );
-
-		}, undefined, function ( event ) {
-
-			if ( onError ) onError( event );
-
-		} );
-
-		texture.sourceFile = url;
+		if ( mapping ) texture.mapping = mapping;
 
 		return texture;
 
 	},
 
-	loadTextureCube: function ( array, mapping, onLoad, onError ) {
-
-		var images = [];
-
-		var loader = new THREE.ImageLoader();
-		loader.crossOrigin = this.crossOrigin;
-
-		var texture = new THREE.CubeTexture( images, mapping );
-
-		var loaded = 0;
-
-		function loadTexture( i ) {
-
-			loader.load( array[ i ], function ( image ) {
-
-				texture.images[ i ] = image;
-
-				loaded += 1;
-
-				if ( loaded === 6 ) {
-
-					texture.needsUpdate = true;
-
-					if ( onLoad ) onLoad( texture );
-
-				}
+	loadTextureCube: function ( urls, mapping, onLoad, onError ) {
 
-			}, undefined, onError );
+		console.warn( 'THREE.ImageUtils.loadTextureCube is being deprecated. Use THREE.CubeTextureLoader() instead.' );
 
-		}
+		var loader = new THREE.CubeTextureLoader();
+		loader.setCrossOrigin( this.crossOrigin );
 
-		for ( var i = 0, il = array.length; i < il; ++ i ) {
+		var texture = loader.load( urls, onLoad, undefined, onError );
 
-			loadTexture( i );
-
-		}
+		if ( mapping ) texture.mapping = mapping;
 
 		return texture;
 
@@ -85,133 +48,6 @@ THREE.ImageUtils = {
 
 		console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' )
 
-	},
-
-	getNormalMap: function ( image, depth ) {
-
-		// Adapted from http://www.paulbrunt.co.uk/lab/heightnormal/
-
-		function cross( a, b ) {
-
-			return [ a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ], a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ], a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ] ];
-
-		}
-
-		function subtract( a, b ) {
-
-			return [ a[ 0 ] - b[ 0 ], a[ 1 ] - b[ 1 ], a[ 2 ] - b[ 2 ] ];
-
-		}
-
-		function normalize( a ) {
-
-			var l = Math.sqrt( a[ 0 ] * a[ 0 ] + a[ 1 ] * a[ 1 ] + a[ 2 ] * a[ 2 ] );
-			return [ a[ 0 ] / l, a[ 1 ] / l, a[ 2 ] / l ];
-
-		}
-
-		depth = depth | 1;
-
-		var width = image.width;
-		var height = image.height;
-
-		var canvas = document.createElement( 'canvas' );
-		canvas.width = width;
-		canvas.height = height;
-
-		var context = canvas.getContext( '2d' );
-		context.drawImage( image, 0, 0 );
-
-		var data = context.getImageData( 0, 0, width, height ).data;
-		var imageData = context.createImageData( width, height );
-		var output = imageData.data;
-
-		for ( var x = 0; x < width; x ++ ) {
-
-			for ( var y = 0; y < height; y ++ ) {
-
-				var ly = y - 1 < 0 ? 0 : y - 1;
-				var uy = y + 1 > height - 1 ? height - 1 : y + 1;
-				var lx = x - 1 < 0 ? 0 : x - 1;
-				var ux = x + 1 > width - 1 ? width - 1 : x + 1;
-
-				var points = [];
-				var origin = [ 0, 0, data[ ( y * width + x ) * 4 ] / 255 * depth ];
-				points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] );
-				points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] );
-				points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] );
-				points.push( [ 1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] );
-				points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] );
-				points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] );
-				points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] );
-				points.push( [ - 1, 1, data[ ( uy * width + lx ) * 4 ] / 255 * depth ] );
-
-				var normals = [];
-				var num_points = points.length;
-
-				for ( var i = 0; i < num_points; i ++ ) {
-
-					var v1 = points[ i ];
-					var v2 = points[ ( i + 1 ) % num_points ];
-					v1 = subtract( v1, origin );
-					v2 = subtract( v2, origin );
-					normals.push( normalize( cross( v1, v2 ) ) );
-
-				}
-
-				var normal = [ 0, 0, 0 ];
-
-				for ( var i = 0; i < normals.length; i ++ ) {
-
-					normal[ 0 ] += normals[ i ][ 0 ];
-					normal[ 1 ] += normals[ i ][ 1 ];
-					normal[ 2 ] += normals[ i ][ 2 ];
-
-				}
-
-				normal[ 0 ] /= normals.length;
-				normal[ 1 ] /= normals.length;
-				normal[ 2 ] /= normals.length;
-
-				var idx = ( y * width + x ) * 4;
-
-				output[ idx ] = ( ( normal[ 0 ] + 1.0 ) / 2.0 * 255 ) | 0;
-				output[ idx + 1 ] = ( ( normal[ 1 ] + 1.0 ) / 2.0 * 255 ) | 0;
-				output[ idx + 2 ] = ( normal[ 2 ] * 255 ) | 0;
-				output[ idx + 3 ] = 255;
-
-			}
-
-		}
-
-		context.putImageData( imageData, 0, 0 );
-
-		return canvas;
-
-	},
-
-	generateDataTexture: function ( width, height, color ) {
-
-		var size = width * height;
-		var data = new Uint8Array( 3 * size );
-
-		var r = Math.floor( color.r * 255 );
-		var g = Math.floor( color.g * 255 );
-		var b = Math.floor( color.b * 255 );
-
-		for ( var i = 0; i < size; i ++ ) {
-
-			data[ i * 3 ] 	   = r;
-			data[ i * 3 + 1 ] = g;
-			data[ i * 3 + 2 ] = b;
-
-		}
-
-		var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
-		texture.needsUpdate = true;
-
-		return texture;
-
 	}
 
 };

+ 750 - 0
src/extras/ShapeUtils.js

@@ -0,0 +1,750 @@
+/**
+ * @author zz85 / http://www.lab4games.net/zz85/blog
+ */
+
+THREE.ShapeUtils = {
+
+	// calculate area of the contour polygon
+
+	area: function ( contour ) {
+
+		var n = contour.length;
+		var a = 0.0;
+
+		for ( var p = n - 1, q = 0; q < n; p = q ++ ) {
+
+			a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
+
+		}
+
+		return a * 0.5;
+
+	},
+
+	triangulate: ( function () {
+
+		/**
+		 * This code is a quick port of code written in C++ which was submitted to
+		 * flipcode.com by John W. Ratcliff  // July 22, 2000
+		 * See original code and more information here:
+		 * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
+		 *
+		 * ported to actionscript by Zevan Rosser
+		 * www.actionsnippet.com
+		 *
+		 * ported to javascript by Joshua Koo
+		 * http://www.lab4games.net/zz85/blog
+		 *
+		 */
+
+		function snip( contour, u, v, w, n, verts ) {
+
+			var p;
+			var ax, ay, bx, by;
+			var cx, cy, px, py;
+
+			ax = contour[ verts[ u ] ].x;
+			ay = contour[ verts[ u ] ].y;
+
+			bx = contour[ verts[ v ] ].x;
+			by = contour[ verts[ v ] ].y;
+
+			cx = contour[ verts[ w ] ].x;
+			cy = contour[ verts[ w ] ].y;
+
+			if ( Number.EPSILON > ( ( ( bx - ax ) * ( cy - ay ) ) - ( ( by - ay ) * ( cx - ax ) ) ) ) return false;
+
+			var aX, aY, bX, bY, cX, cY;
+			var apx, apy, bpx, bpy, cpx, cpy;
+			var cCROSSap, bCROSScp, aCROSSbp;
+
+			aX = cx - bx;  aY = cy - by;
+			bX = ax - cx;  bY = ay - cy;
+			cX = bx - ax;  cY = by - ay;
+
+			for ( p = 0; p < n; p ++ ) {
+
+				px = contour[ verts[ p ] ].x;
+				py = contour[ verts[ p ] ].y;
+
+				if ( ( ( px === ax ) && ( py === ay ) ) ||
+					 ( ( px === bx ) && ( py === by ) ) ||
+					 ( ( px === cx ) && ( py === cy ) ) )	continue;
+
+				apx = px - ax;  apy = py - ay;
+				bpx = px - bx;  bpy = py - by;
+				cpx = px - cx;  cpy = py - cy;
+
+				// see if p is inside triangle abc
+
+				aCROSSbp = aX * bpy - aY * bpx;
+				cCROSSap = cX * apy - cY * apx;
+				bCROSScp = bX * cpy - bY * cpx;
+
+				if ( ( aCROSSbp >= - Number.EPSILON ) && ( bCROSScp >= - Number.EPSILON ) && ( cCROSSap >= - Number.EPSILON ) ) return false;
+
+			}
+
+			return true;
+
+		}
+
+		// takes in an contour array and returns
+
+		return function ( contour, indices ) {
+
+			var n = contour.length;
+
+			if ( n < 3 ) return null;
+
+			var result = [],
+				verts = [],
+				vertIndices = [];
+
+			/* we want a counter-clockwise polygon in verts */
+
+			var u, v, w;
+
+			if ( THREE.ShapeUtils.area( contour ) > 0.0 ) {
+
+				for ( v = 0; v < n; v ++ ) verts[ v ] = v;
+
+			} else {
+
+				for ( v = 0; v < n; v ++ ) verts[ v ] = ( n - 1 ) - v;
+
+			}
+
+			var nv = n;
+
+			/*  remove nv - 2 vertices, creating 1 triangle every time */
+
+			var count = 2 * nv;   /* error detection */
+
+			for ( v = nv - 1; nv > 2; ) {
+
+				/* if we loop, it is probably a non-simple polygon */
+
+				if ( ( count -- ) <= 0 ) {
+
+					//** Triangulate: ERROR - probable bad polygon!
+
+					//throw ( "Warning, unable to triangulate polygon!" );
+					//return null;
+					// Sometimes warning is fine, especially polygons are triangulated in reverse.
+					console.warn( 'THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()' );
+
+					if ( indices ) return vertIndices;
+					return result;
+
+				}
+
+				/* three consecutive vertices in current polygon, <u,v,w> */
+
+				u = v; 	 	if ( nv <= u ) u = 0;     /* previous */
+				v = u + 1;  if ( nv <= v ) v = 0;     /* new v    */
+				w = v + 1;  if ( nv <= w ) w = 0;     /* next     */
+
+				if ( snip( contour, u, v, w, nv, verts ) ) {
+
+					var a, b, c, s, t;
+
+					/* true names of the vertices */
+
+					a = verts[ u ];
+					b = verts[ v ];
+					c = verts[ w ];
+
+					/* output Triangle */
+
+					result.push( [ contour[ a ],
+						contour[ b ],
+						contour[ c ] ] );
+
+
+					vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );
+
+					/* remove v from the remaining polygon */
+
+					for ( s = v, t = v + 1; t < nv; s ++, t ++ ) {
+
+						verts[ s ] = verts[ t ];
+
+					}
+
+					nv --;
+
+					/* reset error detection counter */
+
+					count = 2 * nv;
+
+				}
+
+			}
+
+			if ( indices ) return vertIndices;
+			return result;
+
+		}
+
+	} )(),
+
+	triangulateShape: function ( contour, holes ) {
+
+		function point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {
+
+			// inOtherPt needs to be collinear to the inSegment
+			if ( inSegPt1.x !== inSegPt2.x ) {
+
+				if ( inSegPt1.x < inSegPt2.x ) {
+
+					return	( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );
+
+				} else {
+
+					return	( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );
+
+				}
+
+			} else {
+
+				if ( inSegPt1.y < inSegPt2.y ) {
+
+					return	( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );
+
+				} else {
+
+					return	( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );
+
+				}
+
+			}
+
+		}
+
+		function intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {
+
+			var seg1dx = inSeg1Pt2.x - inSeg1Pt1.x,   seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;
+			var seg2dx = inSeg2Pt2.x - inSeg2Pt1.x,   seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;
+
+			var seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;
+			var seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;
+
+			var limit		= seg1dy * seg2dx - seg1dx * seg2dy;
+			var perpSeg1	= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;
+
+			if ( Math.abs( limit ) > Number.EPSILON ) {
+
+				// not parallel
+
+				var perpSeg2;
+				if ( limit > 0 ) {
+
+					if ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) 		return [];
+					perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;
+					if ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) 		return [];
+
+				} else {
+
+					if ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) 		return [];
+					perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;
+					if ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) 		return [];
+
+				}
+
+				// i.e. to reduce rounding errors
+				// intersection at endpoint of segment#1?
+				if ( perpSeg2 === 0 ) {
+
+					if ( ( inExcludeAdjacentSegs ) &&
+						 ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )		return [];
+					return [ inSeg1Pt1 ];
+
+				}
+				if ( perpSeg2 === limit ) {
+
+					if ( ( inExcludeAdjacentSegs ) &&
+						 ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )		return [];
+					return [ inSeg1Pt2 ];
+
+				}
+				// intersection at endpoint of segment#2?
+				if ( perpSeg1 === 0 )		return [ inSeg2Pt1 ];
+				if ( perpSeg1 === limit )	return [ inSeg2Pt2 ];
+
+				// return real intersection point
+				var factorSeg1 = perpSeg2 / limit;
+				return	[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,
+							y: inSeg1Pt1.y + factorSeg1 * seg1dy } ];
+
+			} else {
+
+				// parallel or collinear
+				if ( ( perpSeg1 !== 0 ) ||
+					 ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) 			return [];
+
+				// they are collinear or degenerate
+				var seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );	// segment1 is just a point?
+				var seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );	// segment2 is just a point?
+				// both segments are points
+				if ( seg1Pt && seg2Pt ) {
+
+					if ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||
+						 ( inSeg1Pt1.y !== inSeg2Pt1.y ) )		return [];	// they are distinct  points
+					return [ inSeg1Pt1 ];                 						// they are the same point
+
+				}
+				// segment#1  is a single point
+				if ( seg1Pt ) {
+
+					if ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )		return [];		// but not in segment#2
+					return [ inSeg1Pt1 ];
+
+				}
+				// segment#2  is a single point
+				if ( seg2Pt ) {
+
+					if ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )		return [];		// but not in segment#1
+					return [ inSeg2Pt1 ];
+
+				}
+
+				// they are collinear segments, which might overlap
+				var seg1min, seg1max, seg1minVal, seg1maxVal;
+				var seg2min, seg2max, seg2minVal, seg2maxVal;
+				if ( seg1dx !== 0 ) {
+
+					// the segments are NOT on a vertical line
+					if ( inSeg1Pt1.x < inSeg1Pt2.x ) {
+
+						seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;
+						seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;
+
+					} else {
+
+						seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;
+						seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;
+
+					}
+					if ( inSeg2Pt1.x < inSeg2Pt2.x ) {
+
+						seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;
+						seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;
+
+					} else {
+
+						seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;
+						seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;
+
+					}
+
+				} else {
+
+					// the segments are on a vertical line
+					if ( inSeg1Pt1.y < inSeg1Pt2.y ) {
+
+						seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;
+						seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;
+
+					} else {
+
+						seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;
+						seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;
+
+					}
+					if ( inSeg2Pt1.y < inSeg2Pt2.y ) {
+
+						seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;
+						seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;
+
+					} else {
+
+						seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;
+						seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;
+
+					}
+
+				}
+				if ( seg1minVal <= seg2minVal ) {
+
+					if ( seg1maxVal <  seg2minVal )	return [];
+					if ( seg1maxVal === seg2minVal )	{
+
+						if ( inExcludeAdjacentSegs )		return [];
+						return [ seg2min ];
+
+					}
+					if ( seg1maxVal <= seg2maxVal )	return [ seg2min, seg1max ];
+					return	[ seg2min, seg2max ];
+
+				} else {
+
+					if ( seg1minVal >  seg2maxVal )	return [];
+					if ( seg1minVal === seg2maxVal )	{
+
+						if ( inExcludeAdjacentSegs )		return [];
+						return [ seg1min ];
+
+					}
+					if ( seg1maxVal <= seg2maxVal )	return [ seg1min, seg1max ];
+					return	[ seg1min, seg2max ];
+
+				}
+
+			}
+
+		}
+
+		function isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {
+
+			// The order of legs is important
+
+			// translation of all points, so that Vertex is at (0,0)
+			var legFromPtX	= inLegFromPt.x - inVertex.x,  legFromPtY	= inLegFromPt.y - inVertex.y;
+			var legToPtX	= inLegToPt.x	- inVertex.x,  legToPtY		= inLegToPt.y	- inVertex.y;
+			var otherPtX	= inOtherPt.x	- inVertex.x,  otherPtY		= inOtherPt.y	- inVertex.y;
+
+			// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.
+			var from2toAngle	= legFromPtX * legToPtY - legFromPtY * legToPtX;
+			var from2otherAngle	= legFromPtX * otherPtY - legFromPtY * otherPtX;
+
+			if ( Math.abs( from2toAngle ) > Number.EPSILON ) {
+
+				// angle != 180 deg.
+
+				var other2toAngle		= otherPtX * legToPtY - otherPtY * legToPtX;
+				// console.log( "from2to: " + from2toAngle + ", from2other: " + from2otherAngle + ", other2to: " + other2toAngle );
+
+				if ( from2toAngle > 0 ) {
+
+					// main angle < 180 deg.
+					return	( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );
+
+				} else {
+
+					// main angle > 180 deg.
+					return	( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );
+
+				}
+
+			} else {
+
+				// angle == 180 deg.
+				// console.log( "from2to: 180 deg., from2other: " + from2otherAngle  );
+				return	( from2otherAngle > 0 );
+
+			}
+
+		}
+
+
+		function removeHoles( contour, holes ) {
+
+			var shape = contour.concat(); // work on this shape
+			var hole;
+
+			function isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {
+
+				// Check if hole point lies within angle around shape point
+				var lastShapeIdx = shape.length - 1;
+
+				var prevShapeIdx = inShapeIdx - 1;
+				if ( prevShapeIdx < 0 )			prevShapeIdx = lastShapeIdx;
+
+				var nextShapeIdx = inShapeIdx + 1;
+				if ( nextShapeIdx > lastShapeIdx )	nextShapeIdx = 0;
+
+				var insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );
+				if ( ! insideAngle ) {
+
+					// console.log( "Vertex (Shape): " + inShapeIdx + ", Point: " + hole[inHoleIdx].x + "/" + hole[inHoleIdx].y );
+					return	false;
+
+				}
+
+				// Check if shape point lies within angle around hole point
+				var lastHoleIdx = hole.length - 1;
+
+				var prevHoleIdx = inHoleIdx - 1;
+				if ( prevHoleIdx < 0 )			prevHoleIdx = lastHoleIdx;
+
+				var nextHoleIdx = inHoleIdx + 1;
+				if ( nextHoleIdx > lastHoleIdx )	nextHoleIdx = 0;
+
+				insideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );
+				if ( ! insideAngle ) {
+
+					// console.log( "Vertex (Hole): " + inHoleIdx + ", Point: " + shape[inShapeIdx].x + "/" + shape[inShapeIdx].y );
+					return	false;
+
+				}
+
+				return	true;
+
+			}
+
+			function intersectsShapeEdge( inShapePt, inHolePt ) {
+
+				// checks for intersections with shape edges
+				var sIdx, nextIdx, intersection;
+				for ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {
+
+					nextIdx = sIdx + 1; nextIdx %= shape.length;
+					intersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );
+					if ( intersection.length > 0 )		return	true;
+
+				}
+
+				return	false;
+
+			}
+
+			var indepHoles = [];
+
+			function intersectsHoleEdge( inShapePt, inHolePt ) {
+
+				// checks for intersections with hole edges
+				var ihIdx, chkHole,
+					hIdx, nextIdx, intersection;
+				for ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {
+
+					chkHole = holes[ indepHoles[ ihIdx ]];
+					for ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {
+
+						nextIdx = hIdx + 1; nextIdx %= chkHole.length;
+						intersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );
+						if ( intersection.length > 0 )		return	true;
+
+					}
+
+				}
+				return	false;
+
+			}
+
+			var holeIndex, shapeIndex,
+				shapePt, holePt,
+				holeIdx, cutKey, failedCuts = [],
+				tmpShape1, tmpShape2,
+				tmpHole1, tmpHole2;
+
+			for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
+
+				indepHoles.push( h );
+
+			}
+
+			var minShapeIndex = 0;
+			var counter = indepHoles.length * 2;
+			while ( indepHoles.length > 0 ) {
+
+				counter --;
+				if ( counter < 0 ) {
+
+					console.log( "Infinite Loop! Holes left:" + indepHoles.length + ", Probably Hole outside Shape!" );
+					break;
+
+				}
+
+				// search for shape-vertex and hole-vertex,
+				// which can be connected without intersections
+				for ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {
+
+					shapePt = shape[ shapeIndex ];
+					holeIndex	= - 1;
+
+					// search for hole which can be reached without intersections
+					for ( var h = 0; h < indepHoles.length; h ++ ) {
+
+						holeIdx = indepHoles[ h ];
+
+						// prevent multiple checks
+						cutKey = shapePt.x + ":" + shapePt.y + ":" + holeIdx;
+						if ( failedCuts[ cutKey ] !== undefined )			continue;
+
+						hole = holes[ holeIdx ];
+						for ( var h2 = 0; h2 < hole.length; h2 ++ ) {
+
+							holePt = hole[ h2 ];
+							if ( ! isCutLineInsideAngles( shapeIndex, h2 ) )		continue;
+							if ( intersectsShapeEdge( shapePt, holePt ) )		continue;
+							if ( intersectsHoleEdge( shapePt, holePt ) )		continue;
+
+							holeIndex = h2;
+							indepHoles.splice( h, 1 );
+
+							tmpShape1 = shape.slice( 0, shapeIndex + 1 );
+							tmpShape2 = shape.slice( shapeIndex );
+							tmpHole1 = hole.slice( holeIndex );
+							tmpHole2 = hole.slice( 0, holeIndex + 1 );
+
+							shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );
+
+							minShapeIndex = shapeIndex;
+
+							// Debug only, to show the selected cuts
+							// glob_CutLines.push( [ shapePt, holePt ] );
+
+							break;
+
+						}
+						if ( holeIndex >= 0 )	break;		// hole-vertex found
+
+						failedCuts[ cutKey ] = true;			// remember failure
+
+					}
+					if ( holeIndex >= 0 )	break;		// hole-vertex found
+
+				}
+
+			}
+
+			return shape; 			/* shape with no holes */
+
+		}
+
+
+		var i, il, f, face,
+			key, index,
+			allPointsMap = {};
+
+		// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.
+
+		var allpoints = contour.concat();
+
+		for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
+
+			Array.prototype.push.apply( allpoints, holes[ h ] );
+
+		}
+
+		//console.log( "allpoints",allpoints, allpoints.length );
+
+		// prepare all points map
+
+		for ( i = 0, il = allpoints.length; i < il; i ++ ) {
+
+			key = allpoints[ i ].x + ":" + allpoints[ i ].y;
+
+			if ( allPointsMap[ key ] !== undefined ) {
+
+				console.warn( "THREE.Shape: Duplicate point", key );
+
+			}
+
+			allPointsMap[ key ] = i;
+
+		}
+
+		// remove holes by cutting paths to holes and adding them to the shape
+		var shapeWithoutHoles = removeHoles( contour, holes );
+
+		var triangles = THREE.ShapeUtils.triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape
+		//console.log( "triangles",triangles, triangles.length );
+
+		// check all face vertices against all points map
+
+		for ( i = 0, il = triangles.length; i < il; i ++ ) {
+
+			face = triangles[ i ];
+
+			for ( f = 0; f < 3; f ++ ) {
+
+				key = face[ f ].x + ":" + face[ f ].y;
+
+				index = allPointsMap[ key ];
+
+				if ( index !== undefined ) {
+
+					face[ f ] = index;
+
+				}
+
+			}
+
+		}
+
+		return triangles.concat();
+
+	},
+
+	isClockWise: function ( pts ) {
+
+		return THREE.ShapeUtils.area( pts ) < 0;
+
+	},
+
+	// Bezier Curves formulas obtained from
+	// http://en.wikipedia.org/wiki/B%C3%A9zier_curve
+
+	// Quad Bezier Functions
+
+	b2: ( function () {
+
+		function b2p0( t, p ) {
+
+			var k = 1 - t;
+			return k * k * p;
+
+		}
+
+		function b2p1( t, p ) {
+
+			return 2 * ( 1 - t ) * t * p;
+
+		}
+
+		function b2p2( t, p ) {
+
+			return t * t * p;
+
+		}
+
+		return function ( t, p0, p1, p2 ) {
+
+			return b2p0( t, p0 ) + b2p1( t, p1 ) + b2p2( t, p2 );
+
+		};
+
+	} )(),
+
+	// Cubic Bezier Functions
+
+	b3: ( function () {
+
+		function b3p0( t, p ) {
+
+			var k = 1 - t;
+			return k * k * k * p;
+
+		}
+
+		function b3p1( t, p ) {
+
+			var k = 1 - t;
+			return 3 * k * k * t * p;
+
+		}
+
+		function b3p2( t, p ) {
+
+			var k = 1 - t;
+			return 3 * k * t * t * p;
+
+		}
+
+		function b3p3( t, p ) {
+
+			return t * t * t * p;
+
+		}
+
+		return function ( t, p0, p1, p2, p3 ) {
+
+			return b3p0( t, p0 ) + b3p1( t, p1 ) + b3p2( t, p2 ) + b3p3( t, p3 );
+
+		};
+
+	} )()
+
+};

+ 1 - 50
src/extras/core/Curve.js

@@ -266,56 +266,7 @@ THREE.Curve.prototype = {
 
 }
 
-/**************************************************************
- *	Utils
- **************************************************************/
-
-THREE.Curve.Utils = {
-
-	tangentQuadraticBezier: function ( t, p0, p1, p2 ) {
-
-		return 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );
-
-	},
-
-	// Puay Bing, thanks for helping with this derivative!
-
-	tangentCubicBezier: function ( t, p0, p1, p2, p3 ) {
-
-		return - 3 * p0 * ( 1 - t ) * ( 1 - t )  +
-			3 * p1 * ( 1 - t ) * ( 1 - t ) - 6 * t * p1 * ( 1 - t ) +
-			6 * t *  p2 * ( 1 - t ) - 3 * t * t * p2 +
-			3 * t * t * p3;
-
-	},
-
-	tangentSpline: function ( t, p0, p1, p2, p3 ) {
-
-		// To check if my formulas are correct
-
-		var h00 = 6 * t * t - 6 * t; 	// derived from 2t^3 − 3t^2 + 1
-		var h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t
-		var h01 = - 6 * t * t + 6 * t; 	// − 2t3 + 3t2
-		var h11 = 3 * t * t - 2 * t;	// t3 − t2
-
-		return h00 + h10 + h01 + h11;
-
-	},
-
-	// Catmull-Rom
-
-	interpolate: function( p0, p1, p2, p3, t ) {
-
-		var v0 = ( p2 - p0 ) * 0.5;
-		var v1 = ( p3 - p1 ) * 0.5;
-		var t2 = t * t;
-		var t3 = t * t2;
-		return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
-
-	}
-
-};
-
+THREE.Curve.Utils = THREE.CurveUtils; // backwards compatibility
 
 // TODO: Transformation for Curves?
 

+ 0 - 147
src/extras/core/CurvePath.js

@@ -11,7 +11,6 @@
 THREE.CurvePath = function () {
 
 	this.curves = [];
-	this.bends = [];
 
 	this.autoClose = false; // Automatically closes the path
 
@@ -139,63 +138,6 @@ THREE.CurvePath.prototype.getCurveLengths = function() {
 
 
 
-// Returns min and max coordinates
-
-THREE.CurvePath.prototype.getBoundingBox = function () {
-
-	var points = this.getPoints();
-
-	var maxX, maxY, maxZ;
-	var minX, minY, minZ;
-
-	maxX = maxY = Number.NEGATIVE_INFINITY;
-	minX = minY = Number.POSITIVE_INFINITY;
-
-	var v3 = points[ 0 ] instanceof THREE.Vector3;
-
-	var sum = v3 ? new THREE.Vector3() : new THREE.Vector2();
-
-	for ( var i = 0, l = points.length; i < l; i ++ ) {
-
-		var p = points[ i ];
-
-		if ( p.x > maxX ) maxX = p.x;
-		else if ( p.x < minX ) minX = p.x;
-
-		if ( p.y > maxY ) maxY = p.y;
-		else if ( p.y < minY ) minY = p.y;
-
-		if ( v3 ) {
-
-			if ( p.z > maxZ ) maxZ = p.z;
-			else if ( p.z < minZ ) minZ = p.z;
-
-		}
-
-		sum.add( p );
-
-	}
-
-	var ret = {
-
-		minX: minX,
-		minY: minY,
-		maxX: maxX,
-		maxY: maxY
-
-	};
-
-	if ( v3 ) {
-
-		ret.maxZ = maxZ;
-		ret.minZ = minZ;
-
-	}
-
-	return ret;
-
-};
-
 /**************************************************************
  *	Create Geometries Helpers
  **************************************************************/
@@ -232,92 +174,3 @@ THREE.CurvePath.prototype.createGeometry = function( points ) {
 	return geometry;
 
 };
-
-
-/**************************************************************
- *	Bend / Wrap Helper Methods
- **************************************************************/
-
-// Wrap path / Bend modifiers?
-
-THREE.CurvePath.prototype.addWrapPath = function ( bendpath ) {
-
-	this.bends.push( bendpath );
-
-};
-
-THREE.CurvePath.prototype.getTransformedPoints = function( segments, bends ) {
-
-	var oldPts = this.getPoints( segments ); // getPoints getSpacedPoints
-
-	if ( ! bends ) {
-
-		bends = this.bends;
-
-	}
-
-	for ( var i = 0, l = bends.length; i < l; i ++ ) {
-
-		oldPts = this.getWrapPoints( oldPts, bends[ i ] );
-
-	}
-
-	return oldPts;
-
-};
-
-THREE.CurvePath.prototype.getTransformedSpacedPoints = function( segments, bends ) {
-
-	var oldPts = this.getSpacedPoints( segments );
-
-	if ( ! bends ) {
-
-		bends = this.bends;
-
-	}
-
-	for ( var i = 0, l = bends.length; i < l; i ++ ) {
-
-		oldPts = this.getWrapPoints( oldPts, bends[ i ] );
-
-	}
-
-	return oldPts;
-
-};
-
-// This returns getPoints() bend/wrapped around the contour of a path.
-// Read http://www.planetclegg.com/projects/WarpingTextToSplines.html
-
-THREE.CurvePath.prototype.getWrapPoints = function ( oldPts, path ) {
-
-	var bounds = this.getBoundingBox();
-
-	for ( var i = 0, l = oldPts.length; i < l; i ++ ) {
-
-		var p = oldPts[ i ];
-
-		var oldX = p.x;
-		var oldY = p.y;
-
-		var xNorm = oldX / bounds.maxX;
-
-		// If using actual distance, for length > path, requires line extrusions
-		//xNorm = path.getUtoTmapping(xNorm, oldX); // 3 styles. 1) wrap stretched. 2) wrap stretch by arc length 3) warp by actual distance
-
-		xNorm = path.getUtoTmapping( xNorm, oldX );
-
-		// check for out of bounds?
-
-		var pathPt = path.getPoint( xNorm );
-		var normal = path.getTangent( xNorm );
-		normal.set( - normal.y, normal.x ).multiplyScalar( oldY );
-
-		p.x = pathPt.x + normal.x;
-		p.y = pathPt.y + normal.y;
-
-	}
-
-	return oldPts;
-
-};

+ 28 - 49
src/extras/core/Path.js

@@ -21,16 +21,6 @@ THREE.Path = function ( points ) {
 THREE.Path.prototype = Object.create( THREE.CurvePath.prototype );
 THREE.Path.prototype.constructor = THREE.Path;
 
-THREE.PathActions = {
-	MOVE_TO: 'moveTo',
-	LINE_TO: 'lineTo',
-	QUADRATIC_CURVE_TO: 'quadraticCurveTo', // Bezier quadratic curve
-	BEZIER_CURVE_TO: 'bezierCurveTo', 		// Bezier cubic curve
-	CSPLINE_THRU: 'splineThru',				// Catmull-Rom spline
-	ARC: 'arc',								// Circle
-	ELLIPSE: 'ellipse'
-};
-
 // TODO Clean up PATH API
 
 // Create path using straight lines to connect all points
@@ -52,15 +42,12 @@ THREE.Path.prototype.fromPoints = function ( vectors ) {
 
 THREE.Path.prototype.moveTo = function ( x, y ) {
 
-	var args = Array.prototype.slice.call( arguments );
-	this.actions.push( { action: THREE.PathActions.MOVE_TO, args: args } );
+	this.actions.push( { action: 'moveTo', args: [ x, y ] } );
 
 };
 
 THREE.Path.prototype.lineTo = function ( x, y ) {
 
-	var args = Array.prototype.slice.call( arguments );
-
 	var lastargs = this.actions[ this.actions.length - 1 ].args;
 
 	var x0 = lastargs[ lastargs.length - 2 ];
@@ -69,14 +56,12 @@ THREE.Path.prototype.lineTo = function ( x, y ) {
 	var curve = new THREE.LineCurve( new THREE.Vector2( x0, y0 ), new THREE.Vector2( x, y ) );
 	this.curves.push( curve );
 
-	this.actions.push( { action: THREE.PathActions.LINE_TO, args: args } );
+	this.actions.push( { action: 'lineTo', args: [ x, y ] } );
 
 };
 
 THREE.Path.prototype.quadraticCurveTo = function( aCPx, aCPy, aX, aY ) {
 
-	var args = Array.prototype.slice.call( arguments );
-
 	var lastargs = this.actions[ this.actions.length - 1 ].args;
 
 	var x0 = lastargs[ lastargs.length - 2 ];
@@ -90,14 +75,12 @@ THREE.Path.prototype.quadraticCurveTo = function( aCPx, aCPy, aX, aY ) {
 
 	this.curves.push( curve );
 
-	this.actions.push( { action: THREE.PathActions.QUADRATIC_CURVE_TO, args: args } );
+	this.actions.push( { action: 'quadraticCurveTo', args: [ aCPx, aCPy, aX, aY ] } );
 
 };
 
 THREE.Path.prototype.bezierCurveTo = function( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
 
-	var args = Array.prototype.slice.call( arguments );
-
 	var lastargs = this.actions[ this.actions.length - 1 ].args;
 
 	var x0 = lastargs[ lastargs.length - 2 ];
@@ -112,13 +95,14 @@ THREE.Path.prototype.bezierCurveTo = function( aCP1x, aCP1y, aCP2x, aCP2y, aX, a
 
 	this.curves.push( curve );
 
-	this.actions.push( { action: THREE.PathActions.BEZIER_CURVE_TO, args: args } );
+	this.actions.push( { action: 'bezierCurveTo', args: [ aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ] } );
 
 };
 
 THREE.Path.prototype.splineThru = function( pts /*Array of Vector*/ ) {
 
 	var args = Array.prototype.slice.call( arguments );
+
 	var lastargs = this.actions[ this.actions.length - 1 ].args;
 
 	var x0 = lastargs[ lastargs.length - 2 ];
@@ -130,7 +114,7 @@ THREE.Path.prototype.splineThru = function( pts /*Array of Vector*/ ) {
 	var curve = new THREE.SplineCurve( npts );
 	this.curves.push( curve );
 
-	this.actions.push( { action: THREE.PathActions.CSPLINE_THRU, args: args } );
+	this.actions.push( { action: 'splineThru', args: args } );
 
 };
 
@@ -181,7 +165,7 @@ THREE.Path.prototype.absellipse = function ( aX, aY, xRadius, yRadius, aStartAng
 	args.push( lastPoint.x );
 	args.push( lastPoint.y );
 
-	this.actions.push( { action: THREE.PathActions.ELLIPSE, args: args } );
+	this.actions.push( { action: 'ellipse', args: args } );
 
  };
 
@@ -213,14 +197,11 @@ THREE.Path.prototype.getSpacedPoints = function ( divisions, closedPath ) {
 
 THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
 
-	if ( this.useSpacedPoints ) {
-
-		return this.getSpacedPoints( divisions, closedPath );
-
-	}
-
 	divisions = divisions || 12;
 
+	var b2 = THREE.ShapeUtils.b2;
+	var b3 = THREE.ShapeUtils.b3;
+
 	var points = [];
 
 	var cpx, cpy, cpx2, cpy2, cpx1, cpy1, cpx0, cpy0,
@@ -235,19 +216,19 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
 
 		switch ( action ) {
 
-		case THREE.PathActions.MOVE_TO:
+		case 'moveTo':
 
 			points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) );
 
 			break;
 
-		case THREE.PathActions.LINE_TO:
+		case 'lineTo':
 
 			points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) );
 
 			break;
 
-		case THREE.PathActions.QUADRATIC_CURVE_TO:
+		case 'quadraticCurveTo':
 
 			cpx  = args[ 2 ];
 			cpy  = args[ 3 ];
@@ -275,8 +256,8 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
 
 				var t = j / divisions;
 
-				tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx );
-				ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy );
+				tx = b2( t, cpx0, cpx1, cpx );
+				ty = b2( t, cpy0, cpy1, cpy );
 
 				points.push( new THREE.Vector2( tx, ty ) );
 
@@ -284,7 +265,7 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
 
 			break;
 
-		case THREE.PathActions.BEZIER_CURVE_TO:
+		case 'bezierCurveTo':
 
 			cpx  = args[ 4 ];
 			cpy  = args[ 5 ];
@@ -316,8 +297,8 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
 
 				var t = j / divisions;
 
-				tx = THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx );
-				ty = THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy );
+				tx = b3( t, cpx0, cpx1, cpx2, cpx );
+				ty = b3( t, cpy0, cpy1, cpy2, cpy );
 
 				points.push( new THREE.Vector2( tx, ty ) );
 
@@ -325,7 +306,7 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
 
 			break;
 
-		case THREE.PathActions.CSPLINE_THRU:
+		case 'splineThru':
 
 			laste = this.actions[ i - 1 ].args;
 
@@ -346,7 +327,7 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
 
 			break;
 
-		case THREE.PathActions.ARC:
+		case 'arc':
 
 			var aX = args[ 0 ], aY = args[ 1 ],
 				aRadius = args[ 2 ],
@@ -382,7 +363,7 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
 
 			break;
 
-		case THREE.PathActions.ELLIPSE:
+		case 'ellipse':
 
 			var aX = args[ 0 ], aY = args[ 1 ],
 				xRadius = args[ 2 ],
@@ -447,9 +428,8 @@ THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
 
 	// Normalize to remove the closing point by default.
 	var lastPoint = points[ points.length - 1 ];
-	var EPSILON = 0.0000000001;
-	if ( Math.abs( lastPoint.x - points[ 0 ].x ) < EPSILON &&
-			 Math.abs( lastPoint.y - points[ 0 ].y ) < EPSILON )
+	if ( Math.abs( lastPoint.x - points[ 0 ].x ) < Number.EPSILON &&
+			 Math.abs( lastPoint.y - points[ 0 ].y ) < Number.EPSILON )
 		points.splice( points.length - 1, 1 );
 	if ( closedPath ) {
 
@@ -486,7 +466,7 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) {
 			var args = item.args;
 			var action = item.action;
 
-			if ( action === THREE.PathActions.MOVE_TO ) {
+			if ( action === 'moveTo' ) {
 
 				if ( lastPath.actions.length !== 0 ) {
 
@@ -537,8 +517,6 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) {
 
 	function isPointInsidePolygon( inPt, inPolygon ) {
 
-		var EPSILON = 0.0000000001;
-
 		var polyLen = inPolygon.length;
 
 		// inPt on polygon contour => immediate success    or
@@ -554,7 +532,7 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) {
 			var edgeDx = edgeHighPt.x - edgeLowPt.x;
 			var edgeDy = edgeHighPt.y - edgeLowPt.y;
 
-			if ( Math.abs( edgeDy ) > EPSILON ) {
+			if ( Math.abs( edgeDy ) > Number.EPSILON ) {
 
 				// not parallel
 				if ( edgeDy < 0 ) {
@@ -596,6 +574,7 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) {
 
 	}
 
+	var isClockWise = THREE.ShapeUtils.isClockWise;
 
 	var subPaths = extractSubpaths( this.actions );
 	if ( subPaths.length === 0 ) return [];
@@ -616,7 +595,7 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) {
 
 	}
 
-	var holesFirst = ! THREE.Shape.Utils.isClockWise( subPaths[ 0 ].getPoints() );
+	var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );
 	holesFirst = isCCW ? ! holesFirst : holesFirst;
 
 	// console.log("Holes first", holesFirst);
@@ -634,7 +613,7 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) {
 
 		tmpPath = subPaths[ i ];
 		tmpPoints = tmpPath.getPoints();
-		solid = THREE.Shape.Utils.isClockWise( tmpPoints );
+		solid = isClockWise( tmpPoints );
 		solid = isCCW ? ! solid : solid;
 
 		if ( solid ) {

+ 3 - 611
src/extras/core/Shape.js

@@ -44,23 +44,7 @@ THREE.Shape.prototype.getPointsHoles = function ( divisions ) {
 
 	for ( var i = 0, l = this.holes.length; i < l; i ++ ) {
 
-		holesPts[ i ] = this.holes[ i ].getTransformedPoints( divisions, this.bends );
-
-	}
-
-	return holesPts;
-
-};
-
-// Get points of holes (spaced by regular distance)
-
-THREE.Shape.prototype.getSpacedPointsHoles = function ( divisions ) {
-
-	var holesPts = [];
-
-	for ( var i = 0, l = this.holes.length; i < l; i ++ ) {
-
-		holesPts[ i ] = this.holes[ i ].getTransformedSpacedPoints( divisions, this.bends );
+		holesPts[ i ] = this.holes[ i ].getPoints( divisions );
 
 	}
 
@@ -75,7 +59,7 @@ THREE.Shape.prototype.extractAllPoints = function ( divisions ) {
 
 	return {
 
-		shape: this.getTransformedPoints( divisions ),
+		shape: this.getPoints( divisions ),
 		holes: this.getPointsHoles( divisions )
 
 	};
@@ -84,600 +68,8 @@ THREE.Shape.prototype.extractAllPoints = function ( divisions ) {
 
 THREE.Shape.prototype.extractPoints = function ( divisions ) {
 
-	if ( this.useSpacedPoints ) {
-
-		return this.extractAllSpacedPoints( divisions );
-
-	}
-
 	return this.extractAllPoints( divisions );
 
 };
 
-/*
-THREE.Shape.prototype.extractAllPointsWithBend = function ( divisions, bend ) {
-
-	return {
-
-		shape: this.transform( bend, divisions ),
-		holes: this.getPointsHoles( divisions, bend )
-
-	};
-
-};
-*/
-
-// Get points of shape and holes (spaced by regular distance)
-
-THREE.Shape.prototype.extractAllSpacedPoints = function ( divisions ) {
-
-	return {
-
-		shape: this.getTransformedSpacedPoints( divisions ),
-		holes: this.getSpacedPointsHoles( divisions )
-
-	};
-
-};
-
-/**************************************************************
- *	Utils
- **************************************************************/
-
-THREE.Shape.Utils = {
-
-	triangulateShape: function ( contour, holes ) {
-
-		function point_in_segment_2D_colin( inSegPt1, inSegPt2, inOtherPt ) {
-
-			// inOtherPt needs to be collinear to the inSegment
-			if ( inSegPt1.x !== inSegPt2.x ) {
-
-				if ( inSegPt1.x < inSegPt2.x ) {
-
-					return	( ( inSegPt1.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt2.x ) );
-
-				} else {
-
-					return	( ( inSegPt2.x <= inOtherPt.x ) && ( inOtherPt.x <= inSegPt1.x ) );
-
-				}
-
-			} else {
-
-				if ( inSegPt1.y < inSegPt2.y ) {
-
-					return	( ( inSegPt1.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt2.y ) );
-
-				} else {
-
-					return	( ( inSegPt2.y <= inOtherPt.y ) && ( inOtherPt.y <= inSegPt1.y ) );
-
-				}
-
-			}
-
-		}
-
-		function intersect_segments_2D( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1, inSeg2Pt2, inExcludeAdjacentSegs ) {
-
-			var EPSILON = 0.0000000001;
-
-			var seg1dx = inSeg1Pt2.x - inSeg1Pt1.x,   seg1dy = inSeg1Pt2.y - inSeg1Pt1.y;
-			var seg2dx = inSeg2Pt2.x - inSeg2Pt1.x,   seg2dy = inSeg2Pt2.y - inSeg2Pt1.y;
-
-			var seg1seg2dx = inSeg1Pt1.x - inSeg2Pt1.x;
-			var seg1seg2dy = inSeg1Pt1.y - inSeg2Pt1.y;
-
-			var limit		= seg1dy * seg2dx - seg1dx * seg2dy;
-			var perpSeg1	= seg1dy * seg1seg2dx - seg1dx * seg1seg2dy;
-
-			if ( Math.abs( limit ) > EPSILON ) {
-
-				// not parallel
-
-				var perpSeg2;
-				if ( limit > 0 ) {
-
-					if ( ( perpSeg1 < 0 ) || ( perpSeg1 > limit ) ) 		return [];
-					perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;
-					if ( ( perpSeg2 < 0 ) || ( perpSeg2 > limit ) ) 		return [];
-
-				} else {
-
-					if ( ( perpSeg1 > 0 ) || ( perpSeg1 < limit ) ) 		return [];
-					perpSeg2 = seg2dy * seg1seg2dx - seg2dx * seg1seg2dy;
-					if ( ( perpSeg2 > 0 ) || ( perpSeg2 < limit ) ) 		return [];
-
-				}
-
-				// i.e. to reduce rounding errors
-				// intersection at endpoint of segment#1?
-				if ( perpSeg2 === 0 ) {
-
-					if ( ( inExcludeAdjacentSegs ) &&
-						 ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )		return [];
-					return [ inSeg1Pt1 ];
-
-				}
-				if ( perpSeg2 === limit ) {
-
-					if ( ( inExcludeAdjacentSegs ) &&
-						 ( ( perpSeg1 === 0 ) || ( perpSeg1 === limit ) ) )		return [];
-					return [ inSeg1Pt2 ];
-
-				}
-				// intersection at endpoint of segment#2?
-				if ( perpSeg1 === 0 )		return [ inSeg2Pt1 ];
-				if ( perpSeg1 === limit )	return [ inSeg2Pt2 ];
-
-				// return real intersection point
-				var factorSeg1 = perpSeg2 / limit;
-				return	[ { x: inSeg1Pt1.x + factorSeg1 * seg1dx,
-							y: inSeg1Pt1.y + factorSeg1 * seg1dy } ];
-
-			} else {
-
-				// parallel or collinear
-				if ( ( perpSeg1 !== 0 ) ||
-					 ( seg2dy * seg1seg2dx !== seg2dx * seg1seg2dy ) ) 			return [];
-
-				// they are collinear or degenerate
-				var seg1Pt = ( ( seg1dx === 0 ) && ( seg1dy === 0 ) );	// segment1 is just a point?
-				var seg2Pt = ( ( seg2dx === 0 ) && ( seg2dy === 0 ) );	// segment2 is just a point?
-				// both segments are points
-				if ( seg1Pt && seg2Pt ) {
-
-					if ( ( inSeg1Pt1.x !== inSeg2Pt1.x ) ||
-						 ( inSeg1Pt1.y !== inSeg2Pt1.y ) )		return [];	// they are distinct  points
-					return [ inSeg1Pt1 ];                 						// they are the same point
-
-				}
-				// segment#1  is a single point
-				if ( seg1Pt ) {
-
-					if ( ! point_in_segment_2D_colin( inSeg2Pt1, inSeg2Pt2, inSeg1Pt1 ) )		return [];		// but not in segment#2
-					return [ inSeg1Pt1 ];
-
-				}
-				// segment#2  is a single point
-				if ( seg2Pt ) {
-
-					if ( ! point_in_segment_2D_colin( inSeg1Pt1, inSeg1Pt2, inSeg2Pt1 ) )		return [];		// but not in segment#1
-					return [ inSeg2Pt1 ];
-
-				}
-
-				// they are collinear segments, which might overlap
-				var seg1min, seg1max, seg1minVal, seg1maxVal;
-				var seg2min, seg2max, seg2minVal, seg2maxVal;
-				if ( seg1dx !== 0 ) {
-
-					// the segments are NOT on a vertical line
-					if ( inSeg1Pt1.x < inSeg1Pt2.x ) {
-
-						seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.x;
-						seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.x;
-
-					} else {
-
-						seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.x;
-						seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.x;
-
-					}
-					if ( inSeg2Pt1.x < inSeg2Pt2.x ) {
-
-						seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.x;
-						seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.x;
-
-					} else {
-
-						seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.x;
-						seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.x;
-
-					}
-
-				} else {
-
-					// the segments are on a vertical line
-					if ( inSeg1Pt1.y < inSeg1Pt2.y ) {
-
-						seg1min = inSeg1Pt1; seg1minVal = inSeg1Pt1.y;
-						seg1max = inSeg1Pt2; seg1maxVal = inSeg1Pt2.y;
-
-					} else {
-
-						seg1min = inSeg1Pt2; seg1minVal = inSeg1Pt2.y;
-						seg1max = inSeg1Pt1; seg1maxVal = inSeg1Pt1.y;
-
-					}
-					if ( inSeg2Pt1.y < inSeg2Pt2.y ) {
-
-						seg2min = inSeg2Pt1; seg2minVal = inSeg2Pt1.y;
-						seg2max = inSeg2Pt2; seg2maxVal = inSeg2Pt2.y;
-
-					} else {
-
-						seg2min = inSeg2Pt2; seg2minVal = inSeg2Pt2.y;
-						seg2max = inSeg2Pt1; seg2maxVal = inSeg2Pt1.y;
-
-					}
-
-				}
-				if ( seg1minVal <= seg2minVal ) {
-
-					if ( seg1maxVal <  seg2minVal )	return [];
-					if ( seg1maxVal === seg2minVal )	{
-
-						if ( inExcludeAdjacentSegs )		return [];
-						return [ seg2min ];
-
-					}
-					if ( seg1maxVal <= seg2maxVal )	return [ seg2min, seg1max ];
-					return	[ seg2min, seg2max ];
-
-				} else {
-
-					if ( seg1minVal >  seg2maxVal )	return [];
-					if ( seg1minVal === seg2maxVal )	{
-
-						if ( inExcludeAdjacentSegs )		return [];
-						return [ seg1min ];
-
-					}
-					if ( seg1maxVal <= seg2maxVal )	return [ seg1min, seg1max ];
-					return	[ seg1min, seg2max ];
-
-				}
-
-			}
-
-		}
-
-		function isPointInsideAngle( inVertex, inLegFromPt, inLegToPt, inOtherPt ) {
-
-			// The order of legs is important
-
-			var EPSILON = 0.0000000001;
-
-			// translation of all points, so that Vertex is at (0,0)
-			var legFromPtX	= inLegFromPt.x - inVertex.x,  legFromPtY	= inLegFromPt.y - inVertex.y;
-			var legToPtX	= inLegToPt.x	- inVertex.x,  legToPtY		= inLegToPt.y	- inVertex.y;
-			var otherPtX	= inOtherPt.x	- inVertex.x,  otherPtY		= inOtherPt.y	- inVertex.y;
-
-			// main angle >0: < 180 deg.; 0: 180 deg.; <0: > 180 deg.
-			var from2toAngle	= legFromPtX * legToPtY - legFromPtY * legToPtX;
-			var from2otherAngle	= legFromPtX * otherPtY - legFromPtY * otherPtX;
-
-			if ( Math.abs( from2toAngle ) > EPSILON ) {
-
-				// angle != 180 deg.
-
-				var other2toAngle		= otherPtX * legToPtY - otherPtY * legToPtX;
-				// console.log( "from2to: " + from2toAngle + ", from2other: " + from2otherAngle + ", other2to: " + other2toAngle );
-
-				if ( from2toAngle > 0 ) {
-
-					// main angle < 180 deg.
-					return	( ( from2otherAngle >= 0 ) && ( other2toAngle >= 0 ) );
-
-				} else {
-
-					// main angle > 180 deg.
-					return	( ( from2otherAngle >= 0 ) || ( other2toAngle >= 0 ) );
-
-				}
-
-			} else {
-
-				// angle == 180 deg.
-				// console.log( "from2to: 180 deg., from2other: " + from2otherAngle  );
-				return	( from2otherAngle > 0 );
-
-			}
-
-		}
-
-
-		function removeHoles( contour, holes ) {
-
-			var shape = contour.concat(); // work on this shape
-			var hole;
-
-			function isCutLineInsideAngles( inShapeIdx, inHoleIdx ) {
-
-				// Check if hole point lies within angle around shape point
-				var lastShapeIdx = shape.length - 1;
-
-				var prevShapeIdx = inShapeIdx - 1;
-				if ( prevShapeIdx < 0 )			prevShapeIdx = lastShapeIdx;
-
-				var nextShapeIdx = inShapeIdx + 1;
-				if ( nextShapeIdx > lastShapeIdx )	nextShapeIdx = 0;
-
-				var insideAngle = isPointInsideAngle( shape[ inShapeIdx ], shape[ prevShapeIdx ], shape[ nextShapeIdx ], hole[ inHoleIdx ] );
-				if ( ! insideAngle ) {
-
-					// console.log( "Vertex (Shape): " + inShapeIdx + ", Point: " + hole[inHoleIdx].x + "/" + hole[inHoleIdx].y );
-					return	false;
-
-				}
-
-				// Check if shape point lies within angle around hole point
-				var lastHoleIdx = hole.length - 1;
-
-				var prevHoleIdx = inHoleIdx - 1;
-				if ( prevHoleIdx < 0 )			prevHoleIdx = lastHoleIdx;
-
-				var nextHoleIdx = inHoleIdx + 1;
-				if ( nextHoleIdx > lastHoleIdx )	nextHoleIdx = 0;
-
-				insideAngle = isPointInsideAngle( hole[ inHoleIdx ], hole[ prevHoleIdx ], hole[ nextHoleIdx ], shape[ inShapeIdx ] );
-				if ( ! insideAngle ) {
-
-					// console.log( "Vertex (Hole): " + inHoleIdx + ", Point: " + shape[inShapeIdx].x + "/" + shape[inShapeIdx].y );
-					return	false;
-
-				}
-
-				return	true;
-
-			}
-
-			function intersectsShapeEdge( inShapePt, inHolePt ) {
-
-				// checks for intersections with shape edges
-				var sIdx, nextIdx, intersection;
-				for ( sIdx = 0; sIdx < shape.length; sIdx ++ ) {
-
-					nextIdx = sIdx + 1; nextIdx %= shape.length;
-					intersection = intersect_segments_2D( inShapePt, inHolePt, shape[ sIdx ], shape[ nextIdx ], true );
-					if ( intersection.length > 0 )		return	true;
-
-				}
-
-				return	false;
-
-			}
-
-			var indepHoles = [];
-
-			function intersectsHoleEdge( inShapePt, inHolePt ) {
-
-				// checks for intersections with hole edges
-				var ihIdx, chkHole,
-					hIdx, nextIdx, intersection;
-				for ( ihIdx = 0; ihIdx < indepHoles.length; ihIdx ++ ) {
-
-					chkHole = holes[ indepHoles[ ihIdx ]];
-					for ( hIdx = 0; hIdx < chkHole.length; hIdx ++ ) {
-
-						nextIdx = hIdx + 1; nextIdx %= chkHole.length;
-						intersection = intersect_segments_2D( inShapePt, inHolePt, chkHole[ hIdx ], chkHole[ nextIdx ], true );
-						if ( intersection.length > 0 )		return	true;
-
-					}
-
-				}
-				return	false;
-
-			}
-
-			var holeIndex, shapeIndex,
-				shapePt, holePt,
-				holeIdx, cutKey, failedCuts = [],
-				tmpShape1, tmpShape2,
-				tmpHole1, tmpHole2;
-
-			for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
-
-				indepHoles.push( h );
-
-			}
-
-			var minShapeIndex = 0;
-			var counter = indepHoles.length * 2;
-			while ( indepHoles.length > 0 ) {
-
-				counter --;
-				if ( counter < 0 ) {
-
-					console.log( "Infinite Loop! Holes left:" + indepHoles.length + ", Probably Hole outside Shape!" );
-					break;
-
-				}
-
-				// search for shape-vertex and hole-vertex,
-				// which can be connected without intersections
-				for ( shapeIndex = minShapeIndex; shapeIndex < shape.length; shapeIndex ++ ) {
-
-					shapePt = shape[ shapeIndex ];
-					holeIndex	= - 1;
-
-					// search for hole which can be reached without intersections
-					for ( var h = 0; h < indepHoles.length; h ++ ) {
-
-						holeIdx = indepHoles[ h ];
-
-						// prevent multiple checks
-						cutKey = shapePt.x + ":" + shapePt.y + ":" + holeIdx;
-						if ( failedCuts[ cutKey ] !== undefined )			continue;
-
-						hole = holes[ holeIdx ];
-						for ( var h2 = 0; h2 < hole.length; h2 ++ ) {
-
-							holePt = hole[ h2 ];
-							if ( ! isCutLineInsideAngles( shapeIndex, h2 ) )		continue;
-							if ( intersectsShapeEdge( shapePt, holePt ) )		continue;
-							if ( intersectsHoleEdge( shapePt, holePt ) )		continue;
-
-							holeIndex = h2;
-							indepHoles.splice( h, 1 );
-
-							tmpShape1 = shape.slice( 0, shapeIndex + 1 );
-							tmpShape2 = shape.slice( shapeIndex );
-							tmpHole1 = hole.slice( holeIndex );
-							tmpHole2 = hole.slice( 0, holeIndex + 1 );
-
-							shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );
-
-							minShapeIndex = shapeIndex;
-
-							// Debug only, to show the selected cuts
-							// glob_CutLines.push( [ shapePt, holePt ] );
-
-							break;
-
-						}
-						if ( holeIndex >= 0 )	break;		// hole-vertex found
-
-						failedCuts[ cutKey ] = true;			// remember failure
-
-					}
-					if ( holeIndex >= 0 )	break;		// hole-vertex found
-
-				}
-
-			}
-
-			return shape; 			/* shape with no holes */
-
-		}
-
-
-		var i, il, f, face,
-			key, index,
-			allPointsMap = {};
-
-		// To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.
-
-		var allpoints = contour.concat();
-
-		for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
-
-			Array.prototype.push.apply( allpoints, holes[ h ] );
-
-		}
-
-		//console.log( "allpoints",allpoints, allpoints.length );
-
-		// prepare all points map
-
-		for ( i = 0, il = allpoints.length; i < il; i ++ ) {
-
-			key = allpoints[ i ].x + ":" + allpoints[ i ].y;
-
-			if ( allPointsMap[ key ] !== undefined ) {
-
-				console.warn( "THREE.Shape: Duplicate point", key );
-
-			}
-
-			allPointsMap[ key ] = i;
-
-		}
-
-		// remove holes by cutting paths to holes and adding them to the shape
-		var shapeWithoutHoles = removeHoles( contour, holes );
-
-		var triangles = THREE.FontUtils.Triangulate( shapeWithoutHoles, false ); // True returns indices for points of spooled shape
-		//console.log( "triangles",triangles, triangles.length );
-
-		// check all face vertices against all points map
-
-		for ( i = 0, il = triangles.length; i < il; i ++ ) {
-
-			face = triangles[ i ];
-
-			for ( f = 0; f < 3; f ++ ) {
-
-				key = face[ f ].x + ":" + face[ f ].y;
-
-				index = allPointsMap[ key ];
-
-				if ( index !== undefined ) {
-
-					face[ f ] = index;
-
-				}
-
-			}
-
-		}
-
-		return triangles.concat();
-
-	},
-
-	isClockWise: function ( pts ) {
-
-		return THREE.FontUtils.Triangulate.area( pts ) < 0;
-
-	},
-
-	// Bezier Curves formulas obtained from
-	// http://en.wikipedia.org/wiki/B%C3%A9zier_curve
-
-	// Quad Bezier Functions
-
-	b2p0: function ( t, p ) {
-
-		var k = 1 - t;
-		return k * k * p;
-
-	},
-
-	b2p1: function ( t, p ) {
-
-		return 2 * ( 1 - t ) * t * p;
-
-	},
-
-	b2p2: function ( t, p ) {
-
-		return t * t * p;
-
-	},
-
-	b2: function ( t, p0, p1, p2 ) {
-
-		return this.b2p0( t, p0 ) + this.b2p1( t, p1 ) + this.b2p2( t, p2 );
-
-	},
-
-	// Cubic Bezier Functions
-
-	b3p0: function ( t, p ) {
-
-		var k = 1 - t;
-		return k * k * k * p;
-
-	},
-
-	b3p1: function ( t, p ) {
-
-		var k = 1 - t;
-		return 3 * k * k * t * p;
-
-	},
-
-	b3p2: function ( t, p ) {
-
-		var k = 1 - t;
-		return 3 * k * t * t * p;
-
-	},
-
-	b3p3: function ( t, p ) {
-
-		return t * t * t * p;
-
-	},
-
-	b3: function ( t, p0, p1, p2, p3 ) {
-
-		return this.b3p0( t, p0 ) + this.b3p1( t, p1 ) + this.b3p2( t, p2 ) +  this.b3p3( t, p3 );
-
-	}
-
-};
+THREE.Shape.Utils = THREE.ShapeUtils; // backwards compatibility

+ 6 - 6
src/extras/curves/ClosedSplineCurve3.js

@@ -26,13 +26,13 @@ THREE.ClosedSplineCurve3 = THREE.Curve.create(
 		var point2 = points[ ( intPoint + 1 ) % points.length ];
 		var point3 = points[ ( intPoint + 2 ) % points.length ];
 
-		var vector = new THREE.Vector3();
+		var interpolate = THREE.CurveUtils.interpolate;
 
-		vector.x = THREE.Curve.Utils.interpolate( point0.x, point1.x, point2.x, point3.x, weight );
-		vector.y = THREE.Curve.Utils.interpolate( point0.y, point1.y, point2.y, point3.y, weight );
-		vector.z = THREE.Curve.Utils.interpolate( point0.z, point1.z, point2.z, point3.z, weight );
-
-		return vector;
+		return new THREE.Vector3(
+			interpolate( point0.x, point1.x, point2.x, point3.x, weight ),
+			interpolate( point0.y, point1.y, point2.y, point3.y, weight ),
+			interpolate( point0.z, point1.z, point2.z, point3.z, weight )
+		);
 
 	}
 

+ 10 - 13
src/extras/curves/CubicBezierCurve.js

@@ -16,25 +16,22 @@ THREE.CubicBezierCurve.prototype.constructor = THREE.CubicBezierCurve;
 
 THREE.CubicBezierCurve.prototype.getPoint = function ( t ) {
 
-	var tx, ty;
+	var b3 = THREE.ShapeUtils.b3;
 
-	tx = THREE.Shape.Utils.b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
-	ty = THREE.Shape.Utils.b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
-
-	return new THREE.Vector2( tx, ty );
+	return new THREE.Vector2( 
+		b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),
+		b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )
+	);
 
 };
 
 THREE.CubicBezierCurve.prototype.getTangent = function( t ) {
 
-	var tx, ty;
-
-	tx = THREE.Curve.Utils.tangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
-	ty = THREE.Curve.Utils.tangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
-
-	var tangent = new THREE.Vector2( tx, ty );
-	tangent.normalize();
+	var tangentCubicBezier = THREE.CurveUtils.tangentCubicBezier;
 
-	return tangent;
+	return new THREE.Vector2( 
+		tangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),
+		tangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y )
+	).normalize();
 
 };

+ 6 - 6
src/extras/curves/CubicBezierCurve3.js

@@ -15,13 +15,13 @@ THREE.CubicBezierCurve3 = THREE.Curve.create(
 
 	function ( t ) {
 
-		var vector = new THREE.Vector3();
+		var b3 = THREE.ShapeUtils.b3;
 
-		vector.x = THREE.Shape.Utils.b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
-		vector.y = THREE.Shape.Utils.b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
-		vector.z = THREE.Shape.Utils.b3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z );
-
-		return vector;
+		return new THREE.Vector3(
+			b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x ),
+			b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y ),
+			b3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z )
+		);
 
 	}
 

+ 10 - 12
src/extras/curves/QuadraticBezierCurve.js

@@ -17,25 +17,23 @@ THREE.QuadraticBezierCurve.prototype.constructor = THREE.QuadraticBezierCurve;
 
 THREE.QuadraticBezierCurve.prototype.getPoint = function ( t ) {
 
-	var vector = new THREE.Vector2();
+	var b2 = THREE.ShapeUtils.b2;
 
-	vector.x = THREE.Shape.Utils.b2( t, this.v0.x, this.v1.x, this.v2.x );
-	vector.y = THREE.Shape.Utils.b2( t, this.v0.y, this.v1.y, this.v2.y );
-
-	return vector;
+	return new THREE.Vector2(
+		b2( t, this.v0.x, this.v1.x, this.v2.x ),
+		b2( t, this.v0.y, this.v1.y, this.v2.y )
+	);
 
 };
 
 
 THREE.QuadraticBezierCurve.prototype.getTangent = function( t ) {
 
-	var vector = new THREE.Vector2();
-
-	vector.x = THREE.Curve.Utils.tangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x );
-	vector.y = THREE.Curve.Utils.tangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y );
-
-	// returns unit vector
+	var tangentQuadraticBezier = THREE.CurveUtils.tangentQuadraticBezier;
 
-	return vector.normalize();
+	return new THREE.Vector2(
+		tangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x ),
+		tangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y )
+	).normalize();
 
 };

+ 6 - 6
src/extras/curves/QuadraticBezierCurve3.js

@@ -14,13 +14,13 @@ THREE.QuadraticBezierCurve3 = THREE.Curve.create(
 
 	function ( t ) {
 
-		var vector = new THREE.Vector3();
+		var b2 = THREE.ShapeUtils.b2;		
 
-		vector.x = THREE.Shape.Utils.b2( t, this.v0.x, this.v1.x, this.v2.x );
-		vector.y = THREE.Shape.Utils.b2( t, this.v0.y, this.v1.y, this.v2.y );
-		vector.z = THREE.Shape.Utils.b2( t, this.v0.z, this.v1.z, this.v2.z );
-
-		return vector;
+		return new THREE.Vector3(
+			b2( t, this.v0.x, this.v1.x, this.v2.x ),
+			b2( t, this.v0.y, this.v1.y, this.v2.y ),
+			b2( t, this.v0.z, this.v1.z, this.v2.z )
+		);
 
 	}
 

+ 5 - 5
src/extras/curves/SplineCurve.js

@@ -24,11 +24,11 @@ THREE.SplineCurve.prototype.getPoint = function ( t ) {
 	var point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
 	var point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
 
-	var vector = new THREE.Vector2();
+	var interpolate = THREE.CurveUtils.interpolate;
 
-	vector.x = THREE.Curve.Utils.interpolate( point0.x, point1.x, point2.x, point3.x, weight );
-	vector.y = THREE.Curve.Utils.interpolate( point0.y, point1.y, point2.y, point3.y, weight );
-
-	return vector;
+	return new THREE.Vector2(
+		interpolate( point0.x, point1.x, point2.x, point3.x, weight ),
+		interpolate( point0.y, point1.y, point2.y, point3.y, weight )
+	);
 
 };

+ 6 - 6
src/extras/curves/SplineCurve3.js

@@ -25,13 +25,13 @@ THREE.SplineCurve3 = THREE.Curve.create(
 		var point2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
 		var point3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
 
-		var vector = new THREE.Vector3();
+		var interpolate = THREE.CurveUtils.interpolate;
 
-		vector.x = THREE.Curve.Utils.interpolate( point0.x, point1.x, point2.x, point3.x, weight );
-		vector.y = THREE.Curve.Utils.interpolate( point0.y, point1.y, point2.y, point3.y, weight );
-		vector.z = THREE.Curve.Utils.interpolate( point0.z, point1.z, point2.z, point3.z, weight );
-
-		return vector;
+		return new THREE.Vector3(
+			interpolate( point0.x, point1.x, point2.x, point3.x, weight ),
+			interpolate( point0.y, point1.y, point2.y, point3.y, weight ),
+			interpolate( point0.z, point1.z, point2.z, point3.z, weight )
+		);
 
 	}
 

+ 11 - 13
src/extras/geometries/ExtrudeGeometry.js

@@ -132,7 +132,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
 	var vertices = shapePoints.shape;
 	var holes = shapePoints.holes;
 
-	var reverse = ! THREE.Shape.Utils.isClockWise( vertices );
+	var reverse = ! THREE.ShapeUtils.isClockWise( vertices );
 
 	if ( reverse ) {
 
@@ -144,7 +144,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
 
 			ahole = holes[ h ];
 
-			if ( THREE.Shape.Utils.isClockWise( ahole ) ) {
+			if ( THREE.ShapeUtils.isClockWise( ahole ) ) {
 
 				holes[ h ] = ahole.reverse();
 
@@ -157,7 +157,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
 	}
 
 
-	var faces = THREE.Shape.Utils.triangulateShape ( vertices, holes );
+	var faces = THREE.ShapeUtils.triangulateShape( vertices, holes );
 
 	/* Vertices */
 
@@ -190,8 +190,6 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
 
 	function getBevelVec( inPt, inPrev, inNext ) {
 
-		var EPSILON = 0.0000000001;
-
 		// computes for inPt the corresponding point inPt' on a new contour
 		//   shifted by 1 unit (length of normalized vector) to the left
 		// if we walk along contour clockwise, this new contour is outside the old one
@@ -212,7 +210,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
 		// check for collinear edges
 		var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
 
-		if ( Math.abs( collinear0 ) > EPSILON ) {
+		if ( Math.abs( collinear0 ) > Number.EPSILON ) {
 
 			// not collinear
 
@@ -258,9 +256,9 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
 			// handle special case of collinear edges
 
 			var direction_eq = false;		// assumes: opposite
-			if ( v_prev_x > EPSILON ) {
+			if ( v_prev_x > Number.EPSILON ) {
 
-				if ( v_next_x > EPSILON ) {
+				if ( v_next_x > Number.EPSILON ) {
 
 					direction_eq = true;
 
@@ -268,9 +266,9 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
 
 			} else {
 
-				if ( v_prev_x < - EPSILON ) {
+				if ( v_prev_x < - Number.EPSILON ) {
 
-					if ( v_next_x < - EPSILON ) {
+					if ( v_next_x < - Number.EPSILON ) {
 
 						direction_eq = true;
 
@@ -628,7 +626,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
 		b += shapesOffset;
 		c += shapesOffset;
 
-		scope.faces.push( new THREE.Face3( a, b, c ) );
+		scope.faces.push( new THREE.Face3( a, b, c, null, null, 0 ) );
 
 		var uvs = uvgen.generateTopUV( scope, a, b, c );
 
@@ -643,8 +641,8 @@ THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
 		c += shapesOffset;
 		d += shapesOffset;
 
-		scope.faces.push( new THREE.Face3( a, b, d ) );
-		scope.faces.push( new THREE.Face3( b, c, d ) );
+		scope.faces.push( new THREE.Face3( a, b, d, null, null, 1 ) );
+		scope.faces.push( new THREE.Face3( b, c, d, null, null, 1 ) );
 
 		var uvs = uvgen.generateSideWallUV( scope, a, b, c, d );
 

+ 2 - 2
src/extras/geometries/PolyhedronGeometry.js

@@ -61,8 +61,8 @@ THREE.PolyhedronGeometry = function ( vertices, indices, radius, detail ) {
 		var x1 = uvs[ 1 ].x;
 		var x2 = uvs[ 2 ].x;
 
-		var max = Math.max( x0, Math.max( x1, x2 ) );
-		var min = Math.min( x0, Math.min( x1, x2 ) );
+		var max = Math.max( x0, x1, x2 );
+		var min = Math.min( x0, x1, x2 );
 
 		if ( max > 0.9 && min < 0.1 ) {
 

+ 3 - 3
src/extras/geometries/ShapeGeometry.js

@@ -67,7 +67,7 @@ THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) {
 	var vertices = shapePoints.shape;
 	var holes = shapePoints.holes;
 
-	var reverse = ! THREE.Shape.Utils.isClockWise( vertices );
+	var reverse = ! THREE.ShapeUtils.isClockWise( vertices );
 
 	if ( reverse ) {
 
@@ -79,7 +79,7 @@ THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) {
 
 			hole = holes[ i ];
 
-			if ( THREE.Shape.Utils.isClockWise( hole ) ) {
+			if ( THREE.ShapeUtils.isClockWise( hole ) ) {
 
 				holes[ i ] = hole.reverse();
 
@@ -91,7 +91,7 @@ THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) {
 
 	}
 
-	var faces = THREE.Shape.Utils.triangulateShape( vertices, holes );
+	var faces = THREE.ShapeUtils.triangulateShape( vertices, holes );
 
 	// Vertices
 

+ 1 - 2
src/extras/geometries/TubeGeometry.js

@@ -174,7 +174,6 @@ THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) {
 
 		numpoints = segments + 1,
 		theta,
-		epsilon = 0.0001,
 		smallest,
 
 		tx, ty, tz,
@@ -273,7 +272,7 @@ THREE.TubeGeometry.FrenetFrames = function ( path, segments, closed ) {
 
 		vec.crossVectors( tangents[ i - 1 ], tangents[ i ] );
 
-		if ( vec.length() > epsilon ) {
+		if ( vec.length() > Number.EPSILON ) {
 
 			vec.normalize();
 

+ 2 - 0
src/lights/AmbientLight.js

@@ -8,6 +8,8 @@ THREE.AmbientLight = function ( color ) {
 
 	this.type = 'AmbientLight';
 
+	this.castShadow = undefined;
+
 };
 
 THREE.AmbientLight.prototype = Object.create( THREE.Light.prototype );

+ 2 - 0
src/lights/HemisphereLight.js

@@ -8,6 +8,8 @@ THREE.HemisphereLight = function ( skyColor, groundColor, intensity ) {
 
 	this.type = 'HemisphereLight';
 
+	this.castShadow = undefined;
+
 	this.position.set( 0, 1, 0 );
 	this.updateMatrix();
 

+ 60 - 0
src/loaders/CubeTextureLoader.js

@@ -0,0 +1,60 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.CubeTextureLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
+
+};
+
+THREE.CubeTextureLoader.prototype = {
+
+	constructor: THREE.CubeTextureLoader,
+
+	load: function ( urls, onLoad, onProgress, onError ) {
+
+		var texture = new THREE.CubeTexture( [] );
+
+		var loader = new THREE.ImageLoader();
+		loader.setCrossOrigin( this.crossOrigin );
+
+		var loaded = 0;
+
+		function loadTexture( i ) {
+
+			loader.load( urls[ i ], function ( image ) {
+
+				texture.images[ i ] = image;
+
+				loaded ++;
+
+				if ( loaded === 6 ) {
+
+					texture.needsUpdate = true;
+
+					if ( onLoad ) onLoad( texture );
+
+				}
+
+			}, undefined, onError );
+
+		}
+
+		for ( var i = 0; i < urls.length; ++ i ) {
+
+			loadTexture( i );
+
+		}
+
+		return texture;
+
+	},
+
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+
+	}
+
+};

+ 163 - 261
src/loaders/Loader.js

@@ -44,315 +44,215 @@ THREE.Loader.prototype = {
 
 	createMaterial: ( function () {
 
-		var imageLoader;
+		var color, textureLoader, materialLoader;
 
-		return function createMaterial( m, texturePath, crossOrigin ) {
+		return function ( m, texturePath, crossOrigin ) {
 
-			var scope = this;
+			if ( color === undefined ) color = new THREE.Color();
+			if ( textureLoader === undefined ) textureLoader = new THREE.TextureLoader();
+			if ( materialLoader === undefined ) materialLoader = new THREE.MaterialLoader();
 
-			if ( crossOrigin === undefined && scope.crossOrigin !== undefined ) crossOrigin = scope.crossOrigin;
+			// convert from old material format
 
-			if ( imageLoader === undefined ) imageLoader = new THREE.ImageLoader();
+			var textures = {};
 
-			function nearest_pow2( n ) {
+			function loadTexture( path, repeat, offset, wrap, anisotropy ) {
 
-				var l = Math.log( n ) / Math.LN2;
-				return Math.pow( 2, Math.round(  l ) );
-
-			}
-
-			function create_texture( where, name, sourceFile, repeat, offset, wrap, anisotropy ) {
-
-				var fullPath = texturePath + sourceFile;
+				var fullPath = texturePath + path;
+				var loader = THREE.Loader.Handlers.get( fullPath );
 
 				var texture;
 
-				var loader = THREE.Loader.Handlers.get( fullPath );
-
 				if ( loader !== null ) {
 
 					texture = loader.load( fullPath );
 
 				} else {
 
-					texture = new THREE.Texture();
-
-					loader = imageLoader;
-					loader.setCrossOrigin( crossOrigin );
-					loader.load( fullPath, function ( image ) {
-
-						if ( THREE.Math.isPowerOfTwo( image.width ) === false ||
-							THREE.Math.isPowerOfTwo( image.height ) === false ) {
-
-							var width = nearest_pow2( image.width );
-							var height = nearest_pow2( image.height );
-
-							var canvas = document.createElement( 'canvas' );
-							canvas.width = width;
-							canvas.height = height;
-
-							var context = canvas.getContext( '2d' );
-							context.drawImage( image, 0, 0, width, height );
-
-							texture.image = canvas;
-
-						} else {
-
-							texture.image = image;
-
-						}
-
-						texture.needsUpdate = true;
-
-					} );
+					textureLoader.setCrossOrigin( crossOrigin );
+					texture = textureLoader.load( fullPath );
 
 				}
 
-				texture.sourceFile = sourceFile;
+				if ( repeat !== undefined ) {
 
-				if ( repeat ) {
-
-					texture.repeat.set( repeat[ 0 ], repeat[ 1 ] );
+					texture.repeat.fromArray( repeat );
 
 					if ( repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping;
 					if ( repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping;
 
 				}
 
-				if ( offset ) {
+				if ( offset !== undefined ) {
 
-					texture.offset.set( offset[ 0 ], offset[ 1 ] );
+					texture.offset.fromArray( offset );
 
 				}
 
-				if ( wrap ) {
+				if ( wrap !== undefined ) {
 
-					var wrapMap = {
-						'repeat': THREE.RepeatWrapping,
-						'mirror': THREE.MirroredRepeatWrapping
-					};
+					if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = THREE.RepeatWrapping;
+					if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = THREE.MirroredRepeatWrapping;
 
-					if ( wrapMap[ wrap[ 0 ] ] !== undefined ) texture.wrapS = wrapMap[ wrap[ 0 ] ];
-					if ( wrapMap[ wrap[ 1 ] ] !== undefined ) texture.wrapT = wrapMap[ wrap[ 1 ] ];
+					if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = THREE.RepeatWrapping;
+					if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = THREE.MirroredRepeatWrapping;
 
 				}
 
-				if ( anisotropy ) {
+				if ( anisotropy !== undefined ) {
 
 					texture.anisotropy = anisotropy;
 
 				}
 
-				where[ name ] = texture;
-
-			}
-
-			function rgb2hex( rgb ) {
-
-				return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255;
-
-			}
-
-			// defaults
-
-			var mtype = 'MeshLambertMaterial';
-			var mpars = {};
-
-			// parameters from model file
-
-			if ( m.shading ) {
-
-				var shading = m.shading.toLowerCase();
-
-				if ( shading === 'phong' ) mtype = 'MeshPhongMaterial';
-				else if ( shading === 'basic' ) mtype = 'MeshBasicMaterial';
-
-			}
-
-			if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) {
-
-				mpars.blending = THREE[ m.blending ];
-
-			}
-
-			if ( m.transparent !== undefined ) {
-
-				mpars.transparent = m.transparent;
-
-			}
-
-			if ( m.opacity !== undefined && m.opacity < 1.0 ) {
-
-				mpars.transparent = true;
-
-			}
-
-			if ( m.depthTest !== undefined ) {
-
-				mpars.depthTest = m.depthTest;
-
-			}
-
-			if ( m.depthWrite !== undefined ) {
-
-				mpars.depthWrite = m.depthWrite;
-
-			}
-
-			if ( m.visible !== undefined ) {
-
-				mpars.visible = m.visible;
-
-			}
-
-			if ( m.flipSided !== undefined ) {
-
-				mpars.side = THREE.BackSide;
-
-			}
-
-			if ( m.doubleSided !== undefined ) {
-
-				mpars.side = THREE.DoubleSide;
-
-			}
-
-			if ( m.wireframe !== undefined ) {
-
-				mpars.wireframe = m.wireframe;
-
-			}
-
-			if ( m.vertexColors !== undefined ) {
-
-				if ( m.vertexColors === 'face' ) {
-
-					mpars.vertexColors = THREE.FaceColors;
-
-				} else if ( m.vertexColors ) {
-
-					mpars.vertexColors = THREE.VertexColors;
-
-				}
-
-			}
-
-			// colors
-
-			if ( m.colorDiffuse ) {
-
-				mpars.color = rgb2hex( m.colorDiffuse );
-
-			} else if ( m.DbgColor ) {
-
-				mpars.color = m.DbgColor;
-
-			}
-
-			if ( m.colorEmissive ) {
-
-				mpars.emissive = rgb2hex( m.colorEmissive );
-
-			}
-
-			if ( mtype === 'MeshPhongMaterial' ) {
-
-				if ( m.colorSpecular ) {
-
-					mpars.specular = rgb2hex( m.colorSpecular );
-
-				}
-
-				if ( m.specularCoef ) {
-
-					mpars.shininess = m.specularCoef;
-
-				}
-
-			}
-
-			// modifiers
-
-			if ( m.transparency !== undefined ) {
-
-				console.warn( 'THREE.Loader: transparency has been renamed to opacity' );
-				m.opacity = m.transparency;
-
-			}
-
-			if ( m.opacity !== undefined ) {
-
-				mpars.opacity = m.opacity;
-
-			}
-
-			// textures
-
-			if ( texturePath ) {
-
-				if ( m.mapDiffuse ) {
-
-					create_texture( mpars, 'map', m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );
-
-				}
-
-				if ( m.mapLight ) {
-
-					create_texture( mpars, 'lightMap', m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );
-
-				}
-
-				if ( m.mapAO ) {
-
-					create_texture( mpars, 'aoMap', m.mapAO, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );
-
-				}
-
-				if ( m.mapBump ) {
-
-					create_texture( mpars, 'bumpMap', m.mapBump, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );
-
-				}
-
-				if ( m.mapNormal ) {
-
-					create_texture( mpars, 'normalMap', m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );
-
-				}
-
-				if ( m.mapSpecular ) {
-
-					create_texture( mpars, 'specularMap', m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );
-
-				}
-
-				if ( m.mapAlpha ) {
+				var uuid = THREE.Math.generateUUID();
 
-					create_texture( mpars, 'alphaMap', m.mapAlpha, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );
+				textures[ uuid ] = texture;
 
-				}
+				return uuid;
 
 			}
 
 			//
 
-			if ( m.mapBumpScale ) {
-
-				mpars.bumpScale = m.mapBumpScale;
-
-			}
-
-			if ( m.mapNormalFactor ) {
-
-				mpars.normalScale = new THREE.Vector2( m.mapNormalFactor, m.mapNormalFactor );
+			var json = {
+				uuid: THREE.Math.generateUUID(),
+				type: 'MeshLambertMaterial'
+			};
+
+			for ( var name in m ) {
+
+				var value = m[ name ];
+
+				switch ( name ) {
+					case 'DbgColor':
+						json.color = value;
+						break;
+					case 'DbgIndex':
+					case 'opticalDensity':
+					case 'illumination':
+						// These were never supported
+						break;
+					case 'DbgName':
+						json.name = value;
+						break;
+					case 'blending':
+						json.blending = THREE[ value ];
+						break;
+					case 'colorDiffuse':
+						json.color = color.fromArray( value ).getHex();
+						break;
+					case 'colorSpecular':
+						json.specular = color.fromArray( value ).getHex();
+						break;
+					case 'colorEmissive':
+						json.emissive = color.fromArray( value ).getHex();
+						break;
+					case 'specularCoef':
+						json.shininess = value;
+						break;
+					case 'shading':
+						if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial';
+						if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial';
+						break;
+					case 'mapDiffuse':
+						json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );
+						break;
+					case 'mapDiffuseRepeat':
+					case 'mapDiffuseOffset':
+					case 'mapDiffuseWrap':
+					case 'mapDiffuseAnisotropy':
+						break;
+					case 'mapLight':
+						json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );
+						break;
+					case 'mapLightRepeat':
+					case 'mapLightOffset':
+					case 'mapLightWrap':
+					case 'mapLightAnisotropy':
+						break;
+					case 'mapAO':
+						json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy );
+						break;
+					case 'mapAORepeat':
+					case 'mapAOOffset':
+					case 'mapAOWrap':
+					case 'mapAOAnisotropy':
+						break;
+					case 'mapBump':
+						json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );
+						break;
+					case 'mapBumpScale':
+						json.bumpScale = value;
+						break;
+					case 'mapBumpRepeat':
+					case 'mapBumpOffset':
+					case 'mapBumpWrap':
+					case 'mapBumpAnisotropy':
+						break;
+					case 'mapNormal':
+						json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );
+						break;
+					case 'mapNormalFactor':
+						json.normalScale = [ value, value ];
+						break;
+					case 'mapNormalRepeat':
+					case 'mapNormalOffset':
+					case 'mapNormalWrap':
+					case 'mapNormalAnisotropy':
+						break;
+					case 'mapSpecular':
+						json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );
+						break;
+					case 'mapSpecularRepeat':
+					case 'mapSpecularOffset':
+					case 'mapSpecularWrap':
+					case 'mapSpecularAnisotropy':
+						break;
+					case 'mapAlpha':
+						json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy );
+						break;
+					case 'mapAlphaRepeat':
+					case 'mapAlphaOffset':
+					case 'mapAlphaWrap':
+					case 'mapAlphaAnisotropy':
+						break;
+					case 'flipSided':
+						json.side = THREE.BackSide;
+						break;
+					case 'doubleSided':
+						json.side = THREE.DoubleSide;
+						break;
+					case 'transparency':
+						console.warn( 'THREE.Loader: transparency has been renamed to opacity' );
+						json.opacity = value;
+						break;
+					case 'opacity':
+					case 'transparent':
+					case 'depthTest':
+					case 'depthWrite':
+					case 'transparent':
+					case 'visible':
+					case 'wireframe':
+						json[ name ] = value;
+						break;
+					case 'vertexColors':
+						if ( value === true ) json.vertexColors = THREE.VertexColors;
+						if ( value === 'face' ) json.vertexColors = THREE.FaceColors;
+						break;
+					default:
+						console.error( 'Loader.createMaterial: Unsupported', name, value );
+						break;
+				}
 
 			}
 
-			var material = new THREE[ mtype ]( mpars );
+			if ( json.type !== 'MeshPhongMaterial' ) delete json.specular;
+			if ( json.opacity < 1 ) json.transparent = true;
 
-			if ( m.DbgName !== undefined ) material.name = m.DbgName;
+			materialLoader.setTextures( textures );
 
-			return material;
+			return materialLoader.parse( json );
 
 		};
 
@@ -372,10 +272,12 @@ THREE.Loader.Handlers = {
 
 	get: function ( file ) {
 
-		for ( var i = 0, l = this.handlers.length; i < l; i += 2 ) {
+		var handlers = this.handlers;
+
+		for ( var i = 0, l = handlers.length; i < l; i += 2 ) {
 
-			var regex = this.handlers[ i ];
-			var loader  = this.handlers[ i + 1 ];
+			var regex = handlers[ i ];
+			var loader  = handlers[ i + 1 ];
 
 			if ( regex.test( file ) ) {
 

+ 0 - 9
src/loaders/ObjectLoader.js

@@ -258,15 +258,6 @@ THREE.ObjectLoader.prototype = {
 
 						break;
 
-					case 'TextGeometry':
-
-						geometry = new THREE.TextGeometry(
-							data.text,
-							data.data
-						);
-
-						break;
-
 					case 'BufferGeometry':
 
 						geometry = bufferGeometryLoader.parse( data );

+ 5 - 3
src/loaders/TextureLoader.js

@@ -14,13 +14,13 @@ THREE.TextureLoader.prototype = {
 
 	load: function ( url, onLoad, onProgress, onError ) {
 
-		var scope = this;
+		var texture = new THREE.Texture();
 
-		var loader = new THREE.ImageLoader( scope.manager );
+		var loader = new THREE.ImageLoader( this.manager );
 		loader.setCrossOrigin( this.crossOrigin );
 		loader.load( url, function ( image ) {
 
-			var texture = new THREE.Texture( image );
+			texture.image = image;
 			texture.needsUpdate = true;
 
 			if ( onLoad !== undefined ) {
@@ -31,6 +31,8 @@ THREE.TextureLoader.prototype = {
 
 		}, onProgress, onError );
 
+		return texture;
+
 	},
 
 	setCrossOrigin: function ( value ) {

+ 17 - 55
src/math/Color.js

@@ -105,18 +105,16 @@ THREE.Color.prototype = {
 
 	setStyle: function ( style ) {
 
-		function parseAlpha( strAlpha ) {
+		function handleAlpha( string ) {
 
-			var alpha = parseFloat( strAlpha );
+			if ( string === undefined ) return;
 
-			if ( alpha < 1 ) {
+			if ( parseFloat( string ) < 1 ) {
 
-				console.warn( 'THREE.Color: Alpha component of color ' + style + ' will be ignored.' );
+				console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
 
 			}
 
-			return alpha;
-
 		}
 
 
@@ -133,52 +131,29 @@ THREE.Color.prototype = {
 			switch ( name ) {
 
 				case 'rgb':
-
-					if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*$/.exec( components ) ) {
-
-						// rgb(255,0,0)
-						this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;
-						this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
-						this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;
-
-						return this;
-
-					}
-
-					if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*$/.exec( components ) ) {
-
-						// rgb(100%,0%,0%)
-						this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;
-						this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
-						this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;
-
-						return this;
-
-					}
-
-					break;
-
 				case 'rgba':
 
-					if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([0-9]*\.?[0-9]+)\s*$/.exec( components ) ) {
+					if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
 
-						// rgba(255,0,0,0.5)
+						// rgb(255,0,0) rgba(255,0,0,0.5)
 						this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;
 						this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
 						this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;
-						parseAlpha( color[ 4 ] );
+
+						handleAlpha( color[ 5 ] );
 
 						return this;
 
 					}
 
-					if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*([0-9]*\.?[0-9]+)\s*$/.exec( components ) ) {
+					if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
 
-						// rgba(100%,0%,0%,0.5)
+						// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
 						this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;
 						this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
 						this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;
-						parseAlpha( color[ 4 ] );
+
+						handleAlpha( color[ 5 ] );
 
 						return this;
 
@@ -187,29 +162,16 @@ THREE.Color.prototype = {
 					break;
 
 				case 'hsl':
-
-					if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*$/.exec( components ) ) {
-
-						// hsl(120,50%,50%)
-						var h = parseFloat( color[ 1 ] );
-						var s = parseInt( color[ 2 ], 10 ) / 100;
-						var l = parseInt( color[ 3 ], 10 ) / 100;
-
-						return this.setHSL( h, s, l );
-
-					}
-
-					break;
-
 				case 'hsla':
 
-					if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*([0-9]*\.?[0-9]+)\s*$/.exec( components ) ) {
+					if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
 
-						// hsla(120,50%,50%,0.5)
-						var h = parseFloat( color[ 1 ] );
+						// hsl(120,50%,50%) hsla(120,50%,50%,0.5)
+						var h = parseFloat( color[ 1 ] ) / 360;
 						var s = parseInt( color[ 2 ], 10 ) / 100;
 						var l = parseInt( color[ 3 ], 10 ) / 100;
-						parseAlpha( color[ 4 ] );
+
+						handleAlpha( color[ 5 ] );
 
 						return this.setHSL( h, s, l );
 

+ 8 - 12
src/math/Math.js

@@ -42,19 +42,9 @@ THREE.Math = {
 
 	}(),
 
-	// Clamp value to range <a, b>
+	clamp: function ( value, min, max ) {
 
-	clamp: function ( x, a, b ) {
-
-		return ( x < a ) ? a : ( ( x > b ) ? b : x );
-
-	},
-
-	// Clamp value to range <a, inf)
-
-	clampBottom: function ( x, a ) {
-
-		return x < a ? a : x;
+		return Math.max( min, Math.min( max, value ) );
 
 	},
 
@@ -162,6 +152,12 @@ THREE.Math = {
 
 	},
 
+	nearestPowerOfTwo: function ( value ) {
+
+		return Math.pow( 2, Math.round( Math.log( value ) / Math.LN2 ) );
+
+	},
+
 	nextPowerOfTwo: function ( value ) {
 
 		value --;

+ 3 - 3
src/math/Matrix4.js

@@ -341,7 +341,7 @@ THREE.Matrix4.prototype = {
 
 			z.subVectors( eye, target ).normalize();
 
-			if ( z.length() === 0 ) {
+			if ( z.lengthSq() === 0 ) {
 
 				z.z = 1;
 
@@ -349,7 +349,7 @@ THREE.Matrix4.prototype = {
 
 			x.crossVectors( up, z ).normalize();
 
-			if ( x.length() === 0 ) {
+			if ( x.lengthSq() === 0 ) {
 
 				z.x += 0.0001;
 				x.crossVectors( up, z ).normalize();
@@ -769,7 +769,7 @@ THREE.Matrix4.prototype = {
 		var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];
 		var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];
 
-		return Math.sqrt( Math.max( scaleXSq, Math.max( scaleYSq, scaleZSq ) ) );
+		return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );
 
 	},
 

+ 41 - 69
src/math/Vector2.js

@@ -174,10 +174,15 @@ THREE.Vector2.prototype = {
 
 	},
 
-	multiplyScalar: function ( s ) {
+	multiplyScalar: function ( scalar ) {
 
-		this.x *= s;
-		this.y *= s;
+		if ( isFinite( scalar ) ) {
+			this.x *= scalar;
+			this.y *= scalar;
+		} else {
+			this.x = 0;
+			this.y = 0;
+		}
 
 		return this;
 
@@ -194,37 +199,14 @@ THREE.Vector2.prototype = {
 
 	divideScalar: function ( scalar ) {
 
-		if ( scalar !== 0 ) {
-
-			var invScalar = 1 / scalar;
-
-			this.x *= invScalar;
-			this.y *= invScalar;
-
-		} else {
-
-			this.x = 0;
-			this.y = 0;
-
-		}
-
-		return this;
+		return this.multiplyScalar( 1 / scalar );
 
 	},
 
 	min: function ( v ) {
 
-		if ( this.x > v.x ) {
-
-			this.x = v.x;
-
-		}
-
-		if ( this.y > v.y ) {
-
-			this.y = v.y;
-
-		}
+		this.x = Math.min( this.x, v.x );
+		this.y = Math.min( this.y, v.y );
 
 		return this;
 
@@ -232,17 +214,8 @@ THREE.Vector2.prototype = {
 
 	max: function ( v ) {
 
-		if ( this.x < v.x ) {
-
-			this.x = v.x;
-
-		}
-
-		if ( this.y < v.y ) {
-
-			this.y = v.y;
-
-		}
+		this.x = Math.max( this.x, v.x );
+		this.y = Math.max( this.y, v.y );
 
 		return this;
 
@@ -252,25 +225,8 @@ THREE.Vector2.prototype = {
 
 		// This function assumes min < max, if this assumption isn't true it will not operate correctly
 
-		if ( this.x < min.x ) {
-
-			this.x = min.x;
-
-		} else if ( this.x > max.x ) {
-
-			this.x = max.x;
-
-		}
-
-		if ( this.y < min.y ) {
-
-			this.y = min.y;
-
-		} else if ( this.y > max.y ) {
-
-			this.y = max.y;
-
-		}
+		this.x = Math.max( min.x, Math.min( max.x, this.x ) );
+		this.y = Math.max( min.y, Math.min( max.y, this.y ) );
 
 		return this;
 
@@ -298,6 +254,16 @@ THREE.Vector2.prototype = {
 
 	}(),
 
+	clampLength: function ( min, max ) {
+
+		var length = this.length();
+
+		this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
+
+		return this;
+
+	},
+
 	floor: function () {
 
 		this.x = Math.floor( this.x );
@@ -386,17 +352,9 @@ THREE.Vector2.prototype = {
 
 	},
 
-	setLength: function ( l ) {
-
-		var oldLength = this.length();
-
-		if ( oldLength !== 0 && l !== oldLength ) {
-
-			this.multiplyScalar( l / oldLength );
+	setLength: function ( length ) {
 
-		}
-
-		return this;
+		return this.multiplyScalar( length / this.length() );
 
 	},
 
@@ -457,6 +415,20 @@ THREE.Vector2.prototype = {
 
 		return this;
 
+	},
+
+	rotateAround: function ( center, angle ) {
+
+		var c = Math.cos( angle ), s = Math.sin( angle );
+
+		var x = this.x - center.x;
+		var y = this.y - center.y;
+
+		this.x = x * c - y * s + center.x;
+		this.y = x * s + y * c + center.y;
+
+		return this;
+
 	}
 
 };

+ 31 - 93
src/math/Vector3.js

@@ -198,9 +198,15 @@ THREE.Vector3.prototype = {
 
 	multiplyScalar: function ( scalar ) {
 
-		this.x *= scalar;
-		this.y *= scalar;
-		this.z *= scalar;
+		if ( isFinite( scalar ) ) {
+			this.x *= scalar;
+			this.y *= scalar;
+			this.z *= scalar;
+		} else {
+			this.x = 0;
+			this.y = 0;
+			this.z = 0;
+		}
 
 		return this;
 
@@ -392,45 +398,15 @@ THREE.Vector3.prototype = {
 
 	divideScalar: function ( scalar ) {
 
-		if ( scalar !== 0 ) {
-
-			var invScalar = 1 / scalar;
-
-			this.x *= invScalar;
-			this.y *= invScalar;
-			this.z *= invScalar;
-
-		} else {
-
-			this.x = 0;
-			this.y = 0;
-			this.z = 0;
-
-		}
-
-		return this;
+		return this.multiplyScalar( 1 / scalar );
 
 	},
 
 	min: function ( v ) {
 
-		if ( this.x > v.x ) {
-
-			this.x = v.x;
-
-		}
-
-		if ( this.y > v.y ) {
-
-			this.y = v.y;
-
-		}
-
-		if ( this.z > v.z ) {
-
-			this.z = v.z;
-
-		}
+		this.x = Math.min( this.x, v.x );
+		this.y = Math.min( this.y, v.y );
+		this.z = Math.min( this.z, v.z );
 
 		return this;
 
@@ -438,23 +414,9 @@ THREE.Vector3.prototype = {
 
 	max: function ( v ) {
 
-		if ( this.x < v.x ) {
-
-			this.x = v.x;
-
-		}
-
-		if ( this.y < v.y ) {
-
-			this.y = v.y;
-
-		}
-
-		if ( this.z < v.z ) {
-
-			this.z = v.z;
-
-		}
+		this.x = Math.max( this.x, v.x );
+		this.y = Math.max( this.y, v.y );
+		this.z = Math.max( this.z, v.z );
 
 		return this;
 
@@ -464,35 +426,9 @@ THREE.Vector3.prototype = {
 
 		// This function assumes min < max, if this assumption isn't true it will not operate correctly
 
-		if ( this.x < min.x ) {
-
-			this.x = min.x;
-
-		} else if ( this.x > max.x ) {
-
-			this.x = max.x;
-
-		}
-
-		if ( this.y < min.y ) {
-
-			this.y = min.y;
-
-		} else if ( this.y > max.y ) {
-
-			this.y = max.y;
-
-		}
-
-		if ( this.z < min.z ) {
-
-			this.z = min.z;
-
-		} else if ( this.z > max.z ) {
-
-			this.z = max.z;
-
-		}
+		this.x = Math.max( min.x, Math.min( max.x, this.x ) );
+		this.y = Math.max( min.y, Math.min( max.y, this.y ) );
+		this.z = Math.max( min.z, Math.min( max.z, this.z ) );
 
 		return this;
 
@@ -520,6 +456,16 @@ THREE.Vector3.prototype = {
 
 	}(),
 
+	clampLength: function ( min, max ) {
+
+		var length = this.length();
+
+		this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length );
+
+		return this;
+
+	},
+
 	floor: function () {
 
 		this.x = Math.floor( this.x );
@@ -600,17 +546,9 @@ THREE.Vector3.prototype = {
 
 	},
 
-	setLength: function ( l ) {
-
-		var oldLength = this.length();
-
-		if ( oldLength !== 0 && l !== oldLength  ) {
+	setLength: function ( length ) {
 
-			this.multiplyScalar( l / oldLength );
-
-		}
-
-		return this;
+		return this.multiplyScalar( length / this.length() );
 
 	},
 

+ 26 - 118
src/math/Vector4.js

@@ -200,10 +200,17 @@ THREE.Vector4.prototype = {
 
 	multiplyScalar: function ( scalar ) {
 
-		this.x *= scalar;
-		this.y *= scalar;
-		this.z *= scalar;
-		this.w *= scalar;
+		if ( isFinite( scalar ) ) {
+			this.x *= scalar;
+			this.y *= scalar;
+			this.z *= scalar;
+			this.w *= scalar;
+		} else {
+			this.x = 0;
+			this.y = 0;
+			this.z = 0;
+			this.w = 0;
+		}
 
 		return this;
 
@@ -229,25 +236,7 @@ THREE.Vector4.prototype = {
 
 	divideScalar: function ( scalar ) {
 
-		if ( scalar !== 0 ) {
-
-			var invScalar = 1 / scalar;
-
-			this.x *= invScalar;
-			this.y *= invScalar;
-			this.z *= invScalar;
-			this.w *= invScalar;
-
-		} else {
-
-			this.x = 0;
-			this.y = 0;
-			this.z = 0;
-			this.w = 1;
-
-		}
-
-		return this;
+		return this.multiplyScalar( 1 / scalar );
 
 	},
 
@@ -411,29 +400,10 @@ THREE.Vector4.prototype = {
 
 	min: function ( v ) {
 
-		if ( this.x > v.x ) {
-
-			this.x = v.x;
-
-		}
-
-		if ( this.y > v.y ) {
-
-			this.y = v.y;
-
-		}
-
-		if ( this.z > v.z ) {
-
-			this.z = v.z;
-
-		}
-
-		if ( this.w > v.w ) {
-
-			this.w = v.w;
-
-		}
+		this.x = Math.min( this.x, v.x );
+		this.y = Math.min( this.y, v.y );
+		this.z = Math.min( this.z, v.z );
+		this.w = Math.min( this.w, v.w );
 
 		return this;
 
@@ -441,29 +411,10 @@ THREE.Vector4.prototype = {
 
 	max: function ( v ) {
 
-		if ( this.x < v.x ) {
-
-			this.x = v.x;
-
-		}
-
-		if ( this.y < v.y ) {
-
-			this.y = v.y;
-
-		}
-
-		if ( this.z < v.z ) {
-
-			this.z = v.z;
-
-		}
-
-		if ( this.w < v.w ) {
-
-			this.w = v.w;
-
-		}
+		this.x = Math.max( this.x, v.x );
+		this.y = Math.max( this.y, v.y );
+		this.z = Math.max( this.z, v.z );
+		this.w = Math.max( this.w, v.w );
 
 		return this;
 
@@ -473,45 +424,10 @@ THREE.Vector4.prototype = {
 
 		// This function assumes min < max, if this assumption isn't true it will not operate correctly
 
-		if ( this.x < min.x ) {
-
-			this.x = min.x;
-
-		} else if ( this.x > max.x ) {
-
-			this.x = max.x;
-
-		}
-
-		if ( this.y < min.y ) {
-
-			this.y = min.y;
-
-		} else if ( this.y > max.y ) {
-
-			this.y = max.y;
-
-		}
-
-		if ( this.z < min.z ) {
-
-			this.z = min.z;
-
-		} else if ( this.z > max.z ) {
-
-			this.z = max.z;
-
-		}
-
-		if ( this.w < min.w ) {
-
-			this.w = min.w;
-
-		} else if ( this.w > max.w ) {
-
-			this.w = max.w;
-
-		}
+		this.x = Math.max( min.x, Math.min( max.x, this.x ) );
+		this.y = Math.max( min.y, Math.min( max.y, this.y ) );
+		this.z = Math.max( min.z, Math.min( max.z, this.z ) );
+		this.w = Math.max( min.w, Math.min( max.w, this.w ) );
 
 		return this;
 
@@ -624,17 +540,9 @@ THREE.Vector4.prototype = {
 
 	},
 
-	setLength: function ( l ) {
-
-		var oldLength = this.length();
-
-		if ( oldLength !== 0 && l !== oldLength ) {
+	setLength: function ( length ) {
 
-			this.multiplyScalar( l / oldLength );
-
-		}
-
-		return this;
+		return this.multiplyScalar( length / this.length() );
 
 	},
 

+ 111 - 64
src/renderers/WebGLRenderer.js

@@ -1105,7 +1105,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		sprites.length = 0;
 		lensFlares.length = 0;
 
-		projectObject( scene );
+		projectObject( scene, camera );
 
 		opaqueObjects.length = opaqueObjectsLastIndex + 1;
 		transparentObjects.length = transparentObjectsLastIndex + 1;
@@ -1168,7 +1168,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		if ( renderTarget ) {
 
 			var texture = renderTarget.texture;
-			var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
+			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
 			if ( texture.generateMipmaps && isTargetPowerOfTwo && texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {
 
 				 updateRenderTargetMipmap( renderTarget );
@@ -1236,77 +1236,81 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	}
 
-	function projectObject( object ) {
+	function projectObject( object, camera ) {
 
 		if ( object.visible === false ) return;
 
-		if ( object instanceof THREE.Light ) {
+		if ( ( object.channels.mask & camera.channels.mask ) !== 0 ) {
 
-			lights.push( object );
+			if ( object instanceof THREE.Light ) {
 
-		} else if ( object instanceof THREE.Sprite ) {
+				lights.push( object );
 
-			sprites.push( object );
+			} else if ( object instanceof THREE.Sprite ) {
 
-		} else if ( object instanceof THREE.LensFlare ) {
+				sprites.push( object );
 
-			lensFlares.push( object );
+			} else if ( object instanceof THREE.LensFlare ) {
 
-		} else if ( object instanceof THREE.ImmediateRenderObject ) {
+				lensFlares.push( object );
 
-			if ( _this.sortObjects === true ) {
+			} else if ( object instanceof THREE.ImmediateRenderObject ) {
 
-				_vector3.setFromMatrixPosition( object.matrixWorld );
-				_vector3.applyProjection( _projScreenMatrix );
+				if ( _this.sortObjects === true ) {
 
-			}
+					_vector3.setFromMatrixPosition( object.matrixWorld );
+					_vector3.applyProjection( _projScreenMatrix );
 
-			pushRenderItem( object, null, object.material, _vector3.z, null );
+				}
 
-		} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Points ) {
+				pushRenderItem( object, null, object.material, _vector3.z, null );
 
-			if ( object instanceof THREE.SkinnedMesh ) {
+			} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Points ) {
 
-				object.skeleton.update();
+				if ( object instanceof THREE.SkinnedMesh ) {
 
-			}
+					object.skeleton.update();
 
-			if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
+				}
 
-				var material = object.material;
+				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
 
-				if ( material.visible === true ) {
+					var material = object.material;
 
-					if ( _this.sortObjects === true ) {
+					if ( material.visible === true ) {
 
-						_vector3.setFromMatrixPosition( object.matrixWorld );
-						_vector3.applyProjection( _projScreenMatrix );
+						if ( _this.sortObjects === true ) {
 
-					}
+							_vector3.setFromMatrixPosition( object.matrixWorld );
+							_vector3.applyProjection( _projScreenMatrix );
+
+						}
 
-					var geometry = objects.update( object );
+						var geometry = objects.update( object );
 
-					if ( material instanceof THREE.MeshFaceMaterial ) {
+						if ( material instanceof THREE.MeshFaceMaterial ) {
 
-						var groups = geometry.groups;
-						var materials = material.materials;
+							var groups = geometry.groups;
+							var materials = material.materials;
 
-						for ( var i = 0, l = groups.length; i < l; i ++ ) {
+							for ( var i = 0, l = groups.length; i < l; i ++ ) {
 
-							var group = groups[ i ];
-							var groupMaterial = materials[ group.materialIndex ];
+								var group = groups[ i ];
+								var groupMaterial = materials[ group.materialIndex ];
 
-							if ( groupMaterial.visible === true ) {
+								if ( groupMaterial.visible === true ) {
 
-								pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );
+									pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );
+
+								}
 
 							}
 
-						}
+						} else {
 
-					} else {
+							pushRenderItem( object, geometry, material, _vector3.z, null );
 
-						pushRenderItem( object, geometry, material, _vector3.z, null );
+						}
 
 					}
 
@@ -1320,7 +1324,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		for ( var i = 0, l = children.length; i < l; i ++ ) {
 
-			projectObject( children[ i ] );
+			projectObject( children[ i ], camera );
 
 		}
 
@@ -1988,34 +1992,36 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 				var light = lights[ i ];
 
-				if ( light.castShadow === false ) continue;
+				if ( light.castShadow === true ) {
 
-				if ( light instanceof THREE.PointLight || light instanceof THREE.SpotLight || light instanceof THREE.DirectionalLight ) {
+					if ( light instanceof THREE.PointLight || light instanceof THREE.SpotLight || light instanceof THREE.DirectionalLight ) {
 
-					var shadow = light.shadow;
+						var shadow = light.shadow;
 
-					if ( light instanceof THREE.PointLight ) {
+						if ( light instanceof THREE.PointLight ) {
 
-						// for point lights we set the shadow matrix to be a translation-only matrix
-						// equal to inverse of the light's position
-						_vector3.setFromMatrixPosition( light.matrixWorld ).negate();
-						shadow.matrix.identity().setPosition( _vector3 );
+							// for point lights we set the shadow matrix to be a translation-only matrix
+							// equal to inverse of the light's position
+							_vector3.setFromMatrixPosition( light.matrixWorld ).negate();
+							shadow.matrix.identity().setPosition( _vector3 );
 
-						// for point lights we set the sign of the shadowDarkness uniform to be negative
-						uniforms.shadowDarkness.value[ j ] = - shadow.darkness;
+							// for point lights we set the sign of the shadowDarkness uniform to be negative
+							uniforms.shadowDarkness.value[ j ] = - shadow.darkness;
 
-					} else {
+						} else {
 
-						uniforms.shadowDarkness.value[ j ] = shadow.darkness;
+							uniforms.shadowDarkness.value[ j ] = shadow.darkness;
 
-					}
+						}
+
+						uniforms.shadowMatrix.value[ j ] = shadow.matrix;
+						uniforms.shadowMap.value[ j ] = shadow.map;
+						uniforms.shadowMapSize.value[ j ] = shadow.mapSize;
+						uniforms.shadowBias.value[ j ] = shadow.bias;
 
-					uniforms.shadowMatrix.value[ j ] = shadow.matrix;
-					uniforms.shadowMap.value[ j ] = shadow.map;
-					uniforms.shadowMapSize.value[ j ] = shadow.mapSize;
-					uniforms.shadowBias.value[ j ] = shadow.bias;
+						j ++;
 
-					j ++;
+					}
 
 				}
 
@@ -2666,7 +2672,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) {
 
-				console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( ' + texture.sourceFile + ' )' );
+				console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );
 
 			}
 
@@ -2675,7 +2681,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {
 
-				console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ' + texture.sourceFile + ' )' );
+				console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );
 
 			}
 
@@ -2705,8 +2711,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			textureProperties.__webglInit = true;
 
-			texture.__webglInit = true;
-
 			texture.addEventListener( 'dispose', onTextureDispose );
 
 			textureProperties.__webglTexture = _gl.createTexture();
@@ -2724,8 +2728,14 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
 
+		if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false ) {
+
+			texture.image = makePowerOfTwo( texture.image );
+
+		}
+
 		var image = texture.image,
-		isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
+		isImagePowerOfTwo = isPowerOfTwo( image ),
 		glFormat = paramThreeToGL( texture.format ),
 		glType = paramThreeToGL( texture.type );
 
@@ -2840,6 +2850,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			}
 
 			uploadTexture( textureProperties, texture, slot );
+
 			return;
 
 		}
@@ -2875,6 +2886,42 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	}
 
+	function isPowerOfTwo( image ) {
+
+		return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );
+
+	}
+
+	function textureNeedsPowerOfTwo( texture ) {
+
+		if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) return true;
+		if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) return true;
+
+		return false;
+
+	}
+
+	function makePowerOfTwo( image ) {
+
+		if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {
+
+			var canvas = document.createElement( 'canvas' );
+			canvas.width = THREE.Math.nearestPowerOfTwo( image.width );
+			canvas.height = THREE.Math.nearestPowerOfTwo( image.height );
+
+			var context = canvas.getContext( '2d' );
+			context.drawImage( image, 0, 0, canvas.width, canvas.height );
+
+			console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
+
+			return canvas;
+
+		}
+
+		return image;
+
+	}
+
 	function setCubeTexture ( texture, slot ) {
 
 		var textureProperties = properties.get( texture );
@@ -2918,7 +2965,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 				}
 
 				var image = cubeImage[ 0 ],
-				isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
+				isImagePowerOfTwo = isPowerOfTwo( image ),
 				glFormat = paramThreeToGL( texture.format ),
 				glType = paramThreeToGL( texture.type );
 
@@ -3056,7 +3103,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			// Setup texture, create render and frame buffers
 
-			var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height ),
+			var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ),
 				glFormat = paramThreeToGL( renderTarget.texture.format ),
 				glType = paramThreeToGL( renderTarget.texture.type );
 

+ 8 - 2
src/renderers/shaders/ShaderLib.js

@@ -15,7 +15,8 @@ THREE.ShaderLib = {
 
 			THREE.UniformsLib[ "common" ],
 			THREE.UniformsLib[ "aomap" ],
-			THREE.UniformsLib[ "fog" ]
+			THREE.UniformsLib[ "fog" ],
+			THREE.UniformsLib[ "shadowmap" ]
 
 		] ),
 
@@ -28,6 +29,7 @@ THREE.ShaderLib = {
 			THREE.ShaderChunk[ "color_pars_vertex" ],
 			THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
 			THREE.ShaderChunk[ "skinning_pars_vertex" ],
+			THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
 			THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
 
 			"void main() {",
@@ -54,6 +56,7 @@ THREE.ShaderLib = {
 
 				THREE.ShaderChunk[ "worldpos_vertex" ],
 				THREE.ShaderChunk[ "envmap_vertex" ],
+				THREE.ShaderChunk[ "shadowmap_vertex" ],
 
 			"}"
 
@@ -73,6 +76,7 @@ THREE.ShaderLib = {
 			THREE.ShaderChunk[ "aomap_pars_fragment" ],
 			THREE.ShaderChunk[ "envmap_pars_fragment" ],
 			THREE.ShaderChunk[ "fog_pars_fragment" ],
+			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "specularmap_pars_fragment" ],
 			THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
 
@@ -81,6 +85,7 @@ THREE.ShaderLib = {
 			"	vec3 outgoingLight = vec3( 0.0 );",
 			"	vec4 diffuseColor = vec4( diffuse, opacity );",
 			"	vec3 totalAmbientLight = vec3( 1.0 );", // hardwired
+			"	vec3 shadowMask = vec3( 1.0 );",
 
 				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
 				THREE.ShaderChunk[ "map_fragment" ],
@@ -89,8 +94,9 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "alphatest_fragment" ],
 				THREE.ShaderChunk[ "specularmap_fragment" ],
 				THREE.ShaderChunk[ "aomap_fragment" ],
+				THREE.ShaderChunk[ "shadowmap_fragment" ],
 
-			"	outgoingLight = diffuseColor.rgb * totalAmbientLight;",
+			"	outgoingLight = diffuseColor.rgb * totalAmbientLight * shadowMask;",
 
 				THREE.ShaderChunk[ "envmap_fragment" ],
 

+ 121 - 119
src/renderers/webgl/WebGLShadowMap.js

@@ -118,178 +118,180 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 			var light = _lights[ i ];
 
-			if ( light.castShadow === false ) continue;
-
-			var shadow = light.shadow;
-			var shadowCamera = shadow.camera;
-			var shadowMapSize = shadow.mapSize;
-
-			if ( light instanceof THREE.PointLight ) {
-
-				faceCount = 6;
-				isPointLight = true;
-
-				var vpWidth = shadowMapSize.x / 4.0;
-				var vpHeight = shadowMapSize.y / 2.0;
-
-				// These viewports map a cube-map onto a 2D texture with the
-				// following orientation:
-				//
-				//  xzXZ
-				//   y Y
-				//
-				// X - Positive x direction
-				// x - Negative x direction
-				// Y - Positive y direction
-				// y - Negative y direction
-				// Z - Positive z direction
-				// z - Negative z direction
-
-				// positive X
-				cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );
-				// negative X
-				cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );
-				// positive Z
-				cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );
-				// negative Z
-				cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );
-				// positive Y
-				cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );
-				// negative Y
-				cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );
-
-			} else {
-
-				faceCount = 1;
-				isPointLight = false;
+			if ( light.castShadow === true ) {
+
+				var shadow = light.shadow;
+				var shadowCamera = shadow.camera;
+				var shadowMapSize = shadow.mapSize;
+
+				if ( light instanceof THREE.PointLight ) {
+
+					faceCount = 6;
+					isPointLight = true;
+
+					var vpWidth = shadowMapSize.x / 4.0;
+					var vpHeight = shadowMapSize.y / 2.0;
+
+					// These viewports map a cube-map onto a 2D texture with the
+					// following orientation:
+					//
+					//  xzXZ
+					//   y Y
+					//
+					// X - Positive x direction
+					// x - Negative x direction
+					// Y - Positive y direction
+					// y - Negative y direction
+					// Z - Positive z direction
+					// z - Negative z direction
+
+					// positive X
+					cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight );
+					// negative X
+					cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight );
+					// positive Z
+					cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight );
+					// negative Z
+					cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight );
+					// positive Y
+					cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight );
+					// negative Y
+					cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight );
 
-			}
+				} else {
 
-			if ( shadow.map === null ) {
+					faceCount = 1;
+					isPointLight = false;
 
-				var shadowFilter = THREE.LinearFilter;
+				}
 
-				if ( scope.type === THREE.PCFSoftShadowMap ) {
+				if ( shadow.map === null ) {
 
-					shadowFilter = THREE.NearestFilter;
+					var shadowFilter = THREE.LinearFilter;
 
-				}
+					if ( scope.type === THREE.PCFSoftShadowMap ) {
 
-				var pars = { minFilter: shadowFilter, magFilter: shadowFilter, format: THREE.RGBAFormat };
+						shadowFilter = THREE.NearestFilter;
 
-				shadow.map = new THREE.WebGLRenderTarget( shadowMapSize.x, shadowMapSize.y, pars );
-				shadow.matrix = new THREE.Matrix4();
+					}
 
-				//
+					var pars = { minFilter: shadowFilter, magFilter: shadowFilter, format: THREE.RGBAFormat };
 
-				if ( light instanceof THREE.SpotLight ) {
+					shadow.map = new THREE.WebGLRenderTarget( shadowMapSize.x, shadowMapSize.y, pars );
+					shadow.matrix = new THREE.Matrix4();
 
-					shadowCamera.aspect = shadowMapSize.x / shadowMapSize.y;
+					//
 
-				}
+					if ( light instanceof THREE.SpotLight ) {
 
-				shadowCamera.updateProjectionMatrix();
+						shadowCamera.aspect = shadowMapSize.x / shadowMapSize.y;
 
-			}
+					}
 
-			var shadowMap = shadow.map;
-			var shadowMatrix = shadow.matrix;
+					shadowCamera.updateProjectionMatrix();
 
-			_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
-			shadowCamera.position.copy( _lightPositionWorld );
+				}
 
-			_renderer.setRenderTarget( shadowMap );
-			_renderer.clear();
+				var shadowMap = shadow.map;
+				var shadowMatrix = shadow.matrix;
 
-			// render shadow map for each cube face (if omni-directional) or
-			// run a single pass if not
+				_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
+				shadowCamera.position.copy( _lightPositionWorld );
 
-			for ( var face = 0; face < faceCount; face ++ ) {
+				_renderer.setRenderTarget( shadowMap );
+				_renderer.clear();
 
-				if ( isPointLight ) {
+				// render shadow map for each cube face (if omni-directional) or
+				// run a single pass if not
 
-					_lookTarget.copy( shadowCamera.position );
-					_lookTarget.add( cubeDirections[ face ] );
-					shadowCamera.up.copy( cubeUps[ face ] );
-					shadowCamera.lookAt( _lookTarget );
-					var vpDimensions = cube2DViewPorts[ face ];
-					_renderer.setViewport( vpDimensions.x, vpDimensions.y, vpDimensions.z, vpDimensions.w );
+				for ( var face = 0; face < faceCount; face ++ ) {
 
-				} else {
+					if ( isPointLight ) {
 
-					_lookTarget.setFromMatrixPosition( light.target.matrixWorld );
-					shadowCamera.lookAt( _lookTarget );
+						_lookTarget.copy( shadowCamera.position );
+						_lookTarget.add( cubeDirections[ face ] );
+						shadowCamera.up.copy( cubeUps[ face ] );
+						shadowCamera.lookAt( _lookTarget );
+						var vpDimensions = cube2DViewPorts[ face ];
+						_renderer.setViewport( vpDimensions.x, vpDimensions.y, vpDimensions.z, vpDimensions.w );
 
-				}
+					} else {
+
+						_lookTarget.setFromMatrixPosition( light.target.matrixWorld );
+						shadowCamera.lookAt( _lookTarget );
+
+					}
+
+					shadowCamera.updateMatrixWorld();
+					shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
 
-				shadowCamera.updateMatrixWorld();
-				shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
+					// compute shadow matrix
 
-				// compute shadow matrix
+					shadowMatrix.set(
+						0.5, 0.0, 0.0, 0.5,
+						0.0, 0.5, 0.0, 0.5,
+						0.0, 0.0, 0.5, 0.5,
+						0.0, 0.0, 0.0, 1.0
+					);
 
-				shadowMatrix.set(
-					0.5, 0.0, 0.0, 0.5,
-					0.0, 0.5, 0.0, 0.5,
-					0.0, 0.0, 0.5, 0.5,
-					0.0, 0.0, 0.0, 1.0
-				);
+					shadowMatrix.multiply( shadowCamera.projectionMatrix );
+					shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
 
-				shadowMatrix.multiply( shadowCamera.projectionMatrix );
-				shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
+					// update camera matrices and frustum
 
-				// update camera matrices and frustum
+					_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
+					_frustum.setFromMatrix( _projScreenMatrix );
 
-				_projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
-				_frustum.setFromMatrix( _projScreenMatrix );
+					// set object matrices & frustum culling
 
-				// set object matrices & frustum culling
+					_renderList.length = 0;
 
-				_renderList.length = 0;
+					projectObject( scene, shadowCamera );
 
-				projectObject( scene, shadowCamera );
+					// render shadow map
+					// render regular objects
 
-				// render shadow map
-				// render regular objects
+					for ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {
 
-				for ( var j = 0, jl = _renderList.length; j < jl; j ++ ) {
+						var object = _renderList[ j ];
+						var geometry = _objects.update( object );
+						var material = object.material;
 
-					var object = _renderList[ j ];
-					var geometry = _objects.update( object );
-					var material = object.material;
+						if ( material instanceof THREE.MeshFaceMaterial ) {
 
-					if ( material instanceof THREE.MeshFaceMaterial ) {
+							var groups = geometry.groups;
+							var materials = material.materials;
 
-						var groups = geometry.groups;
-						var materials = material.materials;
+							for ( var k = 0, kl = groups.length; k < kl; k ++ ) {
 
-						for ( var k = 0, kl = groups.length; k < kl; k ++ ) {
+								var group = groups[ k ];
+								var groupMaterial = materials[ group.materialIndex ];
 
-							var group = groups[ k ];
-							var groupMaterial = materials[ group.materialIndex ];
+								if ( groupMaterial.visible === true ) {
 
-							if ( groupMaterial.visible === true ) {
+									var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );
+									_renderer.renderBufferDirect( shadowCamera, _lights, null, geometry, depthMaterial, object, group );
 
-								var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld );
-								_renderer.renderBufferDirect( shadowCamera, _lights, null, geometry, depthMaterial, object, group );
+								}
 
 							}
 
-						}
+						} else {
 
-					} else {
+							var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );
+							_renderer.renderBufferDirect( shadowCamera, _lights, null, geometry, depthMaterial, object, null );
 
-						var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld );
-						_renderer.renderBufferDirect( shadowCamera, _lights, null, geometry, depthMaterial, object, null );
+						}
 
 					}
 
 				}
 
-			}
+				// We must call _renderer.resetGLState() at the end of each iteration of
+				// the light loop in order to force material updates for each light.
+				_renderer.resetGLState();
 
-			//We must call _renderer.resetGLState() at the end of each iteration of
-			// the light loop in order to force material updates for each light.
-			_renderer.resetGLState();
+			}
 
 		}
 

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

@@ -18,6 +18,7 @@
 	"src/math/Math.js",
 	"src/math/Spline.js",
 	"src/math/Triangle.js",
+	"src/core/Channels.js",
 	"src/core/Clock.js",
 	"src/core/EventDispatcher.js",
 	"src/core/Raycaster.js",
@@ -65,6 +66,7 @@
 	"src/loaders/MaterialLoader.js",
 	"src/loaders/ObjectLoader.js",
 	"src/loaders/TextureLoader.js",
+	"src/loaders/CubeTextureLoader.js",	
 	"src/loaders/BinaryTextureLoader.js",
 	"src/loaders/CompressedTextureLoader.js",
 	"src/materials/Material.js",

+ 2 - 2
utils/build/includes/extras.json

@@ -1,8 +1,9 @@
 [
+	"src/extras/CurveUtils.js",
 	"src/extras/GeometryUtils.js",
 	"src/extras/ImageUtils.js",
 	"src/extras/SceneUtils.js",
-	"src/extras/FontUtils.js",
+	"src/extras/ShapeUtils.js",
 	"src/extras/audio/Audio.js",
 	"src/extras/audio/AudioListener.js",
 	"src/extras/core/Curve.js",
@@ -34,7 +35,6 @@
 	"src/extras/geometries/RingGeometry.js",
 	"src/extras/geometries/SphereGeometry.js",
 	"src/extras/geometries/SphereBufferGeometry.js",
-	"src/extras/geometries/TextGeometry.js",
 	"src/extras/geometries/TorusGeometry.js",
 	"src/extras/geometries/TorusKnotGeometry.js",
 	"src/extras/geometries/TubeGeometry.js",

+ 1 - 0
utils/exporters/max/ThreeJSAnimationExporter.ms

@@ -1303,6 +1303,7 @@ rollout ThreeJSExporter "ThreeJSExporter"
 			
 			max modify mode
 			
+			modPanel.setCurrentObject node.modifiers[#skin]
 			total_bones = skinops.getnumberbones node.modifiers[#skin]
 			
 			vertex_count = getNumverts node

+ 12 - 2
utils/exporters/max/ThreeJSExporter_MorphTargets_v0.ms

@@ -115,10 +115,20 @@ function eav_get_range_from_mods_con obj &i_t1 &i_t2 =
 		for pr in props do
 		(
 			mod_con = (getPropertyController cmod pr)
-			
+		
+			--format "% = % (Animatable - %)\n" pr mod_con	(isPropertyAnimatable obj pr)	
 			if mod_con == undefined then
 			(
-				continue
+				if cmod.name == "Morpher" then
+				(
+					format "% = %" pr cmod[pr]
+					mod_con = cmod[pr]
+				)
+				
+				if mod_con == undefined then
+				(
+					continue
+				)
 			)
 			
 			if mod_con.keys.count <= 0 then

Some files were not shown because too many files changed in this diff