diff --git a/docs/examples/24/dat-gui/dat.gui.min.js b/docs/examples/24/dat-gui/dat.gui.min.js new file mode 100644 index 00000000..3543875a --- /dev/null +++ b/docs/examples/24/dat-gui/dat.gui.min.js @@ -0,0 +1,98 @@ +/** + * dat-gui JavaScript Controller Library + * http://code.google.com/p/dat-gui + * + * Copyright 2011 Data Arts Team, Google Creative Lab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Modification for Qgis2threejs: + * - Fix for local files with IE (Line 61, Column 123). + */ + +var dat=dat||{};dat.gui=dat.gui||{};dat.utils=dat.utils||{};dat.controllers=dat.controllers||{};dat.dom=dat.dom||{};dat.color=dat.color||{};dat.utils.css=function(){return{load:function(e,a){a=a||document;var b=a.createElement("link");b.type="text/css";b.rel="stylesheet";b.href=e;a.getElementsByTagName("head")[0].appendChild(b)},inject:function(e,a){a=a||document;var b=document.createElement("style");b.type="text/css";b.innerHTML=e;a.getElementsByTagName("head")[0].appendChild(b)}}}(); +dat.utils.common=function(){var e=Array.prototype.forEach,a=Array.prototype.slice;return{BREAK:{},extend:function(b){this.each(a.call(arguments,1),function(a){for(var f in a)this.isUndefined(a[f])||(b[f]=a[f])},this);return b},defaults:function(b){this.each(a.call(arguments,1),function(a){for(var f in a)this.isUndefined(b[f])&&(b[f]=a[f])},this);return b},compose:function(){var b=a.call(arguments);return function(){for(var d=a.call(arguments),f=b.length-1;0<=f;f--)d=[b[f].apply(this,d)];return d[0]}}, +each:function(a,d,f){if(e&&a.forEach===e)a.forEach(d,f);else if(a.length===a.length+0)for(var c=0,p=a.length;cthis.__max&&(a=this.__max);void 0!==this.__step&&0!=a%this.__step&&(a=Math.round(a/this.__step)*this.__step);return b.superclass.prototype.setValue.call(this,a)},min:function(a){this.__min=a;return this},max:function(a){this.__max=a;return this},step:function(a){this.__step=a;return this}});return b}(dat.controllers.Controller,dat.utils.common); +dat.controllers.NumberControllerBox=function(e,a,b){var d=function(f,c,e){function k(){var a=parseFloat(n.__input.value);b.isNaN(a)||n.setValue(a)}function l(a){var c=r-a.clientY;n.setValue(n.getValue()+c*n.__impliedStep);r=a.clientY}function q(){a.unbind(window,"mousemove",l);a.unbind(window,"mouseup",q)}this.__truncationSuspended=!1;d.superclass.call(this,f,c,e);var n=this,r;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"change",k);a.bind(this.__input, +"blur",function(){k();n.__onFinishChange&&n.__onFinishChange.call(n,n.getValue())});a.bind(this.__input,"mousedown",function(c){a.bind(window,"mousemove",l);a.bind(window,"mouseup",q);r=c.clientY});a.bind(this.__input,"keydown",function(a){13===a.keyCode&&(n.__truncationSuspended=!0,this.blur(),n.__truncationSuspended=!1)});this.updateDisplay();this.domElement.appendChild(this.__input)};d.superclass=e;b.extend(d.prototype,e.prototype,{updateDisplay:function(){var a=this.__input,c;if(this.__truncationSuspended)c= +this.getValue();else{c=this.getValue();var b=Math.pow(10,this.__precision);c=Math.round(c*b)/b}a.value=c;return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common); +dat.controllers.NumberControllerSlider=function(e,a,b,d,f){function c(a,c,d,b,f){return b+(a-c)/(d-c)*(f-b)}var p=function(d,b,f,e,r){function y(d){d.preventDefault();var b=a.getOffset(h.__background),f=a.getWidth(h.__background);h.setValue(c(d.clientX,b.left,b.left+f,h.__min,h.__max));return!1}function g(){a.unbind(window,"mousemove",y);a.unbind(window,"mouseup",g);h.__onFinishChange&&h.__onFinishChange.call(h,h.getValue())}p.superclass.call(this,d,b,{min:f,max:e,step:r});var h=this;this.__background= +document.createElement("div");this.__foreground=document.createElement("div");a.bind(this.__background,"mousedown",function(c){a.bind(window,"mousemove",y);a.bind(window,"mouseup",g);y(c)});a.addClass(this.__background,"slider");a.addClass(this.__foreground,"slider-fg");this.updateDisplay();this.__background.appendChild(this.__foreground);this.domElement.appendChild(this.__background)};p.superclass=e;p.useDefaultStyles=function(){b.inject(f)};d.extend(p.prototype,e.prototype,{updateDisplay:function(){var a= +(this.getValue()-this.__min)/(this.__max-this.__min);this.__foreground.style.width=100*a+"%";return p.superclass.prototype.updateDisplay.call(this)}});return p}(dat.controllers.NumberController,dat.dom.dom,dat.utils.css,dat.utils.common,"/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n.slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}"); +dat.controllers.FunctionController=function(e,a,b){var d=function(b,c,e){d.superclass.call(this,b,c);var k=this;this.__button=document.createElement("div");this.__button.innerHTML=void 0===e?"Fire":e;a.bind(this.__button,"click",function(a){a.preventDefault();k.fire();return!1});a.addClass(this.__button,"button");this.domElement.appendChild(this.__button)};d.superclass=e;b.extend(d.prototype,e.prototype,{fire:function(){this.__onChange&&this.__onChange.call(this);this.__onFinishChange&&this.__onFinishChange.call(this, +this.getValue());this.getValue().call(this.object)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); +dat.controllers.BooleanController=function(e,a,b){var d=function(b,c){d.superclass.call(this,b,c);var e=this;this.__prev=this.getValue();this.__checkbox=document.createElement("input");this.__checkbox.setAttribute("type","checkbox");a.bind(this.__checkbox,"change",function(){e.setValue(!e.__prev)},!1);this.domElement.appendChild(this.__checkbox);this.updateDisplay()};d.superclass=e;b.extend(d.prototype,e.prototype,{setValue:function(a){a=d.superclass.prototype.setValue.call(this,a);this.__onFinishChange&& +this.__onFinishChange.call(this,this.getValue());this.__prev=this.getValue();return a},updateDisplay:function(){!0===this.getValue()?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=!0):this.__checkbox.checked=!1;return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); +dat.color.toString=function(e){return function(a){if(1==a.a||e.isUndefined(a.a)){for(a=a.hex.toString(16);6>a.length;)a="0"+a;return"#"+a}return"rgba("+Math.round(a.r)+","+Math.round(a.g)+","+Math.round(a.b)+","+a.a+")"}}(dat.utils.common); +dat.color.interpret=function(e,a){var b,d,f=[{litmus:a.isString,conversions:{THREE_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);return null===a?!1:{space:"HEX",hex:parseInt("0x"+a[1].toString()+a[1].toString()+a[2].toString()+a[2].toString()+a[3].toString()+a[3].toString())}},write:e},SIX_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9]{6})$/i);return null===a?!1:{space:"HEX",hex:parseInt("0x"+a[1].toString())}},write:e},CSS_RGB:{read:function(a){a=a.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/); +return null===a?!1:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3])}},write:e},CSS_RGBA:{read:function(a){a=a.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);return null===a?!1:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3]),a:parseFloat(a[4])}},write:e}}},{litmus:a.isNumber,conversions:{HEX:{read:function(a){return{space:"HEX",hex:a,conversionName:"HEX"}},write:function(a){return a.hex}}}},{litmus:a.isArray,conversions:{RGB_ARRAY:{read:function(a){return 3!= +a.length?!1:{space:"RGB",r:a[0],g:a[1],b:a[2]}},write:function(a){return[a.r,a.g,a.b]}},RGBA_ARRAY:{read:function(a){return 4!=a.length?!1:{space:"RGB",r:a[0],g:a[1],b:a[2],a:a[3]}},write:function(a){return[a.r,a.g,a.b,a.a]}}}},{litmus:a.isObject,conversions:{RGBA_OBJ:{read:function(c){return a.isNumber(c.r)&&a.isNumber(c.g)&&a.isNumber(c.b)&&a.isNumber(c.a)?{space:"RGB",r:c.r,g:c.g,b:c.b,a:c.a}:!1},write:function(a){return{r:a.r,g:a.g,b:a.b,a:a.a}}},RGB_OBJ:{read:function(c){return a.isNumber(c.r)&& +a.isNumber(c.g)&&a.isNumber(c.b)?{space:"RGB",r:c.r,g:c.g,b:c.b}:!1},write:function(a){return{r:a.r,g:a.g,b:a.b}}},HSVA_OBJ:{read:function(c){return a.isNumber(c.h)&&a.isNumber(c.s)&&a.isNumber(c.v)&&a.isNumber(c.a)?{space:"HSV",h:c.h,s:c.s,v:c.v,a:c.a}:!1},write:function(a){return{h:a.h,s:a.s,v:a.v,a:a.a}}},HSV_OBJ:{read:function(d){return a.isNumber(d.h)&&a.isNumber(d.s)&&a.isNumber(d.v)?{space:"HSV",h:d.h,s:d.s,v:d.v}:!1},write:function(a){return{h:a.h,s:a.s,v:a.v}}}}}];return function(){d=!1; +var c=1\n\n Here\'s the new load parameter for your GUI\'s constructor:\n\n \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
\n \n
\n\n', +".dg {\n /** Clear list styles */\n /* Auto-place container */\n /* Auto-placed GUI's */\n /* Line items that don't contain folders. */\n /** Folder names */\n /** Hides closed items */\n /** Controller row */\n /** Name-half (left) */\n /** Controller-half (right) */\n /** Controller placement */\n /** Shorter number boxes when slider is present. */\n /** Ensure the entire boolean and function row shows a hand */ }\n .dg ul {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n clear: both; }\n .dg.ac {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 0;\n z-index: 0; }\n .dg:not(.ac) .main {\n /** Exclude mains in ac so that we don't hide close button */\n overflow: hidden; }\n .dg.main {\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear; }\n .dg.main.taller-than-window {\n overflow-y: auto; }\n .dg.main.taller-than-window .close-button {\n opacity: 1;\n /* TODO, these are style notes */\n margin-top: -1px;\n border-top: 1px solid #2c2c2c; }\n .dg.main ul.closed .close-button {\n opacity: 1 !important; }\n .dg.main:hover .close-button,\n .dg.main .close-button.drag {\n opacity: 1; }\n .dg.main .close-button {\n /*opacity: 0;*/\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear;\n border: 0;\n position: absolute;\n line-height: 19px;\n height: 20px;\n /* TODO, these are style notes */\n cursor: pointer;\n text-align: center;\n background-color: #000; }\n .dg.main .close-button:hover {\n background-color: #111; }\n .dg.a {\n float: right;\n margin-right: 15px;\n overflow-x: hidden; }\n .dg.a.has-save > ul {\n margin-top: 27px; }\n .dg.a.has-save > ul.closed {\n margin-top: 0; }\n .dg.a .save-row {\n position: fixed;\n top: 0;\n z-index: 1002; }\n .dg li {\n -webkit-transition: height 0.1s ease-out;\n -o-transition: height 0.1s ease-out;\n -moz-transition: height 0.1s ease-out;\n transition: height 0.1s ease-out; }\n .dg li:not(.folder) {\n cursor: auto;\n height: 27px;\n line-height: 27px;\n overflow: hidden;\n padding: 0 4px 0 5px; }\n .dg li.folder {\n padding: 0;\n border-left: 4px solid rgba(0, 0, 0, 0); }\n .dg li.title {\n cursor: pointer;\n margin-left: -4px; }\n .dg .closed li:not(.title),\n .dg .closed ul li,\n .dg .closed ul li > * {\n height: 0;\n overflow: hidden;\n border: 0; }\n .dg .cr {\n clear: both;\n padding-left: 3px;\n height: 27px; }\n .dg .property-name {\n cursor: default;\n float: left;\n clear: left;\n width: 40%;\n overflow: hidden;\n text-overflow: ellipsis; }\n .dg .c {\n float: left;\n width: 60%; }\n .dg .c input[type=text] {\n border: 0;\n margin-top: 4px;\n padding: 3px;\n width: 100%;\n float: right; }\n .dg .has-slider input[type=text] {\n width: 30%;\n /*display: none;*/\n margin-left: 0; }\n .dg .slider {\n float: left;\n width: 66%;\n margin-left: -5px;\n margin-right: 0;\n height: 19px;\n margin-top: 4px; }\n .dg .slider-fg {\n height: 100%; }\n .dg .c input[type=checkbox] {\n margin-top: 9px; }\n .dg .c select {\n margin-top: 5px; }\n .dg .cr.function,\n .dg .cr.function .property-name,\n .dg .cr.function *,\n .dg .cr.boolean,\n .dg .cr.boolean * {\n cursor: pointer; }\n .dg .selector {\n display: none;\n position: absolute;\n margin-left: -9px;\n margin-top: 23px;\n z-index: 10; }\n .dg .c:hover .selector,\n .dg .selector.drag {\n display: block; }\n .dg li.save-row {\n padding: 0; }\n .dg li.save-row .button {\n display: inline-block;\n padding: 0px 6px; }\n .dg.dialogue {\n background-color: #222;\n width: 460px;\n padding: 15px;\n font-size: 13px;\n line-height: 15px; }\n\n/* TODO Separate style and structure */\n#dg-new-constructor {\n padding: 10px;\n color: #222;\n font-family: Monaco, monospace;\n font-size: 10px;\n border: 0;\n resize: none;\n box-shadow: inset 1px 1px 1px #888;\n word-wrap: break-word;\n margin: 12px 0;\n display: block;\n width: 440px;\n overflow-y: scroll;\n height: 100px;\n position: relative; }\n\n#dg-local-explain {\n display: none;\n font-size: 11px;\n line-height: 17px;\n border-radius: 3px;\n background-color: #333;\n padding: 8px;\n margin-top: 10px; }\n #dg-local-explain code {\n font-size: 10px; }\n\n#dat-gui-save-locally {\n display: none; }\n\n/** Main type */\n.dg {\n color: #eee;\n font: 11px 'Lucida Grande', sans-serif;\n text-shadow: 0 -1px 0 #111;\n /** Auto place */\n /* Controller row,
  • */\n /** Controllers */ }\n .dg.main {\n /** Scrollbar */ }\n .dg.main::-webkit-scrollbar {\n width: 5px;\n background: #1a1a1a; }\n .dg.main::-webkit-scrollbar-corner {\n height: 0;\n display: none; }\n .dg.main::-webkit-scrollbar-thumb {\n border-radius: 5px;\n background: #676767; }\n .dg li:not(.folder) {\n background: #1a1a1a;\n border-bottom: 1px solid #2c2c2c; }\n .dg li.save-row {\n line-height: 25px;\n background: #dad5cb;\n border: 0; }\n .dg li.save-row select {\n margin-left: 5px;\n width: 108px; }\n .dg li.save-row .button {\n margin-left: 5px;\n margin-top: 1px;\n border-radius: 2px;\n font-size: 9px;\n line-height: 7px;\n padding: 4px 4px 5px 4px;\n background: #c5bdad;\n color: #fff;\n text-shadow: 0 1px 0 #b0a58f;\n box-shadow: 0 -1px 0 #b0a58f;\n cursor: pointer; }\n .dg li.save-row .button.gears {\n background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\n height: 7px;\n width: 8px; }\n .dg li.save-row .button:hover {\n background-color: #bab19e;\n box-shadow: 0 -1px 0 #b0a58f; }\n .dg li.folder {\n border-bottom: 0; }\n .dg li.title {\n padding-left: 16px;\n background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n cursor: pointer;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\n .dg .closed li.title {\n background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\n .dg .cr.boolean {\n border-left: 3px solid #806787; }\n .dg .cr.function {\n border-left: 3px solid #e61d5f; }\n .dg .cr.number {\n border-left: 3px solid #2fa1d6; }\n .dg .cr.number input[type=text] {\n color: #2fa1d6; }\n .dg .cr.string {\n border-left: 3px solid #1ed36f; }\n .dg .cr.string input[type=text] {\n color: #1ed36f; }\n .dg .cr.function:hover, .dg .cr.boolean:hover {\n background: #111; }\n .dg .c input[type=text] {\n background: #303030;\n outline: none; }\n .dg .c input[type=text]:hover {\n background: #3c3c3c; }\n .dg .c input[type=text]:focus {\n background: #494949;\n color: #fff; }\n .dg .c .slider {\n background: #303030;\n cursor: ew-resize; }\n .dg .c .slider-fg {\n background: #2fa1d6; }\n .dg .c .slider:hover {\n background: #3c3c3c; }\n .dg .c .slider:hover .slider-fg {\n background: #44abda; }\n", +dat.controllers.factory=function(e,a,b,d,f,c,p){return function(k,l,q,n){var r=k[l];if(p.isArray(q)||p.isObject(q))return new e(k,l,q);if(p.isNumber(r))return p.isNumber(q)&&p.isNumber(n)?new b(k,l,q,n):new a(k,l,{min:q,max:n});if(p.isString(r))return new d(k,l);if(p.isFunction(r))return new f(k,l,"");if(p.isBoolean(r))return new c(k,l)}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(e,a,b){var d= +function(b,c){function e(){k.setValue(k.__input.value)}d.superclass.call(this,b,c);var k=this;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"keyup",e);a.bind(this.__input,"change",e);a.bind(this.__input,"blur",function(){k.__onFinishChange&&k.__onFinishChange.call(k,k.getValue())});a.bind(this.__input,"keydown",function(a){13===a.keyCode&&this.blur()});this.updateDisplay();this.domElement.appendChild(this.__input)};d.superclass=e;b.extend(d.prototype, +e.prototype,{updateDisplay:function(){a.isActive(this.__input)||(this.__input.value=this.getValue());return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.FunctionController,dat.controllers.BooleanController,dat.utils.common),dat.controllers.Controller,dat.controllers.BooleanController,dat.controllers.FunctionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.OptionController, +dat.controllers.ColorController=function(e,a,b,d,f){function c(a,b,d,c){a.style.background="";f.each(l,function(e){a.style.cssText+="background: "+e+"linear-gradient("+b+", "+d+" 0%, "+c+" 100%); "})}function p(a){a.style.background="";a.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);";a.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"; +a.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}var k=function(e,n){function r(b){t(b);a.bind(window,"mousemove",t);a.bind(window, +"mouseup",l)}function l(){a.unbind(window,"mousemove",t);a.unbind(window,"mouseup",l)}function g(){var a=d(this.value);!1!==a?(s.__color.__state=a,s.setValue(s.__color.toOriginal())):this.value=s.__color.toString()}function h(){a.unbind(window,"mousemove",u);a.unbind(window,"mouseup",h)}function t(b){b.preventDefault();var d=a.getWidth(s.__saturation_field),c=a.getOffset(s.__saturation_field),e=(b.clientX-c.left+document.body.scrollLeft)/d;b=1-(b.clientY-c.top+document.body.scrollTop)/d;1 +b&&(b=0);1e&&(e=0);s.__color.v=b;s.__color.s=e;s.setValue(s.__color.toOriginal());return!1}function u(b){b.preventDefault();var d=a.getHeight(s.__hue_field),c=a.getOffset(s.__hue_field);b=1-(b.clientY-c.top+document.body.scrollTop)/d;1b&&(b=0);s.__color.h=360*b;s.setValue(s.__color.toOriginal());return!1}k.superclass.call(this,e,n);this.__color=new b(this.getValue());this.__temp=new b(0);var s=this;this.domElement=document.createElement("div");a.makeSelectable(this.domElement,!1); +this.__selector=document.createElement("div");this.__selector.className="selector";this.__saturation_field=document.createElement("div");this.__saturation_field.className="saturation-field";this.__field_knob=document.createElement("div");this.__field_knob.className="field-knob";this.__field_knob_border="2px solid ";this.__hue_knob=document.createElement("div");this.__hue_knob.className="hue-knob";this.__hue_field=document.createElement("div");this.__hue_field.className="hue-field";this.__input=document.createElement("input"); +this.__input.type="text";this.__input_textShadow="0 1px 1px ";a.bind(this.__input,"keydown",function(a){13===a.keyCode&&g.call(this)});a.bind(this.__input,"blur",g);a.bind(this.__selector,"mousedown",function(b){a.addClass(this,"drag").bind(window,"mouseup",function(b){a.removeClass(s.__selector,"drag")})});var v=document.createElement("div");f.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"});f.extend(this.__field_knob.style, +{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(0.5>this.__color.v?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1});f.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1});f.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"});f.extend(v.style,{width:"100%",height:"100%", +background:"none"});c(v,"top","rgba(0,0,0,0)","#000");f.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"});p(this.__hue_field);f.extend(this.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:this.__input_textShadow+"rgba(0,0,0,0.7)"});a.bind(this.__saturation_field,"mousedown",r);a.bind(this.__field_knob,"mousedown",r);a.bind(this.__hue_field,"mousedown",function(b){u(b);a.bind(window, +"mousemove",u);a.bind(window,"mouseup",h)});this.__saturation_field.appendChild(v);this.__selector.appendChild(this.__field_knob);this.__selector.appendChild(this.__saturation_field);this.__selector.appendChild(this.__hue_field);this.__hue_field.appendChild(this.__hue_knob);this.domElement.appendChild(this.__input);this.domElement.appendChild(this.__selector);this.updateDisplay()};k.superclass=e;f.extend(k.prototype,e.prototype,{updateDisplay:function(){var a=d(this.getValue());if(!1!==a){var e=!1; +f.each(b.COMPONENTS,function(b){if(!f.isUndefined(a[b])&&!f.isUndefined(this.__color.__state[b])&&a[b]!==this.__color.__state[b])return e=!0,{}},this);e&&f.extend(this.__color.__state,a)}f.extend(this.__temp.__state,this.__color.__state);this.__temp.a=1;var k=0.5>this.__color.v||0.5a&&(a+=1);return{h:360*a,s:e/c,v:c/255}},rgb_to_hex:function(a,b,d){a=this.hex_with_component(0,2,a);a=this.hex_with_component(a,1,b);return a=this.hex_with_component(a,0,d)},component_from_hex:function(a,b){return a>>8*b&255},hex_with_component:function(a,b,d){return d<<(e=8*b)|a&~(255< + + + +Forest Basins + + + + + + + + + + +
    +
    +
    +
    + + + + + +
    + + + + + + + + diff --git a/docs/examples/24/legend.png b/docs/examples/24/legend.png new file mode 100644 index 00000000..0fbe41e0 Binary files /dev/null and b/docs/examples/24/legend.png differ diff --git a/docs/examples/24/mt_fuji.html b/docs/examples/24/mt_fuji.html new file mode 100644 index 00000000..48f2ab2a --- /dev/null +++ b/docs/examples/24/mt_fuji.html @@ -0,0 +1,113 @@ + + + + +Mt. Fuji + + + + + + + + +
    +
    +
    +
    + + + + + +
    + + + + + + + + diff --git a/docs/examples/24/proj4js/license.md b/docs/examples/24/proj4js/license.md new file mode 100644 index 00000000..7c99b1ab --- /dev/null +++ b/docs/examples/24/proj4js/license.md @@ -0,0 +1,29 @@ +##Proj4js -- Javascript reprojection library. + +Authors: +- Mike Adair madairATdmsolutions.ca +- Richard Greenwood richATgreenwoodmap.com +- Didier Richard didier.richardATign.fr +- Stephen Irons stephen.ironsATclear.net.nz +- Olivier Terral oterralATgmail.com +- Calvin Metcalf cmetcalfATappgeo.com + +Copyright (c) 2014, Mike Adair, Richard Greenwood, Didier Richard, Stephen Irons, Olivier Terral and Calvin Metcalf + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE._ \ No newline at end of file diff --git a/docs/examples/24/proj4js/proj4.js b/docs/examples/24/proj4js/proj4.js new file mode 100644 index 00000000..d327c536 --- /dev/null +++ b/docs/examples/24/proj4js/proj4.js @@ -0,0 +1,3 @@ +!function(a){if("object"==typeof exports)module.exports=a();else if("function"==typeof define&&define.amd)define(a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.proj4=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;gf;f++)if(!b||2!==f||void 0!==c.z)switch(0===f?(d=g,e="x"):1===f?(d=h,e="y"):(d=i,e="z"),a.axis[f]){case"e":c[e]=d;break;case"w":c[e]=-d;break;case"n":c[e]=d;break;case"s":c[e]=-d;break;case"u":void 0!==c[e]&&(c.z=d);break;case"d":void 0!==c[e]&&(c.z=-d);break;default:return null}return c}},{}],4:[function(a,b){var c=Math.PI/2,d=a("./sign");b.exports=function(a){return Math.abs(a)1&&(a=a>1?1:-1),Math.asin(a)}},{}],7:[function(a,b){b.exports=function(a){return 1-.25*a*(1+a/16*(3+1.25*a))}},{}],8:[function(a,b){b.exports=function(a){return.375*a*(1+.25*a*(1+.46875*a))}},{}],9:[function(a,b){b.exports=function(a){return.05859375*a*a*(1+.75*a)}},{}],10:[function(a,b){b.exports=function(a){return a*a*a*(35/3072)}},{}],11:[function(a,b){b.exports=function(a,b,c){var d=b*c;return a/Math.sqrt(1-d*d)}},{}],12:[function(a,b){b.exports=function(a,b,c,d,e){var f,g;f=a/b;for(var h=0;15>h;h++)if(g=(a-(b*f-c*Math.sin(2*f)+d*Math.sin(4*f)-e*Math.sin(6*f)))/(b-2*c*Math.cos(2*f)+4*d*Math.cos(4*f)-6*e*Math.cos(6*f)),f+=g,Math.abs(g)<=1e-10)return f;return 0/0}},{}],13:[function(a,b){var c=Math.PI/2;b.exports=function(a,b){var d=1-(1-a*a)/(2*a)*Math.log((1-a)/(1+a));if(Math.abs(Math.abs(b)-d)<1e-6)return 0>b?-1*c:c;for(var e,f,g,h,i=Math.asin(.5*b),j=0;30>j;j++)if(f=Math.sin(i),g=Math.cos(i),h=a*f,e=Math.pow(1-h*h,2)/(2*g)*(b/(1-a*a)-f/(1-h*h)+.5/a*Math.log((1-h)/(1+h))),i+=e,Math.abs(e)<=1e-10)return i;return 0/0}},{}],14:[function(a,b){b.exports=function(a,b,c,d,e){return a*e-b*Math.sin(2*e)+c*Math.sin(4*e)-d*Math.sin(6*e)}},{}],15:[function(a,b){b.exports=function(a,b,c){var d=a*b;return c/Math.sqrt(1-d*d)}},{}],16:[function(a,b){var c=Math.PI/2;b.exports=function(a,b){for(var d,e,f=.5*a,g=c-2*Math.atan(b),h=0;15>=h;h++)if(d=a*Math.sin(g),e=c-2*Math.atan(b*Math.pow((1-d)/(1+d),f))-g,g+=e,Math.abs(e)<=1e-10)return g;return-9999}},{}],17:[function(a,b){var c=1,d=.25,e=.046875,f=.01953125,g=.01068115234375,h=.75,i=.46875,j=.013020833333333334,k=.007120768229166667,l=.3645833333333333,m=.005696614583333333,n=.3076171875;b.exports=function(a){var b=[];b[0]=c-a*(d+a*(e+a*(f+a*g))),b[1]=a*(h-a*(e+a*(f+a*g)));var o=a*a;return b[2]=o*(i-a*(j+a*k)),o*=a,b[3]=o*(l-a*m),b[4]=o*a*n,b}},{}],18:[function(a,b){var c=a("./pj_mlfn"),d=1e-10,e=20;b.exports=function(a,b,f){for(var g=1/(1-b),h=a,i=e;i;--i){var j=Math.sin(h),k=1-b*j*j;if(k=(c(h,j,Math.cos(h),f)-a)*k*Math.sqrt(k)*g,h-=k,Math.abs(k)1e-7?(c=a*b,(1-a*a)*(b/(1-c*c)-.5/a*Math.log((1-c)/(1+c)))):2*b}},{}],21:[function(a,b){b.exports=function(a){return 0>a?-1:1}},{}],22:[function(a,b){b.exports=function(a,b){return Math.pow((1-a)/(1+a),b)}},{}],23:[function(a,b){b.exports=function(a){var b={x:a[0],y:a[1]};return a.length>2&&(b.z=a[2]),a.length>3&&(b.m=a[3]),b}},{}],24:[function(a,b){var c=Math.PI/2;b.exports=function(a,b,d){var e=a*d,f=.5*a;return e=Math.pow((1-e)/(1+e),f),Math.tan(.5*(c-b))/e}},{}],25:[function(a,b,c){c.wgs84={towgs84:"0,0,0",ellipse:"WGS84",datumName:"WGS84"},c.ch1903={towgs84:"674.374,15.056,405.346",ellipse:"bessel",datumName:"swiss"},c.ggrs87={towgs84:"-199.87,74.79,246.62",ellipse:"GRS80",datumName:"Greek_Geodetic_Reference_System_1987"},c.nad83={towgs84:"0,0,0",ellipse:"GRS80",datumName:"North_American_Datum_1983"},c.nad27={nadgrids:"@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat",ellipse:"clrk66",datumName:"North_American_Datum_1927"},c.potsdam={towgs84:"606.0,23.0,413.0",ellipse:"bessel",datumName:"Potsdam Rauenberg 1950 DHDN"},c.carthage={towgs84:"-263.0,6.0,431.0",ellipse:"clark80",datumName:"Carthage 1934 Tunisia"},c.hermannskogel={towgs84:"653.0,-212.0,449.0",ellipse:"bessel",datumName:"Hermannskogel"},c.ire65={towgs84:"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",ellipse:"mod_airy",datumName:"Ireland 1965"},c.rassadiran={towgs84:"-133.63,-157.5,-158.62",ellipse:"intl",datumName:"Rassadiran"},c.nzgd49={towgs84:"59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",ellipse:"intl",datumName:"New Zealand Geodetic Datum 1949"},c.osgb36={towgs84:"446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",ellipse:"airy",datumName:"Airy 1830"},c.s_jtsk={towgs84:"589,76,480",ellipse:"bessel",datumName:"S-JTSK (Ferro)"},c.beduaram={towgs84:"-106,-87,188",ellipse:"clrk80",datumName:"Beduaram"},c.gunung_segara={towgs84:"-403,684,41",ellipse:"bessel",datumName:"Gunung Segara Jakarta"},c.rnb72={towgs84:"106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1",ellipse:"intl",datumName:"Reseau National Belge 1972"}},{}],26:[function(a,b,c){c.MERIT={a:6378137,rf:298.257,ellipseName:"MERIT 1983"},c.SGS85={a:6378136,rf:298.257,ellipseName:"Soviet Geodetic System 85"},c.GRS80={a:6378137,rf:298.257222101,ellipseName:"GRS 1980(IUGG, 1980)"},c.IAU76={a:6378140,rf:298.257,ellipseName:"IAU 1976"},c.airy={a:6377563.396,b:6356256.91,ellipseName:"Airy 1830"},c.APL4={a:6378137,rf:298.25,ellipseName:"Appl. Physics. 1965"},c.NWL9D={a:6378145,rf:298.25,ellipseName:"Naval Weapons Lab., 1965"},c.mod_airy={a:6377340.189,b:6356034.446,ellipseName:"Modified Airy"},c.andrae={a:6377104.43,rf:300,ellipseName:"Andrae 1876 (Den., Iclnd.)"},c.aust_SA={a:6378160,rf:298.25,ellipseName:"Australian Natl & S. Amer. 1969"},c.GRS67={a:6378160,rf:298.247167427,ellipseName:"GRS 67(IUGG 1967)"},c.bessel={a:6377397.155,rf:299.1528128,ellipseName:"Bessel 1841"},c.bess_nam={a:6377483.865,rf:299.1528128,ellipseName:"Bessel 1841 (Namibia)"},c.clrk66={a:6378206.4,b:6356583.8,ellipseName:"Clarke 1866"},c.clrk80={a:6378249.145,rf:293.4663,ellipseName:"Clarke 1880 mod."},c.clrk58={a:6378293.645208759,rf:294.2606763692654,ellipseName:"Clarke 1858"},c.CPM={a:6375738.7,rf:334.29,ellipseName:"Comm. des Poids et Mesures 1799"},c.delmbr={a:6376428,rf:311.5,ellipseName:"Delambre 1810 (Belgium)"},c.engelis={a:6378136.05,rf:298.2566,ellipseName:"Engelis 1985"},c.evrst30={a:6377276.345,rf:300.8017,ellipseName:"Everest 1830"},c.evrst48={a:6377304.063,rf:300.8017,ellipseName:"Everest 1948"},c.evrst56={a:6377301.243,rf:300.8017,ellipseName:"Everest 1956"},c.evrst69={a:6377295.664,rf:300.8017,ellipseName:"Everest 1969"},c.evrstSS={a:6377298.556,rf:300.8017,ellipseName:"Everest (Sabah & Sarawak)"},c.fschr60={a:6378166,rf:298.3,ellipseName:"Fischer (Mercury Datum) 1960"},c.fschr60m={a:6378155,rf:298.3,ellipseName:"Fischer 1960"},c.fschr68={a:6378150,rf:298.3,ellipseName:"Fischer 1968"},c.helmert={a:6378200,rf:298.3,ellipseName:"Helmert 1906"},c.hough={a:6378270,rf:297,ellipseName:"Hough"},c.intl={a:6378388,rf:297,ellipseName:"International 1909 (Hayford)"},c.kaula={a:6378163,rf:298.24,ellipseName:"Kaula 1961"},c.lerch={a:6378139,rf:298.257,ellipseName:"Lerch 1979"},c.mprts={a:6397300,rf:191,ellipseName:"Maupertius 1738"},c.new_intl={a:6378157.5,b:6356772.2,ellipseName:"New International 1967"},c.plessis={a:6376523,rf:6355863,ellipseName:"Plessis 1817 (France)"},c.krass={a:6378245,rf:298.3,ellipseName:"Krassovsky, 1942"},c.SEasia={a:6378155,b:6356773.3205,ellipseName:"Southeast Asia"},c.walbeck={a:6376896,b:6355834.8467,ellipseName:"Walbeck"},c.WGS60={a:6378165,rf:298.3,ellipseName:"WGS 60"},c.WGS66={a:6378145,rf:298.25,ellipseName:"WGS 66"},c.WGS7={a:6378135,rf:298.26,ellipseName:"WGS 72"},c.WGS84={a:6378137,rf:298.257223563,ellipseName:"WGS 84"},c.sphere={a:6370997,b:6370997,ellipseName:"Normal Sphere (r=6370997)"}},{}],27:[function(a,b,c){c.greenwich=0,c.lisbon=-9.131906111111,c.paris=2.337229166667,c.bogota=-74.080916666667,c.madrid=-3.687938888889,c.rome=12.452333333333,c.bern=7.439583333333,c.jakarta=106.807719444444,c.ferro=-17.666666666667,c.brussels=4.367975,c.stockholm=18.058277777778,c.athens=23.7163375,c.oslo=10.722916666667},{}],28:[function(a,b){function c(a,b,c){var d;return Array.isArray(c)?(d=f(a,b,c),3===c.length?[d.x,d.y,d.z]:[d.x,d.y]):f(a,b,c)}function d(a){return a instanceof e?a:a.oProj?a.oProj:e(a)}function proj4(a,b,e){a=d(a);var f,h=!1;return"undefined"==typeof b?(b=a,a=g,h=!0):("undefined"!=typeof b.x||Array.isArray(b))&&(e=b,b=a,a=g,h=!0),b=d(b),e?c(a,b,e):(f={forward:function(d){return c(a,b,d)},inverse:function(d){return c(b,a,d)}},h&&(f.oProj=b),f)}var e=a("./Proj"),f=a("./transform"),g=e("WGS84");b.exports=proj4},{"./Proj":2,"./transform":64}],29:[function(a,b){var c=Math.PI/2,d=1,e=2,f=3,g=4,h=5,i=484813681109536e-20,j=1.0026,k=.3826834323650898,l=function(a){if(!(this instanceof l))return new l(a);if(this.datum_type=g,a){if(a.datumCode&&"none"===a.datumCode&&(this.datum_type=h),a.datum_params){for(var b=0;b3&&(0!==a.datum_params[3]||0!==a.datum_params[4]||0!==a.datum_params[5]||0!==a.datum_params[6])&&(this.datum_type=e,a.datum_params[3]*=i,a.datum_params[4]*=i,a.datum_params[5]*=i,a.datum_params[6]=a.datum_params[6]/1e6+1)}this.datum_type=a.grids?f:this.datum_type,this.a=a.a,this.b=a.b,this.es=a.es,this.ep2=a.ep2,this.datum_params=a.datum_params,this.datum_type===f&&(this.grids=a.grids)}};l.prototype={compare_datums:function(a){return this.datum_type!==a.datum_type?!1:this.a!==a.a||Math.abs(this.es-a.es)>5e-11?!1:this.datum_type===d?this.datum_params[0]===a.datum_params[0]&&this.datum_params[1]===a.datum_params[1]&&this.datum_params[2]===a.datum_params[2]:this.datum_type===e?this.datum_params[0]===a.datum_params[0]&&this.datum_params[1]===a.datum_params[1]&&this.datum_params[2]===a.datum_params[2]&&this.datum_params[3]===a.datum_params[3]&&this.datum_params[4]===a.datum_params[4]&&this.datum_params[5]===a.datum_params[5]&&this.datum_params[6]===a.datum_params[6]:this.datum_type===f||a.datum_type===f?this.nadgrids===a.nadgrids:!0},geodetic_to_geocentric:function(a){var b,d,e,f,g,h,i,j=a.x,k=a.y,l=a.z?a.z:0,m=0;if(-c>k&&k>-1.001*c)k=-c;else if(k>c&&1.001*c>k)k=c;else if(-c>k||k>c)return null;return j>Math.PI&&(j-=2*Math.PI),g=Math.sin(k),i=Math.cos(k),h=g*g,f=this.a/Math.sqrt(1-this.es*h),b=(f+l)*i*Math.cos(j),d=(f+l)*i*Math.sin(j),e=(f*(1-this.es)+l)*g,a.x=b,a.y=d,a.z=e,m},geocentric_to_geodetic:function(a){var b,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t=1e-12,u=t*t,v=30,w=a.x,x=a.y,y=a.z?a.z:0;if(o=!1,b=Math.sqrt(w*w+x*x),d=Math.sqrt(w*w+x*x+y*y),b/this.au&&v>p);return r=Math.atan(m/Math.abs(l)),a.x=q,a.y=r,a.z=s,a},geocentric_to_geodetic_noniter:function(a){var b,d,e,f,g,h,i,l,m,n,o,p,q,r,s,t,u,v=a.x,w=a.y,x=a.z?a.z:0;if(v=parseFloat(v),w=parseFloat(w),x=parseFloat(x),u=!1,0!==v)b=Math.atan2(w,v);else if(w>0)b=c;else if(0>w)b=-c;else if(u=!0,b=0,x>0)d=c;else{if(!(0>x))return d=c,void(e=-this.b);d=-c}return g=v*v+w*w,f=Math.sqrt(g),h=x*j,l=Math.sqrt(h*h+g),n=h/l,p=f/l,o=n*n*n,i=x+this.b*this.ep2*o,t=f-this.a*this.es*p*p*p,m=Math.sqrt(i*i+t*t),q=i/m,r=t/m,s=this.a/Math.sqrt(1-this.es*q*q),e=r>=k?f/r-s:-k>=r?f/-r-s:x/q+s*(this.es-1),u===!1&&(d=Math.atan(q/r)),a.x=b,a.y=d,a.z=e,a},geocentric_to_wgs84:function(a){if(this.datum_type===d)a.x+=this.datum_params[0],a.y+=this.datum_params[1],a.z+=this.datum_params[2];else if(this.datum_type===e){var b=this.datum_params[0],c=this.datum_params[1],f=this.datum_params[2],g=this.datum_params[3],h=this.datum_params[4],i=this.datum_params[5],j=this.datum_params[6],k=j*(a.x-i*a.y+h*a.z)+b,l=j*(i*a.x+a.y-g*a.z)+c,m=j*(-h*a.x+g*a.y+a.z)+f;a.x=k,a.y=l,a.z=m}},geocentric_from_wgs84:function(a){if(this.datum_type===d)a.x-=this.datum_params[0],a.y-=this.datum_params[1],a.z-=this.datum_params[2];else if(this.datum_type===e){var b=this.datum_params[0],c=this.datum_params[1],f=this.datum_params[2],g=this.datum_params[3],h=this.datum_params[4],i=this.datum_params[5],j=this.datum_params[6],k=(a.x-b)/j,l=(a.y-c)/j,m=(a.z-f)/j;a.x=k+i*l-h*m,a.y=-i*k+l+g*m,a.z=h*k-g*l+m}}},b.exports=l},{}],30:[function(a,b){var c=1,d=2,e=3,f=5,g=6378137,h=.006694379990141316;b.exports=function(a,b,i){function j(a){return a===c||a===d}var k,l,m;if(a.compare_datums(b))return i;if(a.datum_type===f||b.datum_type===f)return i;var n=a.a,o=a.es,p=b.a,q=b.es,r=a.datum_type;if(r===e)if(0===this.apply_gridshift(a,0,i))a.a=g,a.es=h;else{if(!a.datum_params)return a.a=n,a.es=a.es,i;for(k=1,l=0,m=a.datum_params.length;m>l;l++)k*=a.datum_params[l];if(0===k)return a.a=n,a.es=a.es,i;r=a.datum_params.length>3?d:c}return b.datum_type===e&&(b.a=g,b.es=h),(a.es!==b.es||a.a!==b.a||j(r)||j(b.datum_type))&&(a.geodetic_to_geocentric(i),j(a.datum_type)&&a.geocentric_to_wgs84(i),j(b.datum_type)&&b.geocentric_from_wgs84(i),b.geocentric_to_geodetic(i)),b.datum_type===e&&this.apply_gridshift(b,1,i),a.a=n,a.es=o,b.a=p,b.es=q,i}},{}],31:[function(a,b){function c(a){var b=this;if(2===arguments.length){var d=arguments[1];c[a]="string"==typeof d?"+"===d[0]?e(arguments[1]):f(arguments[1]):d}else if(1===arguments.length){if(Array.isArray(a))return a.map(function(a){Array.isArray(a)?c.apply(b,a):c(a)});if("string"==typeof a){if(a in c)return c[a]}else"EPSG"in a?c["EPSG:"+a.EPSG]=a:"ESRI"in a?c["ESRI:"+a.ESRI]=a:"IAU2000"in a?c["IAU2000:"+a.IAU2000]=a:console.log(a);return}}var d=a("./global"),e=a("./projString"),f=a("./wkt");d(c),b.exports=c},{"./global":34,"./projString":37,"./wkt":65}],32:[function(a,b){var c=a("./constants/Datum"),d=a("./constants/Ellipsoid"),e=a("./extend"),f=a("./datum"),g=1e-10,h=.16666666666666666,i=.04722222222222222,j=.022156084656084655;b.exports=function(a){if(a.datumCode&&"none"!==a.datumCode){var b=c[a.datumCode];b&&(a.datum_params=b.towgs84?b.towgs84.split(","):null,a.ellps=b.ellipse,a.datumName=b.datumName?b.datumName:a.datumCode)}if(!a.a){var k=d[a.ellps]?d[a.ellps]:d.WGS84;e(a,k)}return a.rf&&!a.b&&(a.b=(1-1/a.rf)*a.a),(0===a.rf||Math.abs(a.a-a.b)d?(this.ms1*this.ms1-this.ms2*this.ms2)/(this.qs2-this.qs1):this.con,this.c=this.ms1*this.ms1+this.ns0*this.qs1,this.rh=this.a*Math.sqrt(this.c-this.ns0*this.qs0)/this.ns0)},c.forward=function(a){var b=a.x,c=a.y;this.sin_phi=Math.sin(c),this.cos_phi=Math.cos(c);var d=f(this.e3,this.sin_phi,this.cos_phi),e=this.a*Math.sqrt(this.c-this.ns0*d)/this.ns0,h=this.ns0*g(b-this.long0),i=e*Math.sin(h)+this.x0,j=this.rh-e*Math.cos(h)+this.y0;return a.x=i,a.y=j,a},c.inverse=function(a){var b,c,d,e,f,h;return a.x-=this.x0,a.y=this.rh-a.y+this.y0,this.ns0>=0?(b=Math.sqrt(a.x*a.x+a.y*a.y),d=1):(b=-Math.sqrt(a.x*a.x+a.y*a.y),d=-1),e=0,0!==b&&(e=Math.atan2(d*a.x,d*a.y)),d=b*this.ns0/this.a,this.sphere?h=Math.asin((this.c-d*d)/(2*this.ns0)):(c=(this.c-d*d)/this.ns0,h=this.phi1z(this.e3,c)),f=g(e/this.ns0+this.long0),a.x=f,a.y=h,a},c.phi1z=function(a,b){var c,e,f,g,i,j=h(.5*b);if(d>a)return j;for(var k=a*a,l=1;25>=l;l++)if(c=Math.sin(j),e=Math.cos(j),f=a*c,g=1-f*f,i=.5*g*g/e*(b/(1-k)-c/g+.5/a*Math.log((1-f)/(1+f))),j+=i,Math.abs(i)<=1e-7)return j;return null},c.names=["Albers_Conic_Equal_Area","Albers","aea"]},{"../common/adjust_lon":5,"../common/asinz":6,"../common/msfnz":15,"../common/qsfnz":20}],40:[function(a,b,c){var d=a("../common/adjust_lon"),e=Math.PI/2,f=1e-10,g=a("../common/mlfn"),h=a("../common/e0fn"),i=a("../common/e1fn"),j=a("../common/e2fn"),k=a("../common/e3fn"),l=a("../common/gN"),m=a("../common/asinz"),n=a("../common/imlfn");c.init=function(){this.sin_p12=Math.sin(this.lat0),this.cos_p12=Math.cos(this.lat0)},c.forward=function(a){var b,c,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H=a.x,I=a.y,J=Math.sin(a.y),K=Math.cos(a.y),L=d(H-this.long0);return this.sphere?Math.abs(this.sin_p12-1)<=f?(a.x=this.x0+this.a*(e-I)*Math.sin(L),a.y=this.y0-this.a*(e-I)*Math.cos(L),a):Math.abs(this.sin_p12+1)<=f?(a.x=this.x0+this.a*(e+I)*Math.sin(L),a.y=this.y0+this.a*(e+I)*Math.cos(L),a):(B=this.sin_p12*J+this.cos_p12*K*Math.cos(L),z=Math.acos(B),A=z/Math.sin(z),a.x=this.x0+this.a*A*K*Math.sin(L),a.y=this.y0+this.a*A*(this.cos_p12*J-this.sin_p12*K*Math.cos(L)),a):(b=h(this.es),c=i(this.es),m=j(this.es),n=k(this.es),Math.abs(this.sin_p12-1)<=f?(o=this.a*g(b,c,m,n,e),p=this.a*g(b,c,m,n,I),a.x=this.x0+(o-p)*Math.sin(L),a.y=this.y0-(o-p)*Math.cos(L),a):Math.abs(this.sin_p12+1)<=f?(o=this.a*g(b,c,m,n,e),p=this.a*g(b,c,m,n,I),a.x=this.x0+(o+p)*Math.sin(L),a.y=this.y0+(o+p)*Math.cos(L),a):(q=J/K,r=l(this.a,this.e,this.sin_p12),s=l(this.a,this.e,J),t=Math.atan((1-this.es)*q+this.es*r*this.sin_p12/(s*K)),u=Math.atan2(Math.sin(L),this.cos_p12*Math.tan(t)-this.sin_p12*Math.cos(L)),C=0===u?Math.asin(this.cos_p12*Math.sin(t)-this.sin_p12*Math.cos(t)):Math.abs(Math.abs(u)-Math.PI)<=f?-Math.asin(this.cos_p12*Math.sin(t)-this.sin_p12*Math.cos(t)):Math.asin(Math.sin(L)*Math.cos(t)/Math.sin(u)),v=this.e*this.sin_p12/Math.sqrt(1-this.es),w=this.e*this.cos_p12*Math.cos(u)/Math.sqrt(1-this.es),x=v*w,y=w*w,D=C*C,E=D*C,F=E*C,G=F*C,z=r*C*(1-D*y*(1-y)/6+E/8*x*(1-2*y)+F/120*(y*(4-7*y)-3*v*v*(1-7*y))-G/48*x),a.x=this.x0+z*Math.sin(u),a.y=this.y0+z*Math.cos(u),a))},c.inverse=function(a){a.x-=this.x0,a.y-=this.y0;var b,c,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I;if(this.sphere){if(b=Math.sqrt(a.x*a.x+a.y*a.y),b>2*e*this.a)return;return c=b/this.a,o=Math.sin(c),p=Math.cos(c),q=this.long0,Math.abs(b)<=f?r=this.lat0:(r=m(p*this.sin_p12+a.y*o*this.cos_p12/b),s=Math.abs(this.lat0)-e,q=d(Math.abs(s)<=f?this.lat0>=0?this.long0+Math.atan2(a.x,-a.y):this.long0-Math.atan2(-a.x,a.y):this.long0+Math.atan2(a.x*o,b*this.cos_p12*p-a.y*this.sin_p12*o))),a.x=q,a.y=r,a}return t=h(this.es),u=i(this.es),v=j(this.es),w=k(this.es),Math.abs(this.sin_p12-1)<=f?(x=this.a*g(t,u,v,w,e),b=Math.sqrt(a.x*a.x+a.y*a.y),y=x-b,r=n(y/this.a,t,u,v,w),q=d(this.long0+Math.atan2(a.x,-1*a.y)),a.x=q,a.y=r,a):Math.abs(this.sin_p12+1)<=f?(x=this.a*g(t,u,v,w,e),b=Math.sqrt(a.x*a.x+a.y*a.y),y=b-x,r=n(y/this.a,t,u,v,w),q=d(this.long0+Math.atan2(a.x,a.y)),a.x=q,a.y=r,a):(b=Math.sqrt(a.x*a.x+a.y*a.y),B=Math.atan2(a.x,a.y),z=l(this.a,this.e,this.sin_p12),C=Math.cos(B),D=this.e*this.cos_p12*C,E=-D*D/(1-this.es),F=3*this.es*(1-E)*this.sin_p12*this.cos_p12*C/(1-this.es),G=b/z,H=G-E*(1+E)*Math.pow(G,3)/6-F*(1+3*E)*Math.pow(G,4)/24,I=1-E*H*H/2-G*H*H*H/6,A=Math.asin(this.sin_p12*Math.cos(H)+this.cos_p12*Math.sin(H)*C),q=d(this.long0+Math.asin(Math.sin(B)*Math.sin(H)/Math.cos(A))),r=Math.atan((1-this.es*I*this.sin_p12/Math.sin(A))*Math.tan(A)/(1-this.es)),a.x=q,a.y=r,a)},c.names=["Azimuthal_Equidistant","aeqd"]},{"../common/adjust_lon":5,"../common/asinz":6,"../common/e0fn":7,"../common/e1fn":8,"../common/e2fn":9,"../common/e3fn":10,"../common/gN":11,"../common/imlfn":12,"../common/mlfn":14}],41:[function(a,b,c){var d=a("../common/mlfn"),e=a("../common/e0fn"),f=a("../common/e1fn"),g=a("../common/e2fn"),h=a("../common/e3fn"),i=a("../common/gN"),j=a("../common/adjust_lon"),k=a("../common/adjust_lat"),l=a("../common/imlfn"),m=Math.PI/2,n=1e-10;c.init=function(){this.sphere||(this.e0=e(this.es),this.e1=f(this.es),this.e2=g(this.es),this.e3=h(this.es),this.ml0=this.a*d(this.e0,this.e1,this.e2,this.e3,this.lat0))},c.forward=function(a){var b,c,e=a.x,f=a.y;if(e=j(e-this.long0),this.sphere)b=this.a*Math.asin(Math.cos(f)*Math.sin(e)),c=this.a*(Math.atan2(Math.tan(f),Math.cos(e))-this.lat0);else{var g=Math.sin(f),h=Math.cos(f),k=i(this.a,this.e,g),l=Math.tan(f)*Math.tan(f),m=e*Math.cos(f),n=m*m,o=this.es*h*h/(1-this.es),p=this.a*d(this.e0,this.e1,this.e2,this.e3,f);b=k*m*(1-n*l*(1/6-(8-l+8*o)*n/120)),c=p-this.ml0+k*g/h*n*(.5+(5-l+6*o)*n/24)}return a.x=b+this.x0,a.y=c+this.y0,a},c.inverse=function(a){a.x-=this.x0,a.y-=this.y0;var b,c,d=a.x/this.a,e=a.y/this.a;if(this.sphere){var f=e+this.lat0;b=Math.asin(Math.sin(f)*Math.cos(d)),c=Math.atan2(Math.tan(d),Math.cos(f))}else{var g=this.ml0/this.a+e,h=l(g,this.e0,this.e1,this.e2,this.e3);if(Math.abs(Math.abs(h)-m)<=n)return a.x=this.long0,a.y=m,0>e&&(a.y*=-1),a;var o=i(this.a,this.e,Math.sin(h)),p=o*o*o/this.a/this.a*(1-this.es),q=Math.pow(Math.tan(h),2),r=d*this.a/o,s=r*r;b=h-o*Math.tan(h)/p*r*r*(.5-(1+3*q)*r*r/24),c=r*(1-s*(q/3+(1+3*q)*q*s/15))/Math.cos(h)}return a.x=j(c+this.long0),a.y=k(b),a},c.names=["Cassini","Cassini_Soldner","cass"]},{"../common/adjust_lat":4,"../common/adjust_lon":5,"../common/e0fn":7,"../common/e1fn":8,"../common/e2fn":9,"../common/e3fn":10,"../common/gN":11,"../common/imlfn":12,"../common/mlfn":14}],42:[function(a,b,c){var d=a("../common/adjust_lon"),e=a("../common/qsfnz"),f=a("../common/msfnz"),g=a("../common/iqsfnz");c.init=function(){this.sphere||(this.k0=f(this.e,Math.sin(this.lat_ts),Math.cos(this.lat_ts)))},c.forward=function(a){var b,c,f=a.x,g=a.y,h=d(f-this.long0);if(this.sphere)b=this.x0+this.a*h*Math.cos(this.lat_ts),c=this.y0+this.a*Math.sin(g)/Math.cos(this.lat_ts);else{var i=e(this.e,Math.sin(g));b=this.x0+this.a*this.k0*h,c=this.y0+this.a*i*.5/this.k0}return a.x=b,a.y=c,a},c.inverse=function(a){a.x-=this.x0,a.y-=this.y0;var b,c;return this.sphere?(b=d(this.long0+a.x/this.a/Math.cos(this.lat_ts)),c=Math.asin(a.y/this.a*Math.cos(this.lat_ts))):(c=g(this.e,2*a.y*this.k0/this.a),b=d(this.long0+a.x/(this.a*this.k0))),a.x=b,a.y=c,a},c.names=["cea"]},{"../common/adjust_lon":5,"../common/iqsfnz":13,"../common/msfnz":15,"../common/qsfnz":20}],43:[function(a,b,c){var d=a("../common/adjust_lon"),e=a("../common/adjust_lat");c.init=function(){this.x0=this.x0||0,this.y0=this.y0||0,this.lat0=this.lat0||0,this.long0=this.long0||0,this.lat_ts=this.lat_ts||0,this.title=this.title||"Equidistant Cylindrical (Plate Carre)",this.rc=Math.cos(this.lat_ts)},c.forward=function(a){var b=a.x,c=a.y,f=d(b-this.long0),g=e(c-this.lat0);return a.x=this.x0+this.a*f*this.rc,a.y=this.y0+this.a*g,a},c.inverse=function(a){var b=a.x,c=a.y;return a.x=d(this.long0+(b-this.x0)/(this.a*this.rc)),a.y=e(this.lat0+(c-this.y0)/this.a),a},c.names=["Equirectangular","Equidistant_Cylindrical","eqc"]},{"../common/adjust_lat":4,"../common/adjust_lon":5}],44:[function(a,b,c){var d=a("../common/e0fn"),e=a("../common/e1fn"),f=a("../common/e2fn"),g=a("../common/e3fn"),h=a("../common/msfnz"),i=a("../common/mlfn"),j=a("../common/adjust_lon"),k=a("../common/adjust_lat"),l=a("../common/imlfn"),m=1e-10;c.init=function(){Math.abs(this.lat1+this.lat2)=0?(c=Math.sqrt(a.x*a.x+a.y*a.y),b=1):(c=-Math.sqrt(a.x*a.x+a.y*a.y),b=-1);var f=0;if(0!==c&&(f=Math.atan2(b*a.x,b*a.y)),this.sphere)return e=j(this.long0+f/this.ns),d=k(this.g-c/this.a),a.x=e,a.y=d,a;var g=this.g-c/this.a;return d=l(g,this.e0,this.e1,this.e2,this.e3),e=j(this.long0+f/this.ns),a.x=e,a.y=d,a},c.names=["Equidistant_Conic","eqdc"]},{"../common/adjust_lat":4,"../common/adjust_lon":5,"../common/e0fn":7,"../common/e1fn":8,"../common/e2fn":9,"../common/e3fn":10,"../common/imlfn":12,"../common/mlfn":14,"../common/msfnz":15}],45:[function(a,b,c){var d=Math.PI/4,e=a("../common/srat"),f=Math.PI/2,g=20;c.init=function(){var a=Math.sin(this.lat0),b=Math.cos(this.lat0);b*=b,this.rc=Math.sqrt(1-this.es)/(1-this.es*a*a),this.C=Math.sqrt(1+this.es*b*b/(1-this.es)),this.phic0=Math.asin(a/this.C),this.ratexp=.5*this.C*this.e,this.K=Math.tan(.5*this.phic0+d)/(Math.pow(Math.tan(.5*this.lat0+d),this.C)*e(this.e*a,this.ratexp))},c.forward=function(a){var b=a.x,c=a.y;return a.y=2*Math.atan(this.K*Math.pow(Math.tan(.5*c+d),this.C)*e(this.e*Math.sin(c),this.ratexp))-f,a.x=this.C*b,a},c.inverse=function(a){for(var b=1e-14,c=a.x/this.C,h=a.y,i=Math.pow(Math.tan(.5*h+d)/this.K,1/this.C),j=g;j>0&&(h=2*Math.atan(i*e(this.e*Math.sin(a.y),-.5*this.e))-f,!(Math.abs(h-a.y)0||Math.abs(i)<=e?(j=this.x0+this.a*h*c*Math.sin(f)/i,k=this.y0+this.a*h*(this.cos_p14*b-this.sin_p14*c*g)/i):(j=this.x0+this.infinity_dist*c*Math.sin(f),k=this.y0+this.infinity_dist*(this.cos_p14*b-this.sin_p14*c*g)),a.x=j,a.y=k,a +},c.inverse=function(a){var b,c,e,g,h,i;return a.x=(a.x-this.x0)/this.a,a.y=(a.y-this.y0)/this.a,a.x/=this.k0,a.y/=this.k0,(b=Math.sqrt(a.x*a.x+a.y*a.y))?(g=Math.atan2(b,this.rc),c=Math.sin(g),e=Math.cos(g),i=f(e*this.sin_p14+a.y*c*this.cos_p14/b),h=Math.atan2(a.x*c,b*this.cos_p14*e-a.y*this.sin_p14*c),h=d(this.long0+h)):(i=this.phic0,h=0),a.x=h,a.y=i,a},c.names=["gnom"]},{"../common/adjust_lon":5,"../common/asinz":6}],47:[function(a,b,c){var d=a("../common/adjust_lon");c.init=function(){this.a=6377397.155,this.es=.006674372230614,this.e=Math.sqrt(this.es),this.lat0||(this.lat0=.863937979737193),this.long0||(this.long0=.4334234309119251),this.k0||(this.k0=.9999),this.s45=.785398163397448,this.s90=2*this.s45,this.fi0=this.lat0,this.e2=this.es,this.e=Math.sqrt(this.e2),this.alfa=Math.sqrt(1+this.e2*Math.pow(Math.cos(this.fi0),4)/(1-this.e2)),this.uq=1.04216856380474,this.u0=Math.asin(Math.sin(this.fi0)/this.alfa),this.g=Math.pow((1+this.e*Math.sin(this.fi0))/(1-this.e*Math.sin(this.fi0)),this.alfa*this.e/2),this.k=Math.tan(this.u0/2+this.s45)/Math.pow(Math.tan(this.fi0/2+this.s45),this.alfa)*this.g,this.k1=this.k0,this.n0=this.a*Math.sqrt(1-this.e2)/(1-this.e2*Math.pow(Math.sin(this.fi0),2)),this.s0=1.37008346281555,this.n=Math.sin(this.s0),this.ro0=this.k1*this.n0/Math.tan(this.s0),this.ad=this.s90-this.uq},c.forward=function(a){var b,c,e,f,g,h,i,j=a.x,k=a.y,l=d(j-this.long0);return b=Math.pow((1+this.e*Math.sin(k))/(1-this.e*Math.sin(k)),this.alfa*this.e/2),c=2*(Math.atan(this.k*Math.pow(Math.tan(k/2+this.s45),this.alfa)/b)-this.s45),e=-l*this.alfa,f=Math.asin(Math.cos(this.ad)*Math.sin(c)+Math.sin(this.ad)*Math.cos(c)*Math.cos(e)),g=Math.asin(Math.cos(c)*Math.sin(e)/Math.cos(f)),h=this.n*g,i=this.ro0*Math.pow(Math.tan(this.s0/2+this.s45),this.n)/Math.pow(Math.tan(f/2+this.s45),this.n),a.y=i*Math.cos(h)/1,a.x=i*Math.sin(h)/1,this.czech||(a.y*=-1,a.x*=-1),a},c.inverse=function(a){var b,c,d,e,f,g,h,i,j=a.x;a.x=a.y,a.y=j,this.czech||(a.y*=-1,a.x*=-1),g=Math.sqrt(a.x*a.x+a.y*a.y),f=Math.atan2(a.y,a.x),e=f/Math.sin(this.s0),d=2*(Math.atan(Math.pow(this.ro0/g,1/this.n)*Math.tan(this.s0/2+this.s45))-this.s45),b=Math.asin(Math.cos(this.ad)*Math.sin(d)-Math.sin(this.ad)*Math.cos(d)*Math.cos(e)),c=Math.asin(Math.cos(d)*Math.sin(e)/Math.cos(b)),a.x=this.long0-c/this.alfa,h=b,i=0;var k=0;do a.y=2*(Math.atan(Math.pow(this.k,-1/this.alfa)*Math.pow(Math.tan(b/2+this.s45),1/this.alfa)*Math.pow((1+this.e*Math.sin(h))/(1-this.e*Math.sin(h)),this.e/2))-this.s45),Math.abs(h-a.y)<1e-10&&(i=1),h=a.y,k+=1;while(0===i&&15>k);return k>=15?null:a},c.names=["Krovak","krovak"]},{"../common/adjust_lon":5}],48:[function(a,b,c){var d=Math.PI/2,e=Math.PI/4,f=1e-10,g=a("../common/qsfnz"),h=a("../common/adjust_lon");c.S_POLE=1,c.N_POLE=2,c.EQUIT=3,c.OBLIQ=4,c.init=function(){var a=Math.abs(this.lat0);if(this.mode=Math.abs(a-d)0){var b;switch(this.qp=g(this.e,1),this.mmf=.5/(1-this.es),this.apa=this.authset(this.es),this.mode){case this.N_POLE:this.dd=1;break;case this.S_POLE:this.dd=1;break;case this.EQUIT:this.rq=Math.sqrt(.5*this.qp),this.dd=1/this.rq,this.xmf=1,this.ymf=.5*this.qp;break;case this.OBLIQ:this.rq=Math.sqrt(.5*this.qp),b=Math.sin(this.lat0),this.sinb1=g(this.e,b)/this.qp,this.cosb1=Math.sqrt(1-this.sinb1*this.sinb1),this.dd=Math.cos(this.lat0)/(Math.sqrt(1-this.es*b*b)*this.rq*this.cosb1),this.ymf=(this.xmf=this.rq)/this.dd,this.xmf*=this.dd}}else this.mode===this.OBLIQ&&(this.sinph0=Math.sin(this.lat0),this.cosph0=Math.cos(this.lat0))},c.forward=function(a){var b,c,i,j,k,l,m,n,o,p,q=a.x,r=a.y;if(q=h(q-this.long0),this.sphere){if(k=Math.sin(r),p=Math.cos(r),i=Math.cos(q),this.mode===this.OBLIQ||this.mode===this.EQUIT){if(c=this.mode===this.EQUIT?1+p*i:1+this.sinph0*k+this.cosph0*p*i,f>=c)return null;c=Math.sqrt(2/c),b=c*p*Math.sin(q),c*=this.mode===this.EQUIT?k:this.cosph0*k-this.sinph0*p*i}else if(this.mode===this.N_POLE||this.mode===this.S_POLE){if(this.mode===this.N_POLE&&(i=-i),Math.abs(r+this.phi0)=0?(b=(o=Math.sqrt(l))*j,c=i*(this.mode===this.S_POLE?o:-o)):b=c=0}}return a.x=this.a*b+this.x0,a.y=this.a*c+this.y0,a},c.inverse=function(a){a.x-=this.x0,a.y-=this.y0;var b,c,e,g,i,j,k,l=a.x/this.a,m=a.y/this.a;if(this.sphere){var n,o=0,p=0;if(n=Math.sqrt(l*l+m*m),c=.5*n,c>1)return null;switch(c=2*Math.asin(c),(this.mode===this.OBLIQ||this.mode===this.EQUIT)&&(p=Math.sin(c),o=Math.cos(c)),this.mode){case this.EQUIT:c=Math.abs(n)<=f?0:Math.asin(m*p/n),l*=p,m=o*n;break;case this.OBLIQ:c=Math.abs(n)<=f?this.phi0:Math.asin(o*this.sinph0+m*p*this.cosph0/n),l*=p*this.cosph0,m=(o-Math.sin(c)*this.sinph0)*n;break;case this.N_POLE:m=-m,c=d-c;break;case this.S_POLE:c-=d}b=0!==m||this.mode!==this.EQUIT&&this.mode!==this.OBLIQ?Math.atan2(l,m):0}else{if(k=0,this.mode===this.OBLIQ||this.mode===this.EQUIT){if(l/=this.dd,m*=this.dd,j=Math.sqrt(l*l+m*m),f>j)return a.x=0,a.y=this.phi0,a;g=2*Math.asin(.5*j/this.rq),e=Math.cos(g),l*=g=Math.sin(g),this.mode===this.OBLIQ?(k=e*this.sinb1+m*g*this.cosb1/j,i=this.qp*k,m=j*this.cosb1*e-m*this.sinb1*g):(k=m*g/j,i=this.qp*k,m=j*e)}else if(this.mode===this.N_POLE||this.mode===this.S_POLE){if(this.mode===this.N_POLE&&(m=-m),i=l*l+m*m,!i)return a.x=0,a.y=this.phi0,a;k=1-i/this.qp,this.mode===this.S_POLE&&(k=-k)}b=Math.atan2(l,m),c=this.authlat(Math.asin(k),this.apa)}return a.x=h(this.long0+b),a.y=c,a},c.P00=.3333333333333333,c.P01=.17222222222222222,c.P02=.10257936507936508,c.P10=.06388888888888888,c.P11=.0664021164021164,c.P20=.016415012942191543,c.authset=function(a){var b,c=[];return c[0]=a*this.P00,b=a*a,c[0]+=b*this.P01,c[1]=b*this.P10,b*=a,c[0]+=b*this.P02,c[1]+=b*this.P11,c[2]=b*this.P20,c},c.authlat=function(a,b){var c=a+a;return a+b[0]*Math.sin(c)+b[1]*Math.sin(c+c)+b[2]*Math.sin(c+c+c)},c.names=["Lambert Azimuthal Equal Area","Lambert_Azimuthal_Equal_Area","laea"]},{"../common/adjust_lon":5,"../common/qsfnz":20}],49:[function(a,b,c){var d=1e-10,e=a("../common/msfnz"),f=a("../common/tsfnz"),g=Math.PI/2,h=a("../common/sign"),i=a("../common/adjust_lon"),j=a("../common/phi2z");c.init=function(){if(this.lat2||(this.lat2=this.lat1),this.k0||(this.k0=1),this.x0=this.x0||0,this.y0=this.y0||0,!(Math.abs(this.lat1+this.lat2)d?Math.log(g/k)/Math.log(h/l):b,isNaN(this.ns)&&(this.ns=b),this.f0=g/(this.ns*Math.pow(h,this.ns)),this.rh=this.a*this.f0*Math.pow(m,this.ns),this.title||(this.title="Lambert Conformal Conic")}},c.forward=function(a){var b=a.x,c=a.y;Math.abs(2*Math.abs(c)-Math.PI)<=d&&(c=h(c)*(g-2*d));var e,j,k=Math.abs(Math.abs(c)-g);if(k>d)e=f(this.e,c,Math.sin(c)),j=this.a*this.f0*Math.pow(e,this.ns);else{if(k=c*this.ns,0>=k)return null;j=0}var l=this.ns*i(b-this.long0);return a.x=this.k0*j*Math.sin(l)+this.x0,a.y=this.k0*(this.rh-j*Math.cos(l))+this.y0,a},c.inverse=function(a){var b,c,d,e,f,h=(a.x-this.x0)/this.k0,k=this.rh-(a.y-this.y0)/this.k0;this.ns>0?(b=Math.sqrt(h*h+k*k),c=1):(b=-Math.sqrt(h*h+k*k),c=-1);var l=0;if(0!==b&&(l=Math.atan2(c*h,c*k)),0!==b||this.ns>0){if(c=1/this.ns,d=Math.pow(b/(this.a*this.f0),c),e=j(this.e,d),-9999===e)return null}else e=-g;return f=i(l/this.ns+this.long0),a.x=f,a.y=e,a},c.names=["Lambert Tangential Conformal Conic Projection","Lambert_Conformal_Conic","Lambert_Conformal_Conic_2SP","lcc"]},{"../common/adjust_lon":5,"../common/msfnz":15,"../common/phi2z":16,"../common/sign":21,"../common/tsfnz":24}],50:[function(a,b,c){function d(a){return a}c.init=function(){},c.forward=d,c.inverse=d,c.names=["longlat","identity"]},{}],51:[function(a,b,c){var d=a("../common/msfnz"),e=Math.PI/2,f=1e-10,g=57.29577951308232,h=a("../common/adjust_lon"),i=Math.PI/4,j=a("../common/tsfnz"),k=a("../common/phi2z");c.init=function(){var a=this.b/this.a;this.es=1-a*a,"x0"in this||(this.x0=0),"y0"in this||(this.y0=0),this.e=Math.sqrt(this.es),this.lat_ts?this.k0=this.sphere?Math.cos(this.lat_ts):d(this.e,Math.sin(this.lat_ts),Math.cos(this.lat_ts)):this.k0||(this.k0=this.k?this.k:1)},c.forward=function(a){var b=a.x,c=a.y;if(c*g>90&&-90>c*g&&b*g>180&&-180>b*g)return null;var d,k;if(Math.abs(Math.abs(c)-e)<=f)return null;if(this.sphere)d=this.x0+this.a*this.k0*h(b-this.long0),k=this.y0+this.a*this.k0*Math.log(Math.tan(i+.5*c));else{var l=Math.sin(c),m=j(this.e,c,l);d=this.x0+this.a*this.k0*h(b-this.long0),k=this.y0-this.a*this.k0*Math.log(m)}return a.x=d,a.y=k,a},c.inverse=function(a){var b,c,d=a.x-this.x0,f=a.y-this.y0;if(this.sphere)c=e-2*Math.atan(Math.exp(-f/(this.a*this.k0)));else{var g=Math.exp(-f/(this.a*this.k0));if(c=k(this.e,g),-9999===c)return null}return b=h(this.long0+d/(this.a*this.k0)),a.x=b,a.y=c,a},c.names=["Mercator","Popular Visualisation Pseudo Mercator","Mercator_1SP","Mercator_Auxiliary_Sphere","merc"]},{"../common/adjust_lon":5,"../common/msfnz":15,"../common/phi2z":16,"../common/tsfnz":24}],52:[function(a,b,c){var d=a("../common/adjust_lon");c.init=function(){},c.forward=function(a){var b=a.x,c=a.y,e=d(b-this.long0),f=this.x0+this.a*e,g=this.y0+this.a*Math.log(Math.tan(Math.PI/4+c/2.5))*1.25;return a.x=f,a.y=g,a},c.inverse=function(a){a.x-=this.x0,a.y-=this.y0;var b=d(this.long0+a.x/this.a),c=2.5*(Math.atan(Math.exp(.8*a.y/this.a))-Math.PI/4);return a.x=b,a.y=c,a},c.names=["Miller_Cylindrical","mill"]},{"../common/adjust_lon":5}],53:[function(a,b,c){var d=a("../common/adjust_lon"),e=1e-10;c.init=function(){},c.forward=function(a){for(var b=a.x,c=a.y,f=d(b-this.long0),g=c,h=Math.PI*Math.sin(c),i=0;!0;i++){var j=-(g+Math.sin(g)-h)/(1+Math.cos(g));if(g+=j,Math.abs(j).999999999999&&(c=.999999999999),b=Math.asin(c);var e=d(this.long0+a.x/(.900316316158*this.a*Math.cos(b)));e<-Math.PI&&(e=-Math.PI),e>Math.PI&&(e=Math.PI),c=(2*b+Math.sin(2*b))/Math.PI,Math.abs(c)>1&&(c=1);var f=Math.asin(c);return a.x=e,a.y=f,a},c.names=["Mollweide","moll"]},{"../common/adjust_lon":5}],54:[function(a,b,c){var d=484813681109536e-20;c.iterations=1,c.init=function(){this.A=[],this.A[1]=.6399175073,this.A[2]=-.1358797613,this.A[3]=.063294409,this.A[4]=-.02526853,this.A[5]=.0117879,this.A[6]=-.0055161,this.A[7]=.0026906,this.A[8]=-.001333,this.A[9]=67e-5,this.A[10]=-34e-5,this.B_re=[],this.B_im=[],this.B_re[1]=.7557853228,this.B_im[1]=0,this.B_re[2]=.249204646,this.B_im[2]=.003371507,this.B_re[3]=-.001541739,this.B_im[3]=.04105856,this.B_re[4]=-.10162907,this.B_im[4]=.01727609,this.B_re[5]=-.26623489,this.B_im[5]=-.36249218,this.B_re[6]=-.6870983,this.B_im[6]=-1.1651967,this.C_re=[],this.C_im=[],this.C_re[1]=1.3231270439,this.C_im[1]=0,this.C_re[2]=-.577245789,this.C_im[2]=-.007809598,this.C_re[3]=.508307513,this.C_im[3]=-.112208952,this.C_re[4]=-.15094762,this.C_im[4]=.18200602,this.C_re[5]=1.01418179,this.C_im[5]=1.64497696,this.C_re[6]=1.9660549,this.C_im[6]=2.5127645,this.D=[],this.D[1]=1.5627014243,this.D[2]=.5185406398,this.D[3]=-.03333098,this.D[4]=-.1052906,this.D[5]=-.0368594,this.D[6]=.007317,this.D[7]=.0122,this.D[8]=.00394,this.D[9]=-.0013},c.forward=function(a){var b,c=a.x,e=a.y,f=e-this.lat0,g=c-this.long0,h=f/d*1e-5,i=g,j=1,k=0;for(b=1;10>=b;b++)j*=h,k+=this.A[b]*j;var l,m,n=k,o=i,p=1,q=0,r=0,s=0;for(b=1;6>=b;b++)l=p*n-q*o,m=q*n+p*o,p=l,q=m,r=r+this.B_re[b]*p-this.B_im[b]*q,s=s+this.B_im[b]*p+this.B_re[b]*q;return a.x=s*this.a+this.x0,a.y=r*this.a+this.y0,a},c.inverse=function(a){var b,c,e,f=a.x,g=a.y,h=f-this.x0,i=g-this.y0,j=i/this.a,k=h/this.a,l=1,m=0,n=0,o=0;for(b=1;6>=b;b++)c=l*j-m*k,e=m*j+l*k,l=c,m=e,n=n+this.C_re[b]*l-this.C_im[b]*m,o=o+this.C_im[b]*l+this.C_re[b]*m;for(var p=0;p=b;b++)q=s*n-t*o,r=t*n+s*o,s=q,t=r,u+=(b-1)*(this.B_re[b]*s-this.B_im[b]*t),v+=(b-1)*(this.B_im[b]*s+this.B_re[b]*t);s=1,t=0;var w=this.B_re[1],x=this.B_im[1];for(b=2;6>=b;b++)q=s*n-t*o,r=t*n+s*o,s=q,t=r,w+=b*(this.B_re[b]*s-this.B_im[b]*t),x+=b*(this.B_im[b]*s+this.B_re[b]*t);var y=w*w+x*x;n=(u*w+v*x)/y,o=(v*w-u*x)/y}var z=n,A=o,B=1,C=0;for(b=1;9>=b;b++)B*=z,C+=this.D[b]*B;var D=this.lat0+C*d*1e5,E=this.long0+A;return a.x=E,a.y=D,a},c.names=["New_Zealand_Map_Grid","nzmg"]},{}],55:[function(a,b,c){var d=a("../common/tsfnz"),e=a("../common/adjust_lon"),f=a("../common/phi2z"),g=Math.PI/2,h=Math.PI/4,i=1e-10;c.init=function(){this.no_off=this.no_off||!1,this.no_rot=this.no_rot||!1,isNaN(this.k0)&&(this.k0=1);var a=Math.sin(this.lat0),b=Math.cos(this.lat0),c=this.e*a;this.bl=Math.sqrt(1+this.es/(1-this.es)*Math.pow(b,4)),this.al=this.a*this.bl*this.k0*Math.sqrt(1-this.es)/(1-c*c);var f=d(this.e,this.lat0,a),g=this.bl/b*Math.sqrt((1-this.es)/(1-c*c));1>g*g&&(g=1);var h,i;if(isNaN(this.longc)){var j=d(this.e,this.lat1,Math.sin(this.lat1)),k=d(this.e,this.lat2,Math.sin(this.lat2));this.el=this.lat0>=0?(g+Math.sqrt(g*g-1))*Math.pow(f,this.bl):(g-Math.sqrt(g*g-1))*Math.pow(f,this.bl);var l=Math.pow(j,this.bl),m=Math.pow(k,this.bl);h=this.el/l,i=.5*(h-1/h);var n=(this.el*this.el-m*l)/(this.el*this.el+m*l),o=(m-l)/(m+l),p=e(this.long1-this.long2);this.long0=.5*(this.long1+this.long2)-Math.atan(n*Math.tan(.5*this.bl*p)/o)/this.bl,this.long0=e(this.long0);var q=e(this.long1-this.long0);this.gamma0=Math.atan(Math.sin(this.bl*q)/i),this.alpha=Math.asin(g*Math.sin(this.gamma0))}else h=this.lat0>=0?g+Math.sqrt(g*g-1):g-Math.sqrt(g*g-1),this.el=h*Math.pow(f,this.bl),i=.5*(h-1/h),this.gamma0=Math.asin(Math.sin(this.alpha)/g),this.long0=this.longc-Math.asin(i*Math.tan(this.gamma0))/this.bl;this.uc=this.no_off?0:this.lat0>=0?this.al/this.bl*Math.atan2(Math.sqrt(g*g-1),Math.cos(this.alpha)):-1*this.al/this.bl*Math.atan2(Math.sqrt(g*g-1),Math.cos(this.alpha))},c.forward=function(a){var b,c,f,j=a.x,k=a.y,l=e(j-this.long0);if(Math.abs(Math.abs(k)-g)<=i)f=k>0?-1:1,c=this.al/this.bl*Math.log(Math.tan(h+f*this.gamma0*.5)),b=-1*f*g*this.al/this.bl;else{var m=d(this.e,k,Math.sin(k)),n=this.el/Math.pow(m,this.bl),o=.5*(n-1/n),p=.5*(n+1/n),q=Math.sin(this.bl*l),r=(o*Math.sin(this.gamma0)-q*Math.cos(this.gamma0))/p;c=Math.abs(Math.abs(r)-1)<=i?Number.POSITIVE_INFINITY:.5*this.al*Math.log((1-r)/(1+r))/this.bl,b=Math.abs(Math.cos(this.bl*l))<=i?this.al*this.bl*l:this.al*Math.atan2(o*Math.cos(this.gamma0)+q*Math.sin(this.gamma0),Math.cos(this.bl*l))/this.bl}return this.no_rot?(a.x=this.x0+b,a.y=this.y0+c):(b-=this.uc,a.x=this.x0+c*Math.cos(this.alpha)+b*Math.sin(this.alpha),a.y=this.y0+b*Math.cos(this.alpha)-c*Math.sin(this.alpha)),a},c.inverse=function(a){var b,c;this.no_rot?(c=a.y-this.y0,b=a.x-this.x0):(c=(a.x-this.x0)*Math.cos(this.alpha)-(a.y-this.y0)*Math.sin(this.alpha),b=(a.y-this.y0)*Math.cos(this.alpha)+(a.x-this.x0)*Math.sin(this.alpha),b+=this.uc);var d=Math.exp(-1*this.bl*c/this.al),h=.5*(d-1/d),j=.5*(d+1/d),k=Math.sin(this.bl*b/this.al),l=(k*Math.cos(this.gamma0)+h*Math.sin(this.gamma0))/j,m=Math.pow(this.el/Math.sqrt((1+l)/(1-l)),1/this.bl);return Math.abs(l-1)g?(g=Math.sin(b),c=this.long0+a.x*Math.sqrt(1-this.es*g*g)/(this.a*Math.cos(b)),f=d(c)):j>g-k&&(f=this.long0)),a.x=f,a.y=b,a},c.names=["Sinusoidal","sinu"]},{"../common/adjust_lat":4,"../common/adjust_lon":5,"../common/asinz":6,"../common/pj_enfn":17,"../common/pj_inv_mlfn":18,"../common/pj_mlfn":19}],58:[function(a,b,c){c.init=function(){var a=this.lat0;this.lambda0=this.long0;var b=Math.sin(a),c=this.a,d=this.rf,e=1/d,f=2*e-Math.pow(e,2),g=this.e=Math.sqrt(f);this.R=this.k0*c*Math.sqrt(1-f)/(1-f*Math.pow(b,2)),this.alpha=Math.sqrt(1+f/(1-f)*Math.pow(Math.cos(a),4)),this.b0=Math.asin(b/this.alpha);var h=Math.log(Math.tan(Math.PI/4+this.b0/2)),i=Math.log(Math.tan(Math.PI/4+a/2)),j=Math.log((1+g*b)/(1-g*b));this.K=h-this.alpha*i+this.alpha*g/2*j},c.forward=function(a){var b=Math.log(Math.tan(Math.PI/4-a.y/2)),c=this.e/2*Math.log((1+this.e*Math.sin(a.y))/(1-this.e*Math.sin(a.y))),d=-this.alpha*(b+c)+this.K,e=2*(Math.atan(Math.exp(d))-Math.PI/4),f=this.alpha*(a.x-this.lambda0),g=Math.atan(Math.sin(f)/(Math.sin(this.b0)*Math.tan(e)+Math.cos(this.b0)*Math.cos(f))),h=Math.asin(Math.cos(this.b0)*Math.sin(e)-Math.sin(this.b0)*Math.cos(e)*Math.cos(f));return a.y=this.R/2*Math.log((1+Math.sin(h))/(1-Math.sin(h)))+this.y0,a.x=this.R*g+this.x0,a},c.inverse=function(a){for(var b=a.x-this.x0,c=a.y-this.y0,d=b/this.R,e=2*(Math.atan(Math.exp(c/this.R))-Math.PI/4),f=Math.asin(Math.cos(this.b0)*Math.sin(e)+Math.sin(this.b0)*Math.cos(e)*Math.cos(d)),g=Math.atan(Math.sin(d)/(Math.cos(this.b0)*Math.cos(d)-Math.sin(this.b0)*Math.tan(e))),h=this.lambda0+g/this.alpha,i=0,j=f,k=-1e3,l=0;Math.abs(j-k)>1e-7;){if(++l>20)return;i=1/this.alpha*(Math.log(Math.tan(Math.PI/4+f/2))-this.K)+this.e*Math.log(Math.tan(Math.PI/4+Math.asin(this.e*Math.sin(j))/2)),k=j,j=2*Math.atan(Math.exp(i))-Math.PI/2}return a.x=h,a.y=j,a},c.names=["somerc"]},{}],59:[function(a,b,c){var d=Math.PI/2,e=1e-10,f=a("../common/sign"),g=a("../common/msfnz"),h=a("../common/tsfnz"),i=a("../common/phi2z"),j=a("../common/adjust_lon");c.ssfn_=function(a,b,c){return b*=c,Math.tan(.5*(d+a))*Math.pow((1-b)/(1+b),.5*c)},c.init=function(){this.coslat0=Math.cos(this.lat0),this.sinlat0=Math.sin(this.lat0),this.sphere?1===this.k0&&!isNaN(this.lat_ts)&&Math.abs(this.coslat0)<=e&&(this.k0=.5*(1+f(this.lat0)*Math.sin(this.lat_ts))):(Math.abs(this.coslat0)<=e&&(this.con=this.lat0>0?1:-1),this.cons=Math.sqrt(Math.pow(1+this.e,1+this.e)*Math.pow(1-this.e,1-this.e)),1===this.k0&&!isNaN(this.lat_ts)&&Math.abs(this.coslat0)<=e&&(this.k0=.5*this.cons*g(this.e,Math.sin(this.lat_ts),Math.cos(this.lat_ts))/h(this.e,this.con*this.lat_ts,this.con*Math.sin(this.lat_ts))),this.ms1=g(this.e,this.sinlat0,this.coslat0),this.X0=2*Math.atan(this.ssfn_(this.lat0,this.sinlat0,this.e))-d,this.cosX0=Math.cos(this.X0),this.sinX0=Math.sin(this.X0))},c.forward=function(a){var b,c,f,g,i,k,l=a.x,m=a.y,n=Math.sin(m),o=Math.cos(m),p=j(l-this.long0);return Math.abs(Math.abs(l-this.long0)-Math.PI)<=e&&Math.abs(m+this.lat0)<=e?(a.x=0/0,a.y=0/0,a):this.sphere?(b=2*this.k0/(1+this.sinlat0*n+this.coslat0*o*Math.cos(p)),a.x=this.a*b*o*Math.sin(p)+this.x0,a.y=this.a*b*(this.coslat0*n-this.sinlat0*o*Math.cos(p))+this.y0,a):(c=2*Math.atan(this.ssfn_(m,n,this.e))-d,g=Math.cos(c),f=Math.sin(c),Math.abs(this.coslat0)<=e?(i=h(this.e,m*this.con,this.con*n),k=2*this.a*this.k0*i/this.cons,a.x=this.x0+k*Math.sin(l-this.long0),a.y=this.y0-this.con*k*Math.cos(l-this.long0),a):(Math.abs(this.sinlat0)=k?(a.x=b,a.y=c,a):(c=Math.asin(Math.cos(l)*this.sinlat0+a.y*Math.sin(l)*this.coslat0/k),b=j(Math.abs(this.coslat0)0?this.long0+Math.atan2(a.x,-1*a.y):this.long0+Math.atan2(a.x,a.y):this.long0+Math.atan2(a.x*Math.sin(l),k*this.coslat0*Math.cos(l)-a.y*this.sinlat0*Math.sin(l))),a.x=b,a.y=c,a)}if(Math.abs(this.coslat0)<=e){if(e>=k)return c=this.lat0,b=this.long0,a.x=b,a.y=c,a;a.x*=this.con,a.y*=this.con,f=k*this.cons/(2*this.a*this.k0),c=this.con*i(this.e,f),b=this.con*j(this.con*this.long0+Math.atan2(a.x,-1*a.y))}else g=2*Math.atan(k*this.cosX0/(2*this.a*this.k0*this.ms1)),b=this.long0,e>=k?h=this.X0:(h=Math.asin(Math.cos(g)*this.sinX0+a.y*Math.sin(g)*this.cosX0/k),b=j(this.long0+Math.atan2(a.x*Math.sin(g),k*this.cosX0*Math.cos(g)-a.y*this.sinX0*Math.sin(g)))),c=-1*i(this.e,Math.tan(.5*(d+h)));return a.x=b,a.y=c,a},c.names=["stere"]},{"../common/adjust_lon":5,"../common/msfnz":15,"../common/phi2z":16,"../common/sign":21,"../common/tsfnz":24}],60:[function(a,b,c){var d=a("./gauss"),e=a("../common/adjust_lon");c.init=function(){d.init.apply(this),this.rc&&(this.sinc0=Math.sin(this.phic0),this.cosc0=Math.cos(this.phic0),this.R2=2*this.rc,this.title||(this.title="Oblique Stereographic Alternative"))},c.forward=function(a){var b,c,f,g;return a.x=e(a.x-this.long0),d.forward.apply(this,[a]),b=Math.sin(a.y),c=Math.cos(a.y),f=Math.cos(a.x),g=this.k0*this.R2/(1+this.sinc0*b+this.cosc0*c*f),a.x=g*c*Math.sin(a.x),a.y=g*(this.cosc0*b-this.sinc0*c*f),a.x=this.a*a.x+this.x0,a.y=this.a*a.y+this.y0,a},c.inverse=function(a){var b,c,f,g,h;if(a.x=(a.x-this.x0)/this.a,a.y=(a.y-this.y0)/this.a,a.x/=this.k0,a.y/=this.k0,h=Math.sqrt(a.x*a.x+a.y*a.y)){var i=2*Math.atan2(h,this.R2);b=Math.sin(i),c=Math.cos(i),g=Math.asin(c*this.sinc0+a.y*b*this.cosc0/h),f=Math.atan2(a.x*b,h*this.cosc0*c-a.y*this.sinc0*b)}else g=this.phic0,f=0;return a.x=f,a.y=g,d.inverse.apply(this,[a]),a.x=e(a.x+this.long0),a},c.names=["Stereographic_North_Pole","Oblique_Stereographic","Polar_Stereographic","sterea","Oblique Stereographic Alternative"]},{"../common/adjust_lon":5,"./gauss":45}],61:[function(a,b,c){var d=a("../common/e0fn"),e=a("../common/e1fn"),f=a("../common/e2fn"),g=a("../common/e3fn"),h=a("../common/mlfn"),i=a("../common/adjust_lon"),j=Math.PI/2,k=1e-10,l=a("../common/sign"),m=a("../common/asinz");c.init=function(){this.e0=d(this.es),this.e1=e(this.es),this.e2=f(this.es),this.e3=g(this.es),this.ml0=this.a*h(this.e0,this.e1,this.e2,this.e3,this.lat0)},c.forward=function(a){var b,c,d,e=a.x,f=a.y,g=i(e-this.long0),j=Math.sin(f),k=Math.cos(f);if(this.sphere){var l=k*Math.sin(g);if(Math.abs(Math.abs(l)-1)<1e-10)return 93;c=.5*this.a*this.k0*Math.log((1+l)/(1-l)),b=Math.acos(k*Math.cos(g)/Math.sqrt(1-l*l)),0>f&&(b=-b),d=this.a*this.k0*(b-this.lat0)}else{var m=k*g,n=Math.pow(m,2),o=this.ep2*Math.pow(k,2),p=Math.tan(f),q=Math.pow(p,2);b=1-this.es*Math.pow(j,2);var r=this.a/Math.sqrt(b),s=this.a*h(this.e0,this.e1,this.e2,this.e3,f);c=this.k0*r*m*(1+n/6*(1-q+o+n/20*(5-18*q+Math.pow(q,2)+72*o-58*this.ep2)))+this.x0,d=this.k0*(s-this.ml0+r*p*n*(.5+n/24*(5-q+9*o+4*Math.pow(o,2)+n/30*(61-58*q+Math.pow(q,2)+600*o-330*this.ep2))))+this.y0}return a.x=c,a.y=d,a},c.inverse=function(a){var b,c,d,e,f,g,h=6;if(this.sphere){var n=Math.exp(a.x/(this.a*this.k0)),o=.5*(n-1/n),p=this.lat0+a.y/(this.a*this.k0),q=Math.cos(p);b=Math.sqrt((1-q*q)/(1+o*o)),f=m(b),0>p&&(f=-f),g=0===o&&0===q?this.long0:i(Math.atan2(o,q)+this.long0)}else{var r=a.x-this.x0,s=a.y-this.y0;for(b=(this.ml0+s/this.k0)/this.a,c=b,e=0;!0&&(d=(b+this.e1*Math.sin(2*c)-this.e2*Math.sin(4*c)+this.e3*Math.sin(6*c))/this.e0-c,c+=d,!(Math.abs(d)<=k));e++)if(e>=h)return 95;if(Math.abs(c)=0?this.y0+Math.PI*this.R*Math.tan(.5*k):this.y0+Math.PI*this.R*-Math.tan(.5*k));var l=.5*Math.abs(Math.PI/j-j/Math.PI),m=l*l,n=Math.sin(k),o=Math.cos(k),p=o/(n+o-1),q=p*p,r=p*(2/n-1),s=r*r,t=Math.PI*this.R*(l*(p-s)+Math.sqrt(m*(p-s)*(p-s)-(s+m)*(q-s)))/(s+m);0>j&&(t=-t),b=this.x0+t;var u=m+p;return t=Math.PI*this.R*(r*u-l*Math.sqrt((s+m)*(m+1)-u*u))/(s+m),c=i>=0?this.y0+t:this.y0-t,a.x=b,a.y=c,a},c.inverse=function(a){var b,c,e,g,h,i,j,k,l,m,n,o,p;return a.x-=this.x0,a.y-=this.y0,n=Math.PI*this.R,e=a.x/n,g=a.y/n,h=e*e+g*g,i=-Math.abs(g)*(1+h),j=i-2*g*g+e*e,k=-2*i+1+2*g*g+h*h,p=g*g/k+(2*j*j*j/k/k/k-9*i*j/k/k)/27,l=(i-j*j/3/k)/k,m=2*Math.sqrt(-l/3),n=3*p/l/m,Math.abs(n)>1&&(n=n>=0?1:-1),o=Math.acos(n)/3,c=a.y>=0?(-m*Math.cos(o+Math.PI/3)-j/3/k)*Math.PI:-(-m*Math.cos(o+Math.PI/3)-j/3/k)*Math.PI,b=Math.abs(e)-1?(b[e]={name:a[0].toLowerCase(),convert:a[1]},3===a.length&&(b[e].auth=a[2])):"SPHEROID"===e?(b[e]={name:a[0],a:a[1],rf:a[2]},4===a.length&&(b[e].auth=a[3])):["GEOGCS","GEOCCS","DATUM","VERT_CS","COMPD_CS","LOCAL_CS","FITTED_CS","LOCAL_DATUM"].indexOf(e)>-1?(a[0]=["name",a[0]],c(b,e,a)):a.every(function(a){return Array.isArray(a)})?c(b,e,a):d(a,b[e])):b[e]=!0,void 0):void(b[a]=!0)}function e(a,b){var c=b[0],d=b[1];!(c in a)&&d in a&&(a[c]=a[d],3===b.length&&(a[c]=b[2](a[c])))}function f(a){return a*h}function g(a){function b(b){var c=a.to_meter||1;return parseFloat(b,10)*c}"GEOGCS"===a.type?a.projName="longlat":"LOCAL_CS"===a.type?(a.projName="identity",a.local=!0):a.projName="object"==typeof a.PROJECTION?Object.keys(a.PROJECTION)[0]:a.PROJECTION,a.UNIT&&(a.units=a.UNIT.name.toLowerCase(),"metre"===a.units&&(a.units="meter"),a.UNIT.convert&&(a.to_meter=parseFloat(a.UNIT.convert,10))),a.GEOGCS&&(a.datumCode=a.GEOGCS.DATUM?a.GEOGCS.DATUM.name.toLowerCase():a.GEOGCS.name.toLowerCase(),"d_"===a.datumCode.slice(0,2)&&(a.datumCode=a.datumCode.slice(2)),("new_zealand_geodetic_datum_1949"===a.datumCode||"new_zealand_1949"===a.datumCode)&&(a.datumCode="nzgd49"),"wgs_1984"===a.datumCode&&("Mercator_Auxiliary_Sphere"===a.PROJECTION&&(a.sphere=!0),a.datumCode="wgs84"),"_ferro"===a.datumCode.slice(-6)&&(a.datumCode=a.datumCode.slice(0,-6)),"_jakarta"===a.datumCode.slice(-8)&&(a.datumCode=a.datumCode.slice(0,-8)),~a.datumCode.indexOf("belge")&&(a.datumCode="rnb72"),a.GEOGCS.DATUM&&a.GEOGCS.DATUM.SPHEROID&&(a.ellps=a.GEOGCS.DATUM.SPHEROID.name.replace("_19","").replace(/[Cc]larke\_18/,"clrk"),"international"===a.ellps.toLowerCase().slice(0,13)&&(a.ellps="intl"),a.a=a.GEOGCS.DATUM.SPHEROID.a,a.rf=parseFloat(a.GEOGCS.DATUM.SPHEROID.rf,10)),~a.datumCode.indexOf("osgb_1936")&&(a.datumCode="osgb36")),a.b&&!isFinite(a.b)&&(a.b=a.a); +var c=function(b){return e(a,b)},d=[["standard_parallel_1","Standard_Parallel_1"],["standard_parallel_2","Standard_Parallel_2"],["false_easting","False_Easting"],["false_northing","False_Northing"],["central_meridian","Central_Meridian"],["latitude_of_origin","Latitude_Of_Origin"],["scale_factor","Scale_Factor"],["k0","scale_factor"],["latitude_of_center","Latitude_of_center"],["lat0","latitude_of_center",f],["longitude_of_center","Longitude_Of_Center"],["longc","longitude_of_center",f],["x0","false_easting",b],["y0","false_northing",b],["long0","central_meridian",f],["lat0","latitude_of_origin",f],["lat0","standard_parallel_1",f],["lat1","standard_parallel_1",f],["lat2","standard_parallel_2",f],["alpha","azimuth",f],["srsCode","name"]];d.forEach(c),a.long0||!a.longc||"Albers_Conic_Equal_Area"!==a.PROJECTION&&"Lambert_Azimuthal_Equal_Area"!==a.PROJECTION||(a.long0=a.longc)}var h=.017453292519943295,i=a("./extend");b.exports=function(a,b){var c=JSON.parse((","+a).replace(/\s*\,\s*([A-Z_0-9]+?)(\[)/g,',["$1",').slice(1).replace(/\s*\,\s*([A-Z_0-9]+?)\]/g,',"$1"]')),e=c.shift(),f=c.shift();c.unshift(["name",f]),c.unshift(["type",e]),c.unshift("output");var h={};return d(c,h),g(h.output),i(b,h.output)}},{"./extend":33}],66:[function(a,b,c){function d(a){return a*(Math.PI/180)}function e(a){return 180*(a/Math.PI)}function f(a){var b,c,e,f,g,i,j,k,l,m=a.lat,n=a.lon,o=6378137,p=.00669438,q=.9996,r=d(m),s=d(n);l=Math.floor((n+180)/6)+1,180===n&&(l=60),m>=56&&64>m&&n>=3&&12>n&&(l=32),m>=72&&84>m&&(n>=0&&9>n?l=31:n>=9&&21>n?l=33:n>=21&&33>n?l=35:n>=33&&42>n&&(l=37)),b=6*(l-1)-180+3,k=d(b),c=p/(1-p),e=o/Math.sqrt(1-p*Math.sin(r)*Math.sin(r)),f=Math.tan(r)*Math.tan(r),g=c*Math.cos(r)*Math.cos(r),i=Math.cos(r)*(s-k),j=o*((1-p/4-3*p*p/64-5*p*p*p/256)*r-(3*p/8+3*p*p/32+45*p*p*p/1024)*Math.sin(2*r)+(15*p*p/256+45*p*p*p/1024)*Math.sin(4*r)-35*p*p*p/3072*Math.sin(6*r));var t=q*e*(i+(1-f+g)*i*i*i/6+(5-18*f+f*f+72*g-58*c)*i*i*i*i*i/120)+5e5,u=q*(j+e*Math.tan(r)*(i*i/2+(5-f+9*g+4*g*g)*i*i*i*i/24+(61-58*f+f*f+600*g-330*c)*i*i*i*i*i*i/720));return 0>m&&(u+=1e7),{northing:Math.round(u),easting:Math.round(t),zoneNumber:l,zoneLetter:h(m)}}function g(a){var b=a.northing,c=a.easting,d=a.zoneLetter,f=a.zoneNumber;if(0>f||f>60)return null;var h,i,j,k,l,m,n,o,p,q,r=.9996,s=6378137,t=.00669438,u=(1-Math.sqrt(1-t))/(1+Math.sqrt(1-t)),v=c-5e5,w=b;"N">d&&(w-=1e7),o=6*(f-1)-180+3,h=t/(1-t),n=w/r,p=n/(s*(1-t/4-3*t*t/64-5*t*t*t/256)),q=p+(3*u/2-27*u*u*u/32)*Math.sin(2*p)+(21*u*u/16-55*u*u*u*u/32)*Math.sin(4*p)+151*u*u*u/96*Math.sin(6*p),i=s/Math.sqrt(1-t*Math.sin(q)*Math.sin(q)),j=Math.tan(q)*Math.tan(q),k=h*Math.cos(q)*Math.cos(q),l=s*(1-t)/Math.pow(1-t*Math.sin(q)*Math.sin(q),1.5),m=v/(i*r);var x=q-i*Math.tan(q)/l*(m*m/2-(5+3*j+10*k-4*k*k-9*h)*m*m*m*m/24+(61+90*j+298*k+45*j*j-252*h-3*k*k)*m*m*m*m*m*m/720);x=e(x);var y=(m-(1+2*j+k)*m*m*m/6+(5-2*k+28*j-3*k*k+8*h+24*j*j)*m*m*m*m*m/120)/Math.cos(q);y=o+e(y);var z;if(a.accuracy){var A=g({northing:a.northing+a.accuracy,easting:a.easting+a.accuracy,zoneLetter:a.zoneLetter,zoneNumber:a.zoneNumber});z={top:A.lat,right:A.lon,bottom:x,left:y}}else z={lat:x,lon:y};return z}function h(a){var b="Z";return 84>=a&&a>=72?b="X":72>a&&a>=64?b="W":64>a&&a>=56?b="V":56>a&&a>=48?b="U":48>a&&a>=40?b="T":40>a&&a>=32?b="S":32>a&&a>=24?b="R":24>a&&a>=16?b="Q":16>a&&a>=8?b="P":8>a&&a>=0?b="N":0>a&&a>=-8?b="M":-8>a&&a>=-16?b="L":-16>a&&a>=-24?b="K":-24>a&&a>=-32?b="J":-32>a&&a>=-40?b="H":-40>a&&a>=-48?b="G":-48>a&&a>=-56?b="F":-56>a&&a>=-64?b="E":-64>a&&a>=-72?b="D":-72>a&&a>=-80&&(b="C"),b}function i(a,b){var c=""+a.easting,d=""+a.northing;return a.zoneNumber+a.zoneLetter+j(a.easting,a.northing,a.zoneNumber)+c.substr(c.length-5,b)+d.substr(d.length-5,b)}function j(a,b,c){var d=k(c),e=Math.floor(a/1e5),f=Math.floor(b/1e5)%20;return l(e,f,d)}function k(a){var b=a%q;return 0===b&&(b=q),b}function l(a,b,c){var d=c-1,e=r.charCodeAt(d),f=s.charCodeAt(d),g=e+a-1,h=f+b,i=!1;g>x&&(g=g-x+t-1,i=!0),(g===u||u>e&&g>u||(g>u||u>e)&&i)&&g++,(g===v||v>e&&g>v||(g>v||v>e)&&i)&&(g++,g===u&&g++),g>x&&(g=g-x+t-1),h>w?(h=h-w+t-1,i=!0):i=!1,(h===u||u>f&&h>u||(h>u||u>f)&&i)&&h++,(h===v||v>f&&h>v||(h>v||v>f)&&i)&&(h++,h===u&&h++),h>w&&(h=h-w+t-1);var j=String.fromCharCode(g)+String.fromCharCode(h);return j}function m(a){if(a&&0===a.length)throw"MGRSPoint coverting from nothing";for(var b,c=a.length,d=null,e="",f=0;!/[A-Z]/.test(b=a.charAt(f));){if(f>=2)throw"MGRSPoint bad conversion from: "+a;e+=b,f++}var g=parseInt(e,10);if(0===f||f+3>c)throw"MGRSPoint bad conversion from: "+a;var h=a.charAt(f++);if("A">=h||"B"===h||"Y"===h||h>="Z"||"I"===h||"O"===h)throw"MGRSPoint zone letter "+h+" not handled: "+a;d=a.substring(f,f+=2);for(var i=k(g),j=n(d.charAt(0),i),l=o(d.charAt(1),i);l0&&(q=1e5/Math.pow(10,v),r=a.substring(f,f+v),w=parseFloat(r)*q,s=a.substring(f+v),x=parseFloat(s)*q),t=w+j,u=x+l,{easting:t,northing:u,zoneLetter:h,zoneNumber:g,accuracy:q}}function n(a,b){for(var c=r.charCodeAt(b-1),d=1e5,e=!1;c!==a.charCodeAt(0);){if(c++,c===u&&c++,c===v&&c++,c>x){if(e)throw"Bad character: "+a;c=t,e=!0}d+=1e5}return d}function o(a,b){if(a>"V")throw"MGRSPoint given invalid Northing "+a;for(var c=s.charCodeAt(b-1),d=0,e=!1;c!==a.charCodeAt(0);){if(c++,c===u&&c++,c===v&&c++,c>w){if(e)throw"Bad character: "+a;c=t,e=!0}d+=1e5}return d}function p(a){var b;switch(a){case"C":b=11e5;break;case"D":b=2e6;break;case"E":b=28e5;break;case"F":b=37e5;break;case"G":b=46e5;break;case"H":b=55e5;break;case"J":b=64e5;break;case"K":b=73e5;break;case"L":b=82e5;break;case"M":b=91e5;break;case"N":b=0;break;case"P":b=8e5;break;case"Q":b=17e5;break;case"R":b=26e5;break;case"S":b=35e5;break;case"T":b=44e5;break;case"U":b=53e5;break;case"V":b=62e5;break;case"W":b=7e6;break;case"X":b=79e5;break;default:b=-1}if(b>=0)return b;throw"Invalid zone letter: "+a}var q=6,r="AJSAJS",s="AFAFAF",t=65,u=73,v=79,w=86,x=90;c.forward=function(a,b){return b=b||5,i(f({lat:a[1],lon:a[0]}),b)},c.inverse=function(a){var b=g(m(a.toUpperCase()));return[b.left,b.bottom,b.right,b.top]},c.toPoint=function(a){var b=c.inverse(a);return[(b[2]+b[0])/2,(b[3]+b[1])/2]}},{}],67:[function(a,b){b.exports={name:"proj4",version:"2.2.1",description:"Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.",main:"lib/index.js",directories:{test:"test",doc:"docs"},scripts:{test:"./node_modules/istanbul/lib/cli.js test ./node_modules/mocha/bin/_mocha test/test.js"},repository:{type:"git",url:"git://github.com/proj4js/proj4js.git"},author:"",license:"MIT",jam:{main:"dist/proj4.js",include:["dist/proj4.js","README.md","AUTHORS","LICENSE.md"]},devDependencies:{"grunt-cli":"~0.1.13",grunt:"~0.4.2","grunt-contrib-connect":"~0.6.0","grunt-contrib-jshint":"~0.8.0",chai:"~1.8.1",mocha:"~1.17.1","grunt-mocha-phantomjs":"~0.4.0",browserify:"~3.24.5","grunt-browserify":"~1.3.0","grunt-contrib-uglify":"~0.3.2",curl:"git://github.com/cujojs/curl.git",istanbul:"~0.2.4",tin:"~0.4.0"},dependencies:{mgrs:"0.0.0"}}},{}],"./includedProjections":[function(a,b){b.exports=a("gWUPNW")},{}],gWUPNW:[function(a,b){var c=[a("./lib/projections/tmerc"),a("./lib/projections/utm"),a("./lib/projections/sterea"),a("./lib/projections/stere"),a("./lib/projections/somerc"),a("./lib/projections/omerc"),a("./lib/projections/lcc"),a("./lib/projections/krovak"),a("./lib/projections/cass"),a("./lib/projections/laea"),a("./lib/projections/aea"),a("./lib/projections/gnom"),a("./lib/projections/cea"),a("./lib/projections/eqc"),a("./lib/projections/poly"),a("./lib/projections/nzmg"),a("./lib/projections/mill"),a("./lib/projections/sinu"),a("./lib/projections/moll"),a("./lib/projections/eqdc"),a("./lib/projections/vandg"),a("./lib/projections/aeqd")];b.exports=function(proj4){c.forEach(function(a){proj4.Proj.projections.add(a)})}},{"./lib/projections/aea":39,"./lib/projections/aeqd":40,"./lib/projections/cass":41,"./lib/projections/cea":42,"./lib/projections/eqc":43,"./lib/projections/eqdc":44,"./lib/projections/gnom":46,"./lib/projections/krovak":47,"./lib/projections/laea":48,"./lib/projections/lcc":49,"./lib/projections/mill":52,"./lib/projections/moll":53,"./lib/projections/nzmg":54,"./lib/projections/omerc":55,"./lib/projections/poly":56,"./lib/projections/sinu":57,"./lib/projections/somerc":58,"./lib/projections/stere":59,"./lib/projections/sterea":60,"./lib/projections/tmerc":61,"./lib/projections/utm":62,"./lib/projections/vandg":63}]},{},[35])(35)}); \ No newline at end of file diff --git a/docs/examples/24/qgis2threejs.css b/docs/examples/24/qgis2threejs.css new file mode 100644 index 00000000..82748424 --- /dev/null +++ b/docs/examples/24/qgis2threejs.css @@ -0,0 +1,286 @@ +body { + font-family: arial, sans-serif; + margin: 0; + overflow: hidden; +} + +#view { + position: absolute; + width: 100%; + height: 100%; +} + +#view.sky { + background: -webkit-gradient(linear, left top, left bottom, from(#98c8f6), color-stop(0.4, #cbebff), to(#f0f9ff)); + background: linear-gradient(to bottom, #98c8f6 0%,#cbebff 40%,#f0f9ff 100%); +} + +.hidden { + display: none !important; +} + +.queryable { + cursor: pointer; +} + +.no-events { + pointer-events: none; +} + +#labels { +} + +.label { + position: absolute; + padding: 2px; + text-shadow: -1px -1px #FFF, 0px -1px #FFF, 1px -1px #FFF, -1px 0px #FFF, 1px 0px #FFF, -1px 1px #FFF, 0px 1px #FFF, 1px 1px #FFF; +} + +.print-label { + /* these 2 properties are copied to canvas 2D context in renderLabels function of Qgis2threejs.js */ + color: black; + font: normal medium sans-serif; +} + +#progress { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 5px; +} + +#bar { + width: 0; + height: 5px; + background-color: #2196F3; + opacity: 1; +} + +#bar.fadeout { + opacity: 0; + height: 0; + transition: all .4s; +} + +#header { + position: absolute; + left: 5px; + top: 5px; +} + +#footer { + position: absolute; + left: 5px; + bottom: 5px; +} + +#infobtn { + cursor: pointer; +} + +#infobtn img { + width: 24px; + height: 24px; +} + +/* popup */ +#popup { + position: absolute; + left: 2px; + top: 2px; + max-width: 480px; + min-width: 300px; + z-index: 9999; + border: solid gray; + border-width: 1px 2px 2px; + border-radius: 3px; + display: none; +} + +#popupbar { + background: dimgray; + color: white; + padding-left: 4px; + height: 18px; + border-radius: 3px 3px 0 0; +} + +#closebtn { + color: rgb(220, 220, 220); + background: gray; + border: 1px solid darkgray; + border-radius: 4px; + line-height: 16px; + font-size: 16px; + font-weight: bold; + width: 16px; + height: 16px; + text-align: center; + float: right; + cursor: pointer; +} + +#popupbody { + background-color: white; + padding: 2px 5px 2px; + border-radius: 0 0 3px 3px; + max-height: 500px; + overflow: auto; +} + +/* identify result */ +#popupbody table { + margin-top: 5px; + margin-bottom: 3px; + width: 100%; +} + +#popupbody table caption { + background-color: gray; + color: white; + font-size: small; + padding: 1px; + padding-left: 6px; + text-align: left; +} + +#popupbody table td { + padding-left: 5px; +} + +#qr_layername_table tr { + background-color: #eeeeee; +} + +#qr_coords_table tr { + background-color: #eeeeee; +} + +#qr_attrs_table tr:nth-child(odd) { + background-color: #eeeeee; +} + +#qr_attrs_table tr td:first-child { + width: 40%; +} + +.action-btn { + display: inline-block; + border: 1px solid gray; + border-radius: 2px; + background-color: #FBFBFB; + cursor: pointer; + font-size: small; + padding: 1px; + margin-left: 2px; +} + +.action-zoom { +} + +.action-move { + display: none; +} + +/* pageinfo */ +#pageinfo { + font-size: small; +} + +#pageinfo h1 { + background-color: gray; + color: white; + font-size: small; + font-weight: normal; + margin-top: 5px; + margin-bottom: 3px; + padding: 1px; + padding-left: 6px; +} + +#urlbox { + width: 100%; +} + +#usage, #about { + margin-left: 5px; +} + +#usage tr:nth-child(odd) { + background-color: #eeeeee; +} + +#usage td.star { + font-weight: bold; +} + +#about ul { + margin: 5px; + margin-left: 20px; + padding: 0px; +} + +.license { + font-size: xx-small; +} + +.download-link { + display: block; + border: 1px solid darkgray; + background: lightgray; + color: black; + font-size: large; + margin: 10px 50px 10px; + padding: 8px; + text-align: center; + text-decoration: none; +} + +/* print dialog */ +.print div { + padding: 5px; +} + +.print label { + margin-left: 5px; +} + +.print input[type="text"] { + width: 40px; + border: 1px solid lightgray; + background: #F6F6F6; + margin-left: 8px; + margin-right: 8px; +} + +.print input[type="checkbox"] { + margin-left: 15px; +} + +.print input[type="submit"] { + display: none; +} + +.print .buttonbox { + text-align: center; + padding-top: 10px; + padding-bottom: 10px; +} + +.print .buttonbox span { + border: 1px solid darkgray; + background: lightgray; + margin: 0px 5px 0px; + padding: 5px 10px 5px; + cursor: pointer; +} + +#northarrow { + position: absolute; + left: 12px; + bottom: 16px; + width: 80px; + height: 80px; + z-index: 1000; +} diff --git a/docs/examples/24/qgis2threejs.js b/docs/examples/24/qgis2threejs.js new file mode 100644 index 00000000..1f721f5f --- /dev/null +++ b/docs/examples/24/qgis2threejs.js @@ -0,0 +1,3290 @@ +"use strict"; +// Qgis2threejs.js +// (C) 2014 Minoru Akagi | MIT License +// https://github.com/minorua/Qgis2threejs + +var Q3D = {VERSION: "2.4"}; + +Q3D.Config = { + // scene + autoZShift: false, // automatic z shift adjustment + bgColor: null, // null is sky + // camera + orthoCamera: false, + viewpoint: { // note: y-up + pos: {x: 0, y: 100, z: 100}, // initial camera position + lookAt: {x: 0, y: 0, z:0} + }, + // light + lights: [ + { + type: "ambient", + color: 0x999999, + intensity: 0.8 + }, + { + type: "directional", + color: 0xffffff, + intensity: 0.7, + azimuth: 220, // note: default light azimuth of gdaldem hillshade is 315. + altitude: 45 // altitude angle + }, + { + type: "directional", + color: 0xffffff, + intensity: 0.1, + azimuth: 40, + altitude: -45 + } + ], + // layer + dem: { + side: { + bottomZ: -1.5 // in the unit of world coordinates + }, + frame: { + bottomZ: -1.5 + } + }, + line: { + dash: { + dashSize: 1, + gapSize: 0.5 + } + }, + label: { + visible: true, + connectorColor: 0xc0c0d0, + fixedSize: false, + minFontSize: 8, + queryable: true + }, + // decoration + northArrow: { + color: 0x8b4513, + cameraDistance: 30, + visible: false + }, + + qmarker: { + r: 0.25, + c: 0xffff00, + o: 0.8 + }, + allVisible: false, // set every layer visible property to true on load if set to true + debugMode: false, + exportMode: false // set to true in glTF export mode +}; + +// consts +Q3D.LayerType = { + DEM: "dem", + Point: "point", + Line: "line", + Polygon: "polygon" +}; + +Q3D.MaterialType = { + MeshLambert: 0, + MeshPhong: 1, + MeshToon: 2, + LineBasic: 3, + LineDashed: 4, + Sprite: 5, + Point: 6, + Unknown: -1 +}; + +Q3D.uv = { + i: new THREE.Vector3(1, 0, 0), + j: new THREE.Vector3(0, 1, 0), + k: new THREE.Vector3(0, 0, 1) +}; + +Q3D.ua = window.navigator.userAgent.toLowerCase(); +Q3D.isIE = (Q3D.ua.indexOf("msie") != -1 || Q3D.ua.indexOf("trident") != -1); +Q3D.isTouchDevice = ("ontouchstart" in window); + +Q3D.$ = function (elementId) { + return document.getElementById(elementId); +}; + +/* +Q3D.Group -> THREE.Group -> THREE.Object3D +*/ +Q3D.Group = function () { + THREE.Group.call(this); +}; + +Q3D.Group.prototype = Object.create(THREE.Group.prototype); +Q3D.Group.prototype.constructor = Q3D.Group; + +Q3D.Group.prototype.add = function (object) { + THREE.Group.prototype.add.call(this, object); + object.updateMatrixWorld(); +}; + +Q3D.Group.prototype.clear = function () { + for (var i = this.children.length - 1 ; i >= 0; i--) { + this.remove(this.children[i]); + } +}; + + +/* +Q3D.Scene -> THREE.Scene -> THREE.Object3D + +.mapLayers: an object that holds map layers contained in this scene. the key is layerId. + use .loadJSONObject() to add a map layer to this scene. +.userData: an object that holds metadata (crs, proj, baseExtent, rotation, width, zExaggeration, zShift, wgs84Center) + properties of the scene object in JSON data? + +.add(object): +.getObjectByName(layerId): returns the layer object specified by the layer id. + +-- +custom function +.loadJSONObject(json_obj): +.toMapCoordinates(x, y, z): converts world coordinates to map coordinates +._rotatePoint(point, degrees, origin): +*/ +Q3D.Scene = function () { + THREE.Scene.call(this); + this.autoUpdate = false; + + // scene is z-up + this.rotation.x = -Math.PI / 2; + this.updateMatrixWorld(); + + this.mapLayers = {}; + + this.lightGroup = new Q3D.Group(); + this.add(this.lightGroup); + + this.labelConnectorGroup = new Q3D.Group(); + this.add(this.labelConnectorGroup); + + this.labelRootElement = null; +}; + +Q3D.Scene.prototype = Object.create(THREE.Scene.prototype); +Q3D.Scene.prototype.constructor = Q3D.Scene; + +Q3D.Scene.prototype.add = function (object) { + THREE.Scene.prototype.add.call(this, object); + object.updateMatrixWorld(); +}; + +Q3D.Scene.prototype.loadJSONObject = function (jsonObject) { + if (jsonObject.type == "scene") { + // set properties + if (jsonObject.properties !== undefined) { + this.userData = jsonObject.properties; + + var w = (this.userData.baseExtent[2] - this.userData.baseExtent[0]), + h = (this.userData.baseExtent[3] - this.userData.baseExtent[1]); + + this.userData.scale = this.userData.width / w; + this.userData.zScale = this.userData.scale * this.userData.zExaggeration; + + this.userData.origin = {x: this.userData.baseExtent[0] + w / 2, + y: this.userData.baseExtent[1] + h / 2, + z: -this.userData.zShift}; + } + + // load lights + if (jsonObject.lights !== undefined) { + // remove all existing lights + this.lightGroup.clear(); + + // build lights if scene data has lights settings + // [not implemented yet] + } + + // build default lights if this scene has no lights yet + if (this.lightGroup.children.length == 0) this.buildDefaultLights(); + + // load layers + if (jsonObject.layers !== undefined) { + jsonObject.layers.forEach(function (layer) { + this.loadJSONObject(layer); + }, this); + } + } + else if (jsonObject.type == "layer") { + var layer = this.mapLayers[jsonObject.id]; + if (layer === undefined) { + // console.assert(jsonObject.properties !== undefined); + + // create a layer + var type = jsonObject.properties.type; + if (type == "dem") layer = new Q3D.DEMLayer(); + else if (type == "point") layer = new Q3D.PointLayer(); + else if (type == "line") layer = new Q3D.LineLayer(); + else if (type == "polygon") layer = new Q3D.PolygonLayer(); + else { + // console.error("unknown layer type:" + type); + return; + } + layer.id = jsonObject.id; + layer.addEventListener("renderRequest", this.requestRender.bind(this)); + + this.mapLayers[jsonObject.id] = layer; + this.add(layer.objectGroup); + } + + layer.loadJSONObject(jsonObject, this); + + this.requestRender(); + } + else if (jsonObject.type == "block") { + var layer = this.mapLayers[jsonObject.layer]; + if (layer === undefined) { + // console.error("layer not exists:" + jsonObject.layer); + return; + } + layer.loadJSONObject(jsonObject, this); + + this.requestRender(); + } +}; + +Q3D.Scene.prototype.buildLights = function (lights) { + var p, light, lambda, phi, x, y, z; + var deg2rad = Math.PI / 180; + for (var i = 0; i < lights.length; i++) { + p = lights[i]; + if (p.type == "ambient") { + this.lightGroup.add(new THREE.AmbientLight(p.color, p.intensity)); + } + else if (p.type == "directional") { + lambda = (90 - p.azimuth) * deg2rad; + phi = p.altitude * deg2rad; + + x = Math.cos(phi) * Math.cos(lambda); + y = Math.cos(phi) * Math.sin(lambda); + z = Math.sin(phi); + + light = new THREE.DirectionalLight(p.color, p.intensity); + light.position.set(x, y, z); + this.lightGroup.add(light); + } + } +}; + +Q3D.Scene.prototype.buildDefaultLights = function () { + this.buildLights(Q3D.Config.lights); +}; + +Q3D.Scene.prototype.requestRender = function () { + this.dispatchEvent({type: "renderRequest"}); +}; + +Q3D.Scene.prototype.queryableObjects = function () { + var objs = []; + for (var id in this.mapLayers) { + objs = objs.concat(this.mapLayers[id].queryableObjects()); + } + return objs; +}; + +Q3D.Scene.prototype.toMapCoordinates = function (x, y, z) { + if (this.userData.rotation) { + var pt = this._rotatePoint({x: x, y: y}, this.userData.rotation); + x = pt.x; + y = pt.y; + } + return {x: x / this.userData.scale + this.userData.origin.x, + y: y / this.userData.scale + this.userData.origin.y, + z: z / this.userData.zScale + this.userData.origin.z}; +}; + +// real (geodetic/projected) coordinates to 3D scene coordinates +Q3D.Scene.prototype.toLocalCoordinates = function (x, y, z, isProjected) { + // project x and y coordinates from WGS84 (long, lat) + var pt; + if (!isProjected && typeof proj4 !== "undefined") { + pt = proj4(this.userData.proj).forward([x, y]); + x = pt[0]; + y = pt[1]; + } + + x = (x - this.userData.origin.x) * this.userData.scale; + y = (y - this.userData.origin.y) * this.userData.scale; + z = (z - this.userData.origin.z) * this.userData.zScale; + + if (this.userData.rotation) { + pt = this._rotatePoint({x: x, y: y}, -this.userData.rotation); + x = pt.x; + y = pt.y; + } + return {x: x, y: y, z: z}; +}; + +// Rotate a point counter-clockwise around an origin +Q3D.Scene.prototype._rotatePoint = function (point, degrees, origin) { + var theta = degrees * Math.PI / 180, + c = Math.cos(theta), + s = Math.sin(theta), + x = point.x, + y = point.y; + + if (origin) { + x -= origin.x; + y -= origin.y; + } + + var xd = x * c - y * s, + yd = x * s + y * c; + + if (origin) { + xd += origin.x; + yd += origin.y; + } + return {x: xd, y: yd}; +}; + +Q3D.Scene.prototype.adjustZShift = function () { + // initialize + this.userData.zShiftA = 0; + this.position.y = 0; + this.updateMatrixWorld(); + + var box = new THREE.Box3(); + for (var id in this.mapLayers) { + if (this.mapLayers[id].visible) { + box.union(this.mapLayers[id].boundingBox()); + } + } + + // bbox zmin in map coordinates + var zmin = (box.min.y === Infinity) ? 0 : (box.min.y / this.userData.zScale - this.userData.zShift); + + // shift scene so that bbox zmin becomes zero + this.userData.zShiftA = -zmin; + this.position.y = this.userData.zShiftA * this.userData.zScale; + + // keep positions of lights in world coordinates + this.lightGroup.position.z = -this.position.y; + + this.updateMatrixWorld(); + + this.userData.origin.z = -(this.userData.zShift + this.userData.zShiftA); + + console.log("z shift adjusted: " + this.userData.zShiftA); + + this.dispatchEvent({type: "zShiftAdjusted", sceneData: this.userData}); + + this.requestRender(); +}; + + +/* +Q3D.application + +limitations: +- one renderer +- one scene +*/ +(function () { + // the application + var app = {}; + Q3D.application = app; + + var vec3 = new THREE.Vector3(); + + var listeners = {}; + var dispatchEvent = function (event) { + if (Q3D.Config.debugMode) console.log("about to dispatch " + event + " event."); + + var ls = listeners[event.type] || []; + for (var i = 0; i < ls.length; i++) { + ls[i](event); + } + }; + + app.addEventListener = function (type, listener, prepend) { + listeners[type] = listeners[type] || []; + if (prepend) { + listeners[type].unshift(listener); + } + else { + listeners[type].push(listener); + } + }; + + app.init = function (container) { + app.container = container; + app.running = false; // if true, animation loop is continued. + + // URL parameters + app.urlParams = app.parseUrlParameters(); + if ("popup" in app.urlParams) { + // open popup window + var c = window.location.href.split("?"); + window.open(c[0] + "?" + c[1].replace(/&?popup/, ""), "popup", "width=" + app.urlParams.width + ",height=" + app.urlParams.height); + app.popup.show("Another window has been opened."); + return; + } + + if (app.urlParams.width && app.urlParams.height) { + // set container size + container.style.width = app.urlParams.width + "px"; + container.style.height = app.urlParams.height + "px"; + } + + app.width = container.clientWidth; + app.height = container.clientHeight; + + var bgcolor = Q3D.Config.bgColor; + if (bgcolor === null) container.classList.add("sky"); + + // WebGLRenderer + app.renderer = new THREE.WebGLRenderer({alpha: true, antialias: true}); + app.renderer.setSize(app.width, app.height); + app.renderer.setClearColor(bgcolor || 0, (bgcolor === null) ? 0 : 1); + app.container.appendChild(app.renderer.domElement); + + // set viewpoint if specified by URL parameters + var vars = app.urlParams; + if (vars.cx !== undefined) Q3D.Config.viewpoint.pos = {x: parseFloat(vars.cx), y: parseFloat(vars.cy), z: parseFloat(vars.cz)}; + if (vars.tx !== undefined) Q3D.Config.viewpoint.lookAt = {x: parseFloat(vars.tx), y: parseFloat(vars.ty), z: parseFloat(vars.tz)}; + + // camera + app.buildCamera(Q3D.Config.orthoCamera); + + // scene + app.scene = new Q3D.Scene(); + app.scene.addEventListener("renderRequest", function (event) { + app.render(); + }); + + var controls; + if (typeof THREE.OrbitControls !== "undefined") { + controls = new THREE.OrbitControls(app.camera, app.renderer.domElement); + controls.enableKeys = false; + + var t = Q3D.Config.viewpoint.lookAt; + controls.target.set(t.x, t.y, t.z); + + // custom functions + var offset = new THREE.Vector3(); + var spherical = new THREE.Spherical(); + + controls.moveForward = function (delta) { + offset.copy(controls.object.position).sub(controls.target); + var targetDistance = offset.length() * Math.tan((controls.object.fov / 2) * Math.PI / 180.0); + offset.y = 0; + offset.normalize(); + offset.multiplyScalar(-2 * delta * targetDistance / app.renderer.domElement.clientHeight); + + controls.object.position.add(offset); + controls.target.add(offset); + }; + controls.cameraRotate = function (thetaDelta, phiDelta) { + offset.copy(controls.target).sub(controls.object.position); + spherical.setFromVector3(offset); + + spherical.theta += thetaDelta; + spherical.phi -= phiDelta; + + // restrict theta/phi to be between desired limits + spherical.theta = Math.max(controls.minAzimuthAngle, Math.min(controls.maxAzimuthAngle, spherical.theta)); + spherical.phi = Math.max(controls.minPolarAngle, Math.min(controls.maxPolarAngle, spherical.phi)); + spherical.makeSafe(); + + offset.setFromSpherical(spherical); + controls.target.copy(controls.object.position).add(offset); + controls.object.lookAt(controls.target); + }; + + controls.addEventListener("change", function (event) { + app.render(); + }); + } + + app.controls = controls; + app.controls.update(); + + app.labelVisible = Q3D.Config.label.visible; + + // root element of labels + app.scene.labelRootElement = document.getElementById("labels"); + app.scene.labelRootElement.style.display = (app.labelVisible) ? "block" : "none"; + + // create a marker for queried point + var opt = Q3D.Config.qmarker; + app.queryMarker = new THREE.Mesh(new THREE.SphereBufferGeometry(opt.r), + new THREE.MeshLambertMaterial({color: opt.c, opacity: opt.o, transparent: (opt.o < 1)})); + + app.highlightMaterial = new THREE.MeshLambertMaterial({emissive: 0x999900, transparent: true, opacity: 0.5}); + if (!Q3D.isIE) app.highlightMaterial.side = THREE.DoubleSide; // Shader compilation error occurs with double sided material on IE11 + + app.selectedObject = null; + app.highlightObject = null; + + app.modelBuilders = []; + app._wireframeMode = false; + + // add event listeners + app.addEventListener("sceneLoaded", function () { + if (Q3D.Config.autoZShift) { + app.scene.adjustZShift(); + } + app.render(); + }, true); + + window.addEventListener("keydown", app.eventListener.keydown); + window.addEventListener("resize", app.eventListener.resize); + + app.renderer.domElement.addEventListener("mousedown", app.eventListener.mousedown); + app.renderer.domElement.addEventListener("mouseup", app.eventListener.mouseup); + + var e = Q3D.$("closebtn"); + if (e) e.addEventListener("click", app.closePopup); + }; + + app.parseUrlParameters = function () { + var p, vars = {}; + var params = window.location.search.substring(1).split('&').concat(window.location.hash.substring(1).split('&')); + params.forEach(function (param) { + p = param.split('='); + vars[p[0]] = p[1]; + }); + return vars; + }; + + app.initLoadingManager = function () { + if (app.loadingManager) { + app.loadingManager.onLoad = app.loadingManager.onProgress = app.loadingManager.onError = undefined; + } + + app.loadingManager = new THREE.LoadingManager(function () { + // onLoad + app.loadingManager.isLoading = false; + + document.getElementById("bar").classList.add("fadeout"); + + dispatchEvent({type: "sceneLoaded"}); + }, + function (url, loaded, total) { + // onProgress + document.getElementById("bar").style.width = (loaded / total * 100) + "%"; + }, + function () { + app.loadingManager.isLoading = false; + + dispatchEvent({type: "sceneLoadError"}); + }); + + app.loadingManager.onStart = function () { + app.loadingManager.isLoading = true; + }; + + app.loadingManager.isLoading = false; + }; + + app.initLoadingManager(); + + app.loadFile = function (url, type, callback) { + + var loader = new THREE.FileLoader(app.loadingManager); + loader.setResponseType(type); + + var onError = function (e) { + if (location.protocol == "file:") { + app.popup.show("This browser doesn't allow loading local files via Ajax. See plugin wiki page for details.", "Error", true); + } + }; + + try { + loader.load(url, callback, undefined, onError); + } + catch (e) { // for IE + onError(e); + } + }; + + app.loadJSONObject = function (jsonObject) { + app.scene.loadJSONObject(jsonObject); + }; + + app.loadJSONFile = function (url, callback) { + app.loadFile(url, "json", function (obj) { + app.loadJSONObject(obj); + if (callback) callback(obj); + }); + }; + + app.loadSceneFile = function (url, callback) { + var ext = url.split(".").pop(); + if (ext == "json") app.loadJSONFile(url, callback); + else if (ext == "js") { + var e = document.createElement("script"); + e.src = url; + e.onload = callback; + document.body.appendChild(e); + } + }; + + app.loadTextureFile = function (url, callback) { + return new THREE.TextureLoader(app.loadingManager).load(url, callback); + }; + + app.loadModelFile = function (url, callback) { + var loader, + ext = url.split(".").pop(); + if (ext == "dae") { + loader = new THREE.ColladaLoader(app.loadingManager); + } + else if (ext == "gltf" || ext == "glb") { + loader = new THREE.GLTFLoader(app.loadingManager); + } + else { + console.log("Model file type not supported: " + url); + return; + } + + app.loadingManager.itemStart("M" + url); + + loader.load(url, function (model) { + if (callback) callback(model); + app.loadingManager.itemEnd("M" + url); + }, + undefined, + function (e) { + console.log("Failed to load model: " + url); + app.loadingManager.itemError("M" + url); + }); + }; + + app.mouseDownPoint = new THREE.Vector2(); + app.mouseUpPoint = new THREE.Vector2(); + + app.eventListener = { + + keydown: function (e) { + var controls = app.controls; + var panDelta = 3, rotateAngle = 2 * Math.PI / 180; + if (e.shiftKey && e.ctrlKey) { + switch (e.keyCode) { + case 38: // Shift + Ctrl + UP + controls.dollyOut(controls.getZoomScale()); + break; + case 40: // Shift + Ctrl + DOWN + controls.dollyIn(controls.getZoomScale()); + break; + default: + return; + } + } + else if (e.shiftKey) { + switch (e.keyCode) { + case 37: // LEFT + controls.rotateLeft(rotateAngle); + break; + case 38: // UP + controls.rotateUp(rotateAngle); + break; + case 39: // RIGHT + controls.rotateLeft(-rotateAngle); + break; + case 40: // DOWN + controls.rotateUp(-rotateAngle); + break; + case 82: // Shift + R + controls.reset(); + break; + case 83: // Shift + S + app.showPrintDialog(); + return; + default: + return; + } + } + else if (e.ctrlKey) { + switch (e.keyCode) { + case 37: // Ctrl + LEFT + controls.cameraRotate(rotateAngle, 0); + break; + case 38: // Ctrl + UP + controls.cameraRotate(0, rotateAngle); + break; + case 39: // Ctrl + RIGHT + controls.cameraRotate(-rotateAngle, 0); + break; + case 40: // Ctrl + DOWN + controls.cameraRotate(0, -rotateAngle); + break; + default: + return; + } + } + else { + switch (e.keyCode) { + case 37: // LEFT + controls.panLeft(panDelta, controls.object.matrix); + break; + case 38: // UP + controls.moveForward(3 * panDelta); // horizontally forward + break; + case 39: // RIGHT + controls.panLeft(-panDelta, controls.object.matrix); + break; + case 40: // DOWN + controls.moveForward(-3 * panDelta); + break; + case 27: // ESC + if (Q3D.$("popup").style.display != "none") { + app.closePopup(); + } + else if (app.controls.autoRotate) { + app.setRotateAnimationMode(false); + } + return; + case 73: // I + app.showInfo(); + return; + case 76: // L + app.setLabelVisible(!app.labelVisible); + return; + case 82: // R + app.setRotateAnimationMode(!controls.autoRotate); + return; + case 87: // W + app.setWireframeMode(!app._wireframeMode); + return; + default: + return; + } + } + app.controls.update(); + }, + + mousedown: function (e) { + app.mouseDownPoint.set(e.clientX, e.clientY); + }, + + mouseup: function (e) { + app.mouseUpPoint.set(e.clientX, e.clientY); + if (app.mouseDownPoint.equals(app.mouseUpPoint)) app.canvasClicked(e); + }, + + resize: function () { + app.setCanvasSize(app.container.clientWidth, app.container.clientHeight); + app.render(); + } + + }; + + app.setCanvasSize = function (width, height) { + app.width = width; + app.height = height; + app.camera.aspect = width / height; + app.camera.updateProjectionMatrix(); + app.renderer.setSize(width, height); + }; + + app.buildCamera = function (is_ortho) { + if (is_ortho) { + app.camera = new THREE.OrthographicCamera(-app.width / 10, app.width / 10, app.height / 10, -app.height / 10, 0.1, 10000); + } + else { + app.camera = new THREE.PerspectiveCamera(45, app.width / app.height, 0.1, 10000); + } + + var v = Q3D.Config.viewpoint, + p = v.pos, + t = v.lookAt; + app.camera.position.set(p.x, p.y, p.z); + app.camera.lookAt(t.x, t.y, t.z); + }; + + // rotation: direction to North (clockwise from up (+y), in degrees) + app.buildNorthArrow = function (container, rotation) { + app.renderer2 = new THREE.WebGLRenderer({alpha: true, antialias: true}); + app.renderer2.setClearColor(0, 0); + app.renderer2.setSize(container.clientWidth, container.clientHeight); + + app.container2 = container; + app.container2.appendChild(app.renderer2.domElement); + + app.camera2 = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 1, 1000); + app.camera2.up = app.camera.up; + + app.scene2 = new Q3D.Scene(); + app.scene2.buildDefaultLights(); + + // an arrow object + var geometry = new THREE.Geometry(); + geometry.vertices.push( + new THREE.Vector3(-5, -10, 0), + new THREE.Vector3(0, 10, 0), + new THREE.Vector3(0, -7, 3), + new THREE.Vector3(5, -10, 0) + ); + geometry.faces.push( + new THREE.Face3(0, 1, 2), + new THREE.Face3(2, 1, 3) + ); + geometry.computeFaceNormals(); + + var material = new THREE.MeshLambertMaterial({color: Q3D.Config.northArrow.color, side: THREE.DoubleSide}); + var mesh = new THREE.Mesh(geometry, material); + if (rotation) mesh.rotation.z = -rotation * Math.PI / 180; + app.scene2.add(mesh); + }; + + app.currentViewUrl = function () { + var c = app.camera.position, t = app.controls.target, u = app.camera.up; + var hash = "#cx=" + c.x + "&cy=" + c.y + "&cz=" + c.z; + if (t.x || t.y || t.z) hash += "&tx=" + t.x + "&ty=" + t.y + "&tz=" + t.z; + return window.location.href.split("#")[0] + hash; + }; + + // enable the controls + app.start = function () { + if (app.controls) app.controls.enabled = true; + }; + + app.pause = function () { + app.running = false; + if (app.controls) app.controls.enabled = false; + }; + + app.resume = function () { + if (app.controls) app.controls.enabled = true; + }; + + app.startAnimation = function () { + app.running = true; + app.animate(); + }; + + app.stopAnimation = function () { + app.running = false; + }; + + // animation loop + app.animate = function () { + if (app.running) requestAnimationFrame(app.animate); + app.render(true); + }; + + app.render = function (updateControls) { + if (updateControls) app.controls.update(); + app.renderer.render(app.scene, app.camera); + + // North arrow + if (app.renderer2) { + app.camera.getWorldDirection(vec3); + app.camera2.position.copy(vec3.negate().setLength(Q3D.Config.northArrow.cameraDistance)); + app.camera2.quaternion.copy(app.camera.quaternion); + + app.renderer2.render(app.scene2, app.camera2); + } + + // labels + app.updateLabelPosition(); + }; + + // TODO: remove [obsolete] app.setIntervalRender + (function () { + var _delay, _repeat, _times, _id = null; + var func = function () { + app.render(); + if (_repeat <= ++_times) { + clearInterval(_id); + _id = null; + } + }; + app.setIntervalRender = function (delay, repeat) { + if (_id === null || _delay != delay) { + if (_id !== null) { + clearInterval(_id); + } + _id = setInterval(func, delay); + _delay = delay; + } + _repeat = repeat; + _times = 0; + }; + })(); + + // app.updateLabelPosition() + (function () { + var camera, + c2t = new THREE.Vector3(), + c2l = new THREE.Vector3(); + + app.updateLabelPosition = function () { + var rootGroup = app.scene.labelConnectorGroup; + if (!app.labelVisible || rootGroup.children.length == 0) return; + + camera = app.camera; + camera.getWorldDirection(c2t); + + // make list of [connector object, pt, distance to camera] + var obj_dist = [], + i, l, k, m, + connGroup, conn, pt0; + + for (i = 0, l = rootGroup.children.length; i < l; i++) { + connGroup = rootGroup.children[i]; + if (!connGroup.visible) continue; + for (k = 0, m = connGroup.children.length; k < m; k++) { + conn = connGroup.children[k]; + pt0 = conn.geometry.vertices[0]; + vec3.set(pt0.x, pt0.z, -pt0.y); + + if (c2l.subVectors(vec3, camera.position).dot(c2t) > 0) // label is in front + obj_dist.push([conn, pt0, camera.position.distanceTo(vec3)]); + else // label is in back + conn.userData.elem.style.display = "none"; + } + } + + if (obj_dist.length == 0) return; + + // sort label objects in descending order of distances + obj_dist.sort(function (a, b) { + if (a[2] < b[2]) return 1; + if (a[2] > b[2]) return -1; + return 0; + }); + + var widthHalf = app.width / 2, + heightHalf = app.height / 2, + fixedSize = Q3D.Config.label.fixedSize, + minFontSize = Q3D.Config.label.minFontSize; + + var label, dist, x, y, e, t, fontSize; + for (i = 0, l = obj_dist.length; i < l; i++) { + label = obj_dist[i][0]; + pt0 = obj_dist[i][1]; + dist = obj_dist[i][2]; + + // calculate label position + vec3.set(pt0.x, pt0.z, -pt0.y).project(camera); + x = (vec3.x * widthHalf) + widthHalf; + y = -(vec3.y * heightHalf) + heightHalf; + + // set label position + e = label.userData.elem; + t = "translate(" + (x - (e.offsetWidth / 2)) + "px," + (y - (e.offsetHeight / 2)) + "px)"; + e.style.display = "block"; + e.style.zIndex = i + 1; + e.style.webkitTransform = t; + e.style.transform = t; + + // set font size + if (!fixedSize) { + if (dist < 10) dist = 10; + fontSize = Math.max(Math.round(1000 / dist), minFontSize); + e.style.fontSize = fontSize + "px"; + } + } + }; + })(); + + app.setLabelVisible = function (visible) { + app.labelVisible = visible; + app.scene.labelRootElement.style.display = (visible) ? "block" : "none"; + app.scene.labelConnectorGroup.visible = visible; + app.render(); + }; + + app.setRotateAnimationMode = function (enabled) { + app.controls.autoRotate = enabled; + if (enabled) { + app.startAnimation(); + } + else { + app.stopAnimation(); + } + }; + + app.setWireframeMode = function (wireframe) { + if (wireframe == app._wireframeMode) return; + + for (var id in app.scene.mapLayers) { + app.scene.mapLayers[id].setWireframeMode(wireframe); + } + + app._wireframeMode = wireframe; + app.render(); + }; + + app.intersectObjects = function (offsetX, offsetY) { + var vec2 = new THREE.Vector2((offsetX / app.width) * 2 - 1, + -(offsetY / app.height) * 2 + 1); + var ray = new THREE.Raycaster(); + ray.linePrecision = 0.2; + ray.setFromCamera(vec2, app.camera); + return ray.intersectObjects(app.scene.queryableObjects()); + }; + + app._offset = function (elm) { + var top = 0, left = 0; + do { + top += elm.offsetTop || 0; left += elm.offsetLeft || 0; elm = elm.offsetParent; + } while (elm); + return {top: top, left: left}; + }; + + app.popup = { + + timerId: null, + + modal: false, + + // show box + // obj: html, element or content id ("queryresult" or "pageinfo") + // modal: boolean + // duration: int [milliseconds] + show: function (obj, title, modal, duration) { + + if (modal) app.pause(); + else if (this.modal) app.resume(); + + this.modal = Boolean(modal); + + var content = Q3D.$("popupcontent"); + [content, Q3D.$("queryresult"), Q3D.$("pageinfo")].forEach(function (e) { + if (e) e.style.display = "none"; + }); + + if (obj == "queryresult" || obj == "pageinfo") { + Q3D.$(obj).style.display = "block"; + } + else { + if (obj instanceof HTMLElement) { + content.innerHTML = ""; + content.appendChild(obj); + } + else { + content.innerHTML = obj; + } + content.style.display = "block"; + } + Q3D.$("popupbar").innerHTML = title || ""; + Q3D.$("popup").style.display = "block"; + + if (app.popup.timerId !== null) { + clearTimeout(app.popup.timerId); + app.popup.timerId = null; + } + + if (duration) { + app.popup.timerId = setTimeout(function () { + app.popup.hide(); + }, duration); + } + }, + + hide: function () { + Q3D.$("popup").style.display = "none"; + if (app.popup.timerId !== null) clearTimeout(app.popup.timerId); + app.popup.timerId = null; + if (this.modal) app.resume(); + } + + }; + + app.showInfo = function () { + var url = Q3D.$("urlbox"); + if (url) url.value = app.currentViewUrl(); + app.popup.show("pageinfo"); + }; + + app.queryTargetPosition = new THREE.Vector3(); // y-up + + app.cameraAction = { + + move: function (x, y, z) { // z-up + if (x === undefined) app.camera.position.copy(app.queryTargetPosition); + else app.camera.position.set(x, z, -y); // y-up + app.render(true); + }, + + vecZoom: new THREE.Vector3(0, 10, 10), // y-up + + zoomIn: function (x, y, z) { // z-up + if (x === undefined) vec3.copy(app.queryTargetPosition); + else vec3.set(x, z, -y); // y-up + + app.camera.position.addVectors(vec3, app.cameraAction.vecZoom); + app.camera.lookAt(vec3.x, vec3.y, vec3.z); + if (app.controls.target !== undefined) app.controls.target.copy(vec3); + app.render(true); + }, + + orbit: function (x, y, z) { // z-up + if (app.controls.target === undefined) return; + + if (x === undefined) app.controls.target.copy(app.queryTargetPosition); + else app.controls.target.set(x, z, -y); // y-up + app.setRotateAnimationMode(true); + } + + }; + + app.showQueryResult = function (point, obj, hide_coords) { + app.queryTargetPosition.set(point.x, point.z, -point.y); // y-up + + var layer = app.scene.mapLayers[obj.userData.layerId], + e = document.getElementById("qr_layername"); + + // layer name + if (layer && e) e.innerHTML = layer.properties.name; + + // clicked coordinates + e = document.getElementById("qr_coords_table"); + if (e) { + if (hide_coords) { + e.classList.add("hidden"); + } + else { + e.classList.remove("hidden"); + + var pt = app.scene.toMapCoordinates(point.x, point.y, point.z); + e = document.getElementById("qr_coords"); + if (typeof proj4 === "undefined") { + e.innerHTML = [pt.x.toFixed(2), pt.y.toFixed(2), pt.z.toFixed(2)].join(", "); + } + else { + var lonLat = proj4(app.scene.userData.proj).inverse([pt.x, pt.y]); + e.innerHTML = Q3D.Utils.convertToDMS(lonLat[1], lonLat[0]) + ", Elev. " + pt.z.toFixed(2); + } + } + } + + e = document.getElementById("qr_attrs_table"); + if (e) { + for (var i = e.children.length - 1; i >= 0; i--) { + if (e.children[i].tagName.toUpperCase() == "TR") e.removeChild(e.children[i]); + } + + if (layer && layer.properties.propertyNames !== undefined) { + var row; + for (var i = 0, l = layer.properties.propertyNames.length; i < l; i++) { + row = document.createElement("tr"); + row.innerHTML = "" + layer.properties.propertyNames[i] + "" + + "" + obj.userData.properties[i] + ""; + e.appendChild(row); + } + e.classList.remove("hidden"); + } + else { + e.classList.add("hidden"); + } + } + app.popup.show("queryresult"); + }; + + app.showPrintDialog = function () { + + function e(tagName, parent, innerHTML) { + var elem = document.createElement(tagName); + if (parent) parent.appendChild(elem); + if (innerHTML) elem.innerHTML = innerHTML; + return elem; + } + + var f = e("form"); + f.className = "print"; + + var d1 = e("div", f, "Image Size"); + d1.style.textDecoration = "underline"; + + var d2 = e("div", f), + l1 = e("label", d2, "Width:"), + width = e("input", d2); + d2.style.cssFloat = "left"; + l1.htmlFor = width.id = width.name = "printwidth"; + width.type = "text"; + width.value = app.width; + e("span", d2, "px,"); + + var d3 = e("div", f), + l2 = e("label", d3, "Height:"), + height = e("input", d3); + l2.htmlFor = height.id = height.name = "printheight"; + height.type = "text"; + height.value = app.height; + e("span", d3, "px"); + + var d4 = e("div", f), + ka = e("input", d4); + ka.type = "checkbox"; + ka.checked = true; + e("span", d4, "Keep Aspect Ratio"); + + var d5 = e("div", f, "Option"); + d5.style.textDecoration = "underline"; + + var d6 = e("div", f), + bg = e("input", d6); + bg.type = "checkbox"; + bg.checked = true; + e("span", d6, "Fill Background"); + + var d7 = e("div", f), + ok = e("span", d7, "OK"), + cancel = e("span", d7, "Cancel"); + d7.className = "buttonbox"; + + e("input", f).type = "submit"; + + // event handlers + // width and height boxes + var aspect = app.width / app.height; + + width.oninput = function () { + if (ka.checked) height.value = Math.round(width.value / aspect); + }; + + height.oninput = function () { + if (ka.checked) width.value = Math.round(height.value * aspect); + }; + + ok.onclick = function () { + app.popup.show("Rendering..."); + window.setTimeout(function () { + app.saveCanvasImage(width.value, height.value, bg.checked); + }, 10); + }; + + cancel.onclick = app.closePopup; + + // enter key pressed + f.onsubmit = function () { + ok.onclick(); + return false; + }; + + app.popup.show(f, "Save Image", true); // modal + }; + + app.closePopup = function () { + app.popup.hide(); + app.scene.remove(app.queryMarker); + app.highlightFeature(null); + app.render(); + if (app._canvasImageUrl) { + URL.revokeObjectURL(app._canvasImageUrl); + app._canvasImageUrl = null; + } + }; + + app.highlightFeature = function (object) { + if (app.highlightObject) { + // remove highlight object from the scene + app.scene.remove(app.highlightObject); + app.selectedObject = null; + app.highlightObject = null; + } + + if (object === null) return; + + var layer = app.scene.mapLayers[object.userData.layerId]; + if (layer === undefined || layer.type == Q3D.LayerType.DEM) return; + if (["Icon", "JSON model", "COLLADA model"].indexOf(layer.objType) != -1) return; + + // create a highlight object (if layer type is Point, slightly bigger than the object) + // var highlightObject = new Q3D.Group(); + var s = (layer.type == Q3D.LayerType.Point) ? 1.01 : 1; + + var clone = object.clone(); + clone.traverse(function (obj) { + obj.material = app.highlightMaterial; + }); + if (s != 1) clone.scale.set(clone.scale.x * s, clone.scale.y * s, clone.scale.z * s); + // highlightObject.add(clone); + + // add the highlight object to the scene + app.scene.add(clone); + + app.selectedObject = object; + app.highlightObject = clone; + }; + + app.canvasClicked = function (e) { + var canvasOffset = app._offset(app.renderer.domElement); + var objs = app.intersectObjects(e.clientX - canvasOffset.left, e.clientY - canvasOffset.top); + var obj, pt; + + for (var i = 0, l = objs.length; i < l; i++) { + obj = objs[i]; + + // query marker + pt = {x: obj.point.x, y: -obj.point.z, z: obj.point.y}; // obj's coordinate system is y-up + app.queryMarker.position.set(pt.x, pt.y, pt.z); // this is z-up + app.scene.add(app.queryMarker); + + // get layerId of clicked object + var layerId, object = obj.object; + while (object) { + layerId = object.userData.layerId; + if (layerId !== undefined) break; + object = object.parent; + } + + app.highlightFeature(object); + app.render(); + app.showQueryResult(pt, object); + + return; + } + app.closePopup(); + }; + + app.saveCanvasImage = function (width, height, fill_background, saveImageFunc) { + if (fill_background === undefined) fill_background = true; + + // set canvas size + var old_size; + if (width && height) { + old_size = [app.width, app.height]; + app.setCanvasSize(width, height); + } + + // functions + var saveBlob = function (blob) { + var filename = "image.png"; + + // ie + if (window.navigator.msSaveBlob !== undefined) { + window.navigator.msSaveBlob(blob, filename); + app.popup.hide(); + } + else { + // create object url + if (app._canvasImageUrl) URL.revokeObjectURL(app._canvasImageUrl); + app._canvasImageUrl = URL.createObjectURL(blob); + + // display a link to save the image + var e = document.createElement("a"); + e.className = "download-link"; + e.href = app._canvasImageUrl; + e.download = filename; + e.innerHTML = "Save"; + app.popup.show("Click to save the image to a file." + e.outerHTML, "Image is ready"); + } + }; + + var saveCanvasImage = saveImageFunc || function (canvas) { + if (canvas.toBlob !== undefined) { + canvas.toBlob(saveBlob); + } + else { // !HTMLCanvasElement.prototype.toBlob + // https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement.toBlob + var binStr = atob(canvas.toDataURL("image/png").split(',')[1]), + len = binStr.length, + arr = new Uint8Array(len); + + for (var i = 0; i < len; i++) { + arr[i] = binStr.charCodeAt(i); + } + + saveBlob(new Blob([arr], {type: "image/png"})); + } + }; + + var labels = []; // list of [label point, text] + if (app.labelVisible) { + var rootGroup = app.scene.labelConnectorGroup, connGroup, conn, pt; + for (var i = 0; i < rootGroup.children.length; i++) { + connGroup = rootGroup.children[i]; + if (!connGroup.visible) continue; + for (var k = 0; k < connGroup.children.length; k++) { + conn = connGroup.children[k]; + pt = conn.geometry.vertices[0]; + labels.push({pt: new THREE.Vector3(pt.x, pt.z, -pt.y), // in world coordinates + text: conn.userData.elem.textContent}); + } + } + } + + var renderLabels = function (ctx) { + // context settings + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + + // get label style from css + var elem = document.createElement("div"); + elem.className = "print-label"; + document.body.appendChild(elem); + var style = document.defaultView.getComputedStyle(elem, ""), + color = style.color; + ctx.font = style.font; + document.body.removeChild(elem); + + var widthHalf = width / 2, + heightHalf = height / 2, + camera = app.camera, + c2t = new THREE.Vector3(), + c2l = new THREE.Vector3(), + v = new THREE.Vector3(); + + camera.getWorldDirection(c2t); + + // make a list of [label index, distance to camera] + var idx_dist = []; + for (var i = 0, l = labels.length; i < l; i++) { + idx_dist.push([i, camera.position.distanceTo(labels[i].pt)]); + } + + // sort label indexes in descending order of distances + idx_dist.sort(function (a, b) { + if (a[1] < b[1]) return 1; + if (a[1] > b[1]) return -1; + return 0; + }); + + var label, text, x, y; + for (var i = 0, l = idx_dist.length; i < l; i++) { + label = labels[idx_dist[i][0]]; + if (c2l.subVectors(label.pt, camera.position).dot(c2t) > 0) { // label is in front + // calculate label position + v.copy(label.pt).project(camera); + x = (v.x * widthHalf) + widthHalf; + y = -(v.y * heightHalf) + heightHalf; + if (x < 0 || width <= x || y < 0 || height <= y) continue; + + // outline effect + ctx.fillStyle = "#FFF"; + for (var j = 0; j < 9; j++) { + if (j != 4) ctx.fillText(label.text, x + Math.floor(j / 3) - 1, y + j % 3 - 1); + } + + ctx.fillStyle = color; + ctx.fillText(label.text, x, y); + } + } + }; + + var restoreCanvasSize = function () { + // restore canvas size + if (old_size) app.setCanvasSize(old_size[0], old_size[1]); + app.render(); + }; + + // background option + if (!fill_background) app.renderer.setClearColor(0, 0); + + // render + app.renderer.preserveDrawingBuffer = true; + app.renderer.render(app.scene, app.camera); + + // restore clear color + var bgcolor = Q3D.Config.bgColor; + app.renderer.setClearColor(bgcolor || 0, (bgcolor === null) ? 0 : 1); + + if ((fill_background && bgcolor === null) || labels.length > 0) { + var canvas = document.createElement("canvas"); + canvas.width = width; + canvas.height = height; + + var ctx = canvas.getContext("2d"); + if (fill_background && bgcolor === null) { + // render "sky-like" background + var grad = ctx.createLinearGradient(0, 0, 0, height); + grad.addColorStop(0, "#98c8f6"); + grad.addColorStop(0.4, "#cbebff"); + grad.addColorStop(1, "#f0f9ff"); + ctx.fillStyle = grad; + ctx.fillRect(0, 0, width, height); + } + + var image = new Image(); + image.onload = function () { + // draw webgl canvas image + ctx.drawImage(image, 0, 0, width, height); + + // render labels + if (labels.length > 0) renderLabels(ctx); + + // save canvas image + saveCanvasImage(canvas); + restoreCanvasSize(); + }; + image.src = app.renderer.domElement.toDataURL("image/png"); + } + else { + // save webgl canvas image + saveCanvasImage(app.renderer.domElement); + restoreCanvasSize(); + } + }; +})(); + + +/* +Q3D.Material +*/ +Q3D.Material = function () { + this.loaded = false; +}; + +Q3D.Material.prototype = { + + constructor: Q3D.Material, + + // callback is called when material has been completely loaded + loadJSONObject: function (jsonObject, callback) { + this.origProp = jsonObject; + + var m = jsonObject, opt = {}, defer = false; + + if (m.ds && !Q3D.isIE) opt.side = THREE.DoubleSide; + + if (m.flat) opt.flatShading = true; + + // texture + if (m.image !== undefined) { + var _this = this; + if (m.image.url !== undefined) { + opt.map = Q3D.application.loadTextureFile(m.image.url, function () { + _this._loadCompleted(callback); + }); + defer = true; + } + else if (m.image.object !== undefined) { // WebKit Bridge + opt.map = new THREE.Texture(m.image.object.toImageData()); + opt.map.needsUpdate = true; + } + else { // base64 + var img = new Image(); + img.onload = function () { + opt.map.needsUpdate = true; + _this._loadCompleted(callback); + }; + img.src = m.image.base64; + opt.map = new THREE.Texture(img); + defer = true; + } + } + + if (m.c !== undefined) opt.color = m.c; + + if (m.o !== undefined && m.o < 1) { + opt.opacity = m.o; + opt.transparent = true; + } + + if (m.t) opt.transparent = true; + + if (m.w) opt.wireframe = true; + + if (m.type == Q3D.MaterialType.MeshLambert) { + this.mtl = new THREE.MeshLambertMaterial(opt); + } + else if (m.type == Q3D.MaterialType.MeshPhong) { + this.mtl = new THREE.MeshPhongMaterial(opt); + } + else if (m.type == Q3D.MaterialType.MeshToon) { + this.mtl = new THREE.MeshToonMaterial(opt); + } + else if (m.type == Q3D.MaterialType.Point) { + opt.size = m.s; + this.mtl = new THREE.PointsMaterial(opt); + } + else if (m.type == Q3D.MaterialType.LineBasic) { + this.mtl = new THREE.LineBasicMaterial(opt); + } + else if (m.type == Q3D.MaterialType.LineDashed) { + opt.dashSize = Q3D.Config.line.dash.dashSize; + opt.gapSize = Q3D.Config.line.dash.gapSize; + this.mtl = new THREE.LineDashedMaterial(opt); + } + else { + opt.color = 0xffffff; + this.mtl = new THREE.SpriteMaterial(opt); + } + + if (!defer) this._loadCompleted(callback); + }, + + _loadCompleted: function (anotherCallback) { + this.loaded = true; + + if (this._callbacks !== undefined) { + for (var i = 0; i < this._callbacks.length; i++) { + this._callbacks[i](); + } + this._callbacks = []; + } + + if (anotherCallback) anotherCallback(); + }, + + callbackOnLoad: function (callback) { + if (this.loaded) return callback(); + + if (this._callbacks === undefined) this._callbacks = []; + this._callbacks.push(callback); + }, + + set: function (material) { + this.mtl = material; + this.origProp = {}; + }, + + type: function () { + if (this.mtl instanceof THREE.MeshLambertMaterial) return Q3D.MaterialType.MeshLambert; + if (this.mtl instanceof THREE.MeshPhongMaterial) return Q3D.MaterialType.MeshPhong; + if (this.mtl instanceof THREE.LineBasicMaterial) return Q3D.MaterialType.LineBasic; + if (this.mtl instanceof THREE.LineDashedMaterial) return Q3D.MaterialType.LineDashed; + if (this.mtl instanceof THREE.SpriteMaterial) return Q3D.MaterialType.Sprite; + if (this.mtl === undefined) return undefined; + if (this.mtl === null) return null; + return Q3D.MaterialType.Unknown; + }, + + dispose: function () { + if (!this.mtl) return; + + if (this.mtl.map) this.mtl.map.dispose(); // dispose of texture + this.mtl.dispose(); + this.mtl = null; + } +}; + +/* +Q3D.Materials +*/ +Q3D.Materials = function () { + this.materials = []; +}; + +Q3D.Materials.prototype = Object.create(THREE.EventDispatcher.prototype); +Q3D.Materials.prototype.constructor = Q3D.Materials; + +// material: instance of Q3D.Material object or THREE.Material-based object +Q3D.Materials.prototype.add = function (material) { + if (material instanceof Q3D.Material) this.materials.push(material); + else { + var mtl = new Q3D.Material(); + mtl.set(material); + this.materials.push(mtl); + } +}; + +Q3D.Materials.prototype.get = function (index) { + return this.materials[index]; +}; + +Q3D.Materials.prototype.mtl = function (index) { + return this.materials[index].mtl; +}; + +Q3D.Materials.prototype.loadJSONObject = function (jsonObject) { + var _this = this, iterated = false; + var callback = function () { + if (iterated) _this.dispatchEvent({type: "renderRequest"}); + }; + + for (var i = 0, l = jsonObject.length; i < l; i++) { + var mtl = new Q3D.Material(); + mtl.loadJSONObject(jsonObject[i], callback); + this.add(mtl); + } + iterated = true; +}; + +Q3D.Materials.prototype.dispose = function () { + for (var i = 0, l = this.materials.length; i < l; i++) { + this.materials[i].dispose(); + } + this.materials = []; +}; + +Q3D.Materials.prototype.addFromObject3D = function (object) { + var _this = this, mtls = []; + + object.traverse(function (obj) { + if (obj.material === undefined) return; + ((obj.material instanceof Array) ? obj.material : [obj.material]).forEach(function (mtl) { + if (mtls.indexOf(mtl) == -1) { + mtls.push(mtl); + } + }); + }); + + var material; + for (var i = 0, l = mtls.length; i < l; i++) { + material = new Q3D.Material(); + material.set(mtls[i]); + this.materials.push(material); + } +}; + +// opacity +Q3D.Materials.prototype.opacity = function () { + if (this.materials.length == 0) return 1; + + var sum = 0; + for (var i = 0, l = this.materials.length; i < l; i++) { + sum += this.materials[i].mtl.opacity; + } + return sum / this.materials.length; +}; + +Q3D.Materials.prototype.setOpacity = function (opacity) { + var material; + for (var i = 0, l = this.materials.length; i < l; i++) { + material = this.materials[i]; + material.mtl.transparent = Boolean(material.origProp.t) || (opacity < 1); + material.mtl.opacity = opacity; + } +}; + +// wireframe: boolean +Q3D.Materials.prototype.setWireframeMode = function (wireframe) { + var material; + for (var i = 0, l = this.materials.length; i < l; i++) { + material = this.materials[i]; + if (material.origProp.w || material.mtl instanceof THREE.LineBasicMaterial) continue; + material.mtl.wireframe = wireframe; + } +}; + + +/* +Q3D.DEMBlock +*/ +Q3D.DEMBlock = function () {}; + +Q3D.DEMBlock.prototype = { + + constructor: Q3D.DEMBlock, + + // obj: json object + loadJSONObject: function (obj, layer, callback) { + var _this = this, + grid = obj.grid; + this.data = obj; + + // load material + this.material = new Q3D.Material(); + this.material.loadJSONObject(obj.material, function () { + layer.requestRender(); + }); + layer.materials.add(this.material); + + // create a plane geometry + var geom; + if (layer.geometryCache) { + var params = layer.geometryCache.parameters || {}; + if (params.width === obj.width && params.height === obj.height && + params.widthSegments === grid.width - 1 && params.heightSegments === grid.height - 1) { + geom = layer.geometryCache.clone(); + geom.parameters = layer.geometryCache.parameters; + } + } + geom = geom || new THREE.PlaneBufferGeometry(obj.width, obj.height, grid.width - 1, grid.height - 1); + layer.geometryCache = geom; + + // create a mesh + var mesh = new THREE.Mesh(geom, this.material.mtl); + mesh.position.fromArray(obj.translate); + mesh.scale.z = obj.zScale; + layer.addObject(mesh); + + var buildGeometry = function (grid_values) { + var vertices = geom.attributes.position.array; + for (var i = 0, j = 0, l = vertices.length; i < l; i++, j += 3) { + vertices[j + 2] = grid_values[i]; + } + geom.attributes.position.needsUpdate = true; + + if (layer.properties.shading) { + geom.computeVertexNormals(); + } + + if (callback) callback(mesh); + }; + + if (grid.url !== undefined) { + Q3D.application.loadFile(grid.url, "arraybuffer", function (buf) { + grid.array = new Float32Array(buf); + buildGeometry(grid.array); + }); + } + else { // WebKit Bridge + if (grid.binary !== undefined) grid.array = new Float32Array(grid.binary.buffer, 0, grid.width * grid.height); + buildGeometry(grid.array); + } + + this.obj = mesh; + return mesh; + }, + + buildSides: function (layer, parent, material, z0) { + var planeWidth = this.data.width, + planeHeight = this.data.height, + grid = this.data.grid, + grid_values = grid.array, + w = grid.width, + h = grid.height, + k = w * (h - 1); + + var e0 = z0 / this.data.zScale - this.data.zShift - (this.data.zShiftA || 0), + band_width = -2 * e0; + + // front and back + var geom_fr = new THREE.PlaneBufferGeometry(planeWidth, band_width, w - 1, 1), + geom_ba = geom_fr.clone(); + + var vertices_fr = geom_fr.attributes.position.array, + vertices_ba = geom_ba.attributes.position.array; + + var i, mesh; + for (i = 0; i < w; i++) { + vertices_fr[i * 3 + 1] = grid_values[k + i]; + vertices_ba[i * 3 + 1] = grid_values[w - 1 - i]; + } + mesh = new THREE.Mesh(geom_fr, material); + mesh.rotation.x = Math.PI / 2; + mesh.position.y = -planeHeight / 2; + mesh.name = "side"; + parent.add(mesh); + + mesh = new THREE.Mesh(geom_ba, material); + mesh.rotation.x = Math.PI / 2; + mesh.rotation.y = Math.PI; + mesh.position.y = planeHeight / 2; + mesh.name = "side"; + parent.add(mesh); + + // left and right + var geom_le = new THREE.PlaneBufferGeometry(band_width, planeHeight, 1, h - 1), + geom_ri = geom_le.clone(); + + var vertices_le = geom_le.attributes.position.array, + vertices_ri = geom_ri.attributes.position.array; + + for (i = 0; i < h; i++) { + vertices_le[(i * 2 + 1) * 3] = grid_values[w * i]; + vertices_ri[i * 2 * 3] = -grid_values[w * (i + 1) - 1]; + } + mesh = new THREE.Mesh(geom_le, material); + mesh.rotation.y = -Math.PI / 2; + mesh.position.x = -planeWidth / 2; + mesh.name = "side"; + parent.add(mesh); + + mesh = new THREE.Mesh(geom_ri, material); + mesh.rotation.y = Math.PI / 2; + mesh.position.x = planeWidth / 2; + mesh.name = "side"; + parent.add(mesh); + + // bottom + var geom; + if (Q3D.Config.exportMode) { + geom = new THREE.PlaneBufferGeometry(planeWidth, planeHeight, w - 1, h - 1); + } + else { + geom = new THREE.PlaneBufferGeometry(planeWidth, planeHeight, 1, 1); + } + mesh = new THREE.Mesh(geom, material); + mesh.rotation.x = Math.PI; + mesh.position.z = e0; + mesh.name = "bottom"; + parent.add(mesh); + + parent.updateMatrixWorld(); + }, + + buildFrame: function (layer, parent, material, z0) { + var grid = this.data.grid, + planeWidth = this.data.width, + planeHeight = this.data.height; + + // horizontal rectangle at bottom + var hw = planeWidth / 2, + hh = planeHeight / 2, + e0 = z0 / this.data.zScale - this.data.zShift - (this.data.zShiftA || 0); + var v = [-hw, -hh, e0, + hw, -hh, e0, + hw, hh, e0, + -hw, hh, e0, + -hw, -hh, e0]; + + var geom = new THREE.BufferGeometry(); + geom.addAttribute("position", new THREE.Float32BufferAttribute(v, 3)); + + var obj = new THREE.Line(geom, material); + obj.name = "frame"; + parent.add(obj); + + // vertical lines at corners + v = [[-hw, -hh, grid.array[grid.array.length - grid.width]], + [ hw, -hh, grid.array[grid.array.length - 1]], + [ hw, hh, grid.array[grid.width - 1]], + [-hw, hh, grid.array[0]]]; + + v.forEach(function (p) { + var geom = new THREE.BufferGeometry(), + vl = [p[0], p[1], p[2], p[0], p[1], e0]; + geom.addAttribute("position", new THREE.Float32BufferAttribute(vl, 3)); + + var obj = new THREE.Line(geom, material); + obj.name = "frame"; + parent.add(obj); + }); + + parent.updateMatrixWorld(); + }, + + getValue: function (x, y) { + var grid = this.data.grid; + if (0 <= x && x < grid.width && 0 <= y && y < grid.height) return grid.array[x + grid.width * y]; + return null; + }, + + contains: function (x, y) { + var translate = this.data.translate, + xmin = translate[0] - this.data.width / 2, + xmax = translate[0] + this.data.width / 2, + ymin = translate[1] - this.data.height / 2, + ymax = translate[1] + this.data.height / 2; + if (xmin <= x && x <= xmax && ymin <= y && y <= ymax) return true; + return false; + } + +}; + + +/* +Q3D.ClippedDEMBlock +*/ +Q3D.ClippedDEMBlock = function () {}; + +Q3D.ClippedDEMBlock.prototype = { + + constructor: Q3D.ClippedDEMBlock, + + loadJSONObject: function (obj, layer, callback) { + this.data = obj; + var _this = this; + + // load material + this.material = new Q3D.Material(); + this.material.loadJSONObject(obj.material, function () { + layer.requestRender(); + }); + layer.materials.add(this.material); + + var geom = new THREE.BufferGeometry(), + mesh = new THREE.Mesh(geom, this.material.mtl); + mesh.position.fromArray(obj.translate); + mesh.scale.z = obj.zScale; + layer.addObject(mesh); + + var buildGeometry = function (obj) { + + var vertices = obj.triangles.v, + base_width = layer.sceneData.width, + base_height = layer.sceneData.height; + var normals = [], uvs = []; + for (var i = 0, l = vertices.length; i < l; i += 3) { + normals.push(0, 0, 1); + uvs.push(vertices[i] / base_width + 0.5, vertices[i + 1] / base_height + 0.5); + } + + geom.setIndex(obj.triangles.f); + geom.addAttribute("position", new THREE.Float32BufferAttribute(vertices, 3)); + geom.addAttribute("normal", new THREE.Float32BufferAttribute(normals, 3)); + geom.addAttribute("uv", new THREE.Float32BufferAttribute(uvs, 2)); + + if (layer.properties.shading) { + geom.computeVertexNormals(); + } + + geom.attributes.position.needsUpdate = true; + geom.attributes.normal.needsUpdate = true; + geom.attributes.uv.needsUpdate = true; + + _this.data.polygons = obj.polygons; + if (callback) callback(mesh); + }; + + if (obj.geom.url !== undefined) { + Q3D.application.loadFile(obj.geom.url, "json", function (obj) { + buildGeometry(obj); + }); + } + else { // WebKit Bridge + buildGeometry(obj.geom); + } + + this.obj = mesh; + return mesh; + }, + + buildSides: function (layer, parent, material, z0) { + var polygons = this.data.polygons, + e0 = z0 / this.data.zScale - this.data.zShift - (this.data.zShiftA || 0), + bzFunc = function (x, y) { return e0; }; + + // make back-side material for bottom + var mat_back = material.clone(); + mat_back.side = THREE.BackSide; + layer.materials.add(mat_back); + + var geom, mesh, shape, vertices; + for (var i = 0, l = polygons.length; i < l; i++) { + var bnds = polygons[i]; + + // sides + for (var j = 0, m = bnds.length; j < m; j++) { + vertices = Q3D.Utils.arrayToVec3Array(bnds[j]); + geom = Q3D.Utils.createWallGeometry(vertices, bzFunc, true); + mesh = new THREE.Mesh(geom, material); + mesh.name = "side"; + parent.add(mesh); + } + + // bottom + shape = new THREE.Shape(Q3D.Utils.arrayToVec2Array(bnds[0])); + for (var j = 1, m = bnds.length; j < m; j++) { + shape.holes.push(new THREE.Path(Q3D.Utils.arrayToVec2Array(bnds[j]))); + } + geom = new THREE.ShapeBufferGeometry(shape); + mesh = new THREE.Mesh(geom, mat_back); + mesh.position.z = e0; + mesh.name = "bottom"; + parent.add(mesh); + } + parent.updateMatrixWorld(); + }, + + // not implemented + getValue: function (x, y) { + return null; + }, + + // not implemented + contains: function (x, y) { + return false; + } + +}; + +/* +Q3D.MapLayer +*/ +Q3D.MapLayer = function () { + this.properties = {}; + this.queryable = true; + + this.materials = new Q3D.Materials(); + this.materials.addEventListener("renderRequest", this.requestRender.bind(this)); + + this.objectGroup = new Q3D.Group(); + this.queryObjs = []; +}; + +Q3D.MapLayer.prototype = Object.create(THREE.EventDispatcher.prototype); +Q3D.MapLayer.prototype.constructor = Q3D.MapLayer; + +Q3D.MapLayer.prototype.addObject = function (object, queryable) { + if (queryable === undefined) queryable = this.queryable; + + object.userData.layerId = this.id; + this.objectGroup.add(object); + + if (queryable) { + var queryObjs = this.queryObjs; + object.traverse(function (obj) { + queryObjs.push(obj); + }); + } + return this.objectGroup.children.length - 1; +}; + +Q3D.MapLayer.prototype.queryableObjects = function () { + return (this.visible) ? this.queryObjs : []; +}; + +Q3D.MapLayer.prototype.removeAllObjects = function () { + // dispose of geometries + this.objectGroup.traverse(function (obj) { + if (obj.geometry) obj.geometry.dispose(); + }); + + // dispose of materials + this.materials.dispose(); + + // remove all child objects from object group + for (var i = this.objectGroup.children.length - 1 ; i >= 0; i--) { + this.objectGroup.remove(this.objectGroup.children[i]); + } + this.queryObjs = []; +}; + +Q3D.MapLayer.prototype.loadJSONObject = function (jsonObject, scene) { + if (jsonObject.type == "layer") { + // properties + if (jsonObject.properties !== undefined) { + this.properties = jsonObject.properties; + this.visible = (jsonObject.properties.visible || Q3D.Config.allVisible) ? true : false; + } + + if (jsonObject.data !== undefined) { + this.removeAllObjects(); + + // materials + if (jsonObject.data.materials !== undefined) { + this.materials.loadJSONObject(jsonObject.data.materials); + } + } + + this.sceneData = scene.userData; + this._bbox = undefined; + } +}; + +Object.defineProperty(Q3D.MapLayer.prototype, "opacity", { + get: function () { + return this.materials.opacity(); + }, + set: function (value) { + this.materials.setOpacity(value); + this.requestRender(); + } +}); + +Object.defineProperty(Q3D.MapLayer.prototype, "visible", { + get: function () { + return this.objectGroup.visible; + }, + set: function (value) { + this.objectGroup.visible = value; + this.requestRender(); + } +}); + +Q3D.MapLayer.prototype.boundingBox = function (forceUpdate) { + if (!this._bbox || forceUpdate) { + this._bbox = new THREE.Box3().setFromObject(this.objectGroup); + } + return this._bbox; +} + +Q3D.MapLayer.prototype.setWireframeMode = function (wireframe) { + this.materials.setWireframeMode(wireframe); +}; + +Q3D.MapLayer.prototype.requestRender = function () { + this.dispatchEvent({type: "renderRequest"}); +}; + + +/* +Q3D.DEMLayer --> Q3D.MapLayer +*/ +Q3D.DEMLayer = function () { + Q3D.MapLayer.call(this); + this.type = Q3D.LayerType.DEM; + this.blocks = []; +}; + +Q3D.DEMLayer.prototype = Object.create(Q3D.MapLayer.prototype); +Q3D.DEMLayer.prototype.constructor = Q3D.DEMLayer; + +Q3D.DEMLayer.prototype.loadJSONObject = function (jsonObject, scene) { + var old_shading = this.properties.shading; + Q3D.MapLayer.prototype.loadJSONObject.call(this, jsonObject, scene); + if (jsonObject.type == "layer") { + if (old_shading != jsonObject.properties.shading) { + this.geometryCache = null; + } + + if (jsonObject.data !== undefined) { + jsonObject.data.forEach(function (obj) { + this.buildBlock(obj, scene); + }, this); + } + } + else if (jsonObject.type == "block") { + this.buildBlock(jsonObject, scene); + } +}; + +Q3D.DEMLayer.prototype.buildBlock = function (jsonObject, scene) { + var _this = this; + + var index = jsonObject.block; + this.blocks[index] = (jsonObject.grid !== undefined) ? (new Q3D.DEMBlock()) : (new Q3D.ClippedDEMBlock()); + this.blocks[index].loadJSONObject(jsonObject, this, function (m) { + + if (jsonObject.sides || jsonObject.frame) { + + _this.sideVisible = true; + + var buildSides = function () { + var material; + // build sides and bottom + if (jsonObject.sides) { + material = new Q3D.Material(); + material.loadJSONObject(jsonObject.sides.mtl); + _this.materials.add(material); + + _this.blocks[index].buildSides(_this, m, material.mtl, Q3D.Config.dem.side.bottomZ); + } + // build frame + if (jsonObject.frame) { + material = new Q3D.Material(); + material.loadJSONObject(jsonObject.frame.mtl); + _this.materials.add(material); + + _this.blocks[index].buildFrame(_this, m, material.mtl, Q3D.Config.dem.frame.bottomZ); + } + _this.requestRender(); + }; + + if (Q3D.Config.autoZShift) { + scene.addEventListener("zShiftAdjusted", function listener(event) { + // set adjusted z shift to every block + _this.blocks.forEach(function (block) { + block.data.zShiftA = event.sceneData.zShiftA; + }); + buildSides(); + scene.removeEventListener("zShiftAdjusted", listener); + }); + } + else { + buildSides(); + } + } + _this.requestRender(); + }); +}; + +// calculate elevation at the coordinates (x, y) on triangle face +Q3D.DEMLayer.prototype.getZ = function (x, y) { + for (var i = 0, l = this.blocks.length; i < l; i++) { + var block = this.blocks[i], + data = block.data; + if (!block.contains(x, y)) continue; + + var ix = data.width / (data.grid.width - 1), + iy = data.height / (data.grid.height - 1); + + var xmin = data.translate[0] - data.width / 2, + ymax = data.translate[1] + data.height / 2; + + var mx0 = Math.floor((x - xmin) / ix), + my0 = Math.floor((ymax - y) / iy); + + var z = [block.getValue(mx0, my0), + block.getValue(mx0 + 1, my0), + block.getValue(mx0, my0 + 1), + block.getValue(mx0 + 1, my0 + 1)]; + + var px0 = xmin + ix * mx0, + py0 = ymax - iy * my0; + + var sdx = (x - px0) / ix, + sdy = (py0 - y) / iy; + + // console.log(x, y, mx0, my0, sdx, sdy); + + if (sdx <= 1 - sdy) return z[0] + (z[1] - z[0]) * sdx + (z[2] - z[0]) * sdy; + else return z[3] + (z[2] - z[3]) * (1 - sdx) + (z[1] - z[3]) * (1 - sdy); + } + return null; +}; + +Q3D.DEMLayer.prototype.segmentizeLineString = function (lineString, zFunc) { + // does not support multiple blocks + if (zFunc === undefined) zFunc = function () { return 0; }; + var width = this.sceneData.width, + height = this.sceneData.height; + var xmin = -width / 2, + ymax = height / 2; + var grid = this.blocks[0].data.grid, + ix = width / (grid.width - 1), + iy = height / (grid.height - 1); + var sort_func = function (a, b) { return a - b; }; + + var pts = []; + for (var i = 1, l = lineString.length; i < l; i++) { + var pt1 = lineString[i - 1], pt2 = lineString[i]; + var x1 = pt1[0], x2 = pt2[0], y1 = pt1[1], y2 = pt2[1], z1 = pt1[2], z2 = pt2[2]; + var nx1 = (x1 - xmin) / ix, + nx2 = (x2 - xmin) / ix; + var ny1 = (ymax - y1) / iy, + ny2 = (ymax - y2) / iy; + var ns1 = Math.abs(ny1 + nx1), + ns2 = Math.abs(ny2 + nx2); + + var p = [0], nvp = [[nx1, nx2], [ny1, ny2], [ns1, ns2]]; + for (var j = 0; j < 3; j++) { + var v1 = nvp[j][0], v2 = nvp[j][1]; + if (v1 == v2) continue; + var k = Math.ceil(Math.min(v1, v2)); + var n = Math.floor(Math.max(v1, v2)); + for (; k <= n; k++) { + p.push((k - v1) / (v2 - v1)); + } + } + + p.sort(sort_func); + + var x, y, z, lp = null; + for (var j = 0, m = p.length; j < m; j++) { + if (lp === p[j]) continue; + if (p[j] == 1) break; + + x = x1 + (x2 - x1) * p[j]; + y = y1 + (y2 - y1) * p[j]; + + if (z1 === undefined || z2 === undefined) z = zFunc(x, y); + else z = z1 + (z2 - z1) * p[j]; + + pts.push(new THREE.Vector3(x, y, z)); + + // Q3D.Utils.putStick(x, y, zFunc); + + lp = p[j]; + } + } + // last point (= the first point) + var pt = lineString[lineString.length - 1]; + pts.push(new THREE.Vector3(pt[0], pt[1], (pt[2] === undefined) ? zFunc(pt[0], pt[1]) : pt[2])); + + /* + for (var i = 0, l = lineString.length - 1; i < l; i++) { + Q3D.Utils.putStick(lineString[i][0], lineString[i][1], zFunc, 0.8); + } + */ + + return pts; +}; + +Q3D.DEMLayer.prototype.setSideVisible = function (visible) { + this.sideVisible = visible; + this.objectGroup.traverse(function (obj) { + if (obj.name == "side" || obj.name == "bottom" || obj.name == "frame") obj.visible = visible; + }); +}; + + +/* +Q3D.VectorLayer --> Q3D.MapLayer +*/ +Q3D.VectorLayer = function () { + Q3D.MapLayer.call(this); + + // this.labelConnectorGroup = undefined; + // this.labelParentElement = undefined; +}; + +Q3D.VectorLayer.prototype = Object.create(Q3D.MapLayer.prototype); +Q3D.VectorLayer.prototype.constructor = Q3D.VectorLayer; + +Q3D.VectorLayer.prototype.build = function (block) {}; + +Q3D.VectorLayer.prototype.clearLabels = function () { + if (this.labelConnectorGroup) this.labelConnectorGroup.clear(); + + // create parent element for labels + var elem = this.labelParentElement; + if (elem) { + while (elem.lastChild) { + elem.removeChild(elem.lastChild); + } + } +}; + +Q3D.VectorLayer.prototype.buildLabels = function (features, getPointsFunc) { + if (this.properties.label === undefined || getPointsFunc === undefined) return; + + var zShift = this.sceneData.zShift, + zScale = this.sceneData.zScale, + z0 = zShift * zScale; + var prop = this.properties.label, + pIndex = prop.index, + isRelative = prop.relative; + + var line_mat = new THREE.LineBasicMaterial({color: Q3D.Config.label.connectorColor}); + var f, text, e, pt0, pt1, geom, conn; + + for (var i = 0, l = features.length; i < l; i++) { + f = features[i]; + text = f.prop[pIndex]; + if (text === null || text === "") continue; + + getPointsFunc(f).forEach(function (pt) { + // create div element for label + e = document.createElement("div"); + e.className = "label"; + e.innerHTML = text; + this.labelParentElement.appendChild(e); + + pt0 = new THREE.Vector3(pt[0], pt[1], pt[2]); // bottom + pt1 = new THREE.Vector3(pt[0], pt[1], (isRelative) ? pt[2] + f.lh : z0 + f.lh); // top + + if (Q3D.Config.label.queryable) { + var obj = this.objectGroup.children[f.objIndices[0]]; + e.onclick = function () { + app.scene.remove(app.queryMarker); + app.highlightFeature(obj); + app.render(); + app.showQueryResult({x: pt[0], y: pt[1], z: pt[2]}, obj, true); + }; + e.classList.add("queryable"); + } + else { + e.classList.add("no-events"); + } + + // create connector + geom = new THREE.Geometry(); + geom.vertices.push(pt1, pt0); + + conn = new THREE.Line(geom, line_mat); + conn.userData.layerId = this.id; + //conn.userData.featureId = i; + conn.userData.elem = e; + + this.labelConnectorGroup.add(conn); + + }, this); + } +}; + +Q3D.VectorLayer.prototype.loadJSONObject = function (jsonObject, scene) { + Q3D.MapLayer.prototype.loadJSONObject.call(this, jsonObject, scene); + if (jsonObject.type == "layer") { + if (jsonObject.data !== undefined) { + this.clearLabels(); + + // build labels + if (this.properties.label !== undefined) { + // create a label connector group + if (this.labelConnectorGroup === undefined) { + this.labelConnectorGroup = new Q3D.Group(); + this.labelConnectorGroup.userData.layerId = this.id; + this.labelConnectorGroup.visible = this.visible; + scene.labelConnectorGroup.add(this.labelConnectorGroup); + } + + // create a label parent element + if (this.labelParentElement === undefined) { + this.labelParentElement = document.createElement("div"); + this.labelParentElement.style.display = (this.visible) ? "block" : "none"; + scene.labelRootElement.appendChild(this.labelParentElement); + } + } + + (jsonObject.data.blocks || []).forEach(function (block) { + if (block.url !== undefined) Q3D.application.loadJSONFile(block.url); + else { + this.build(block.features); + if (this.properties.label !== undefined) this.buildLabels(block.features); + } + }, this); + } + } + else if (jsonObject.type == "block") { + this.build(jsonObject.features); + if (this.properties.label !== undefined) this.buildLabels(jsonObject.features); + } +}; + +Object.defineProperty(Q3D.VectorLayer.prototype, "visible", { + get: function () { + return Object.getOwnPropertyDescriptor(Q3D.MapLayer.prototype, "visible").get.call(this); + }, + set: function (value) { + if (this.labelParentElement) this.labelParentElement.style.display = (value) ? "block" : "none"; + if (this.labelConnectorGroup) this.labelConnectorGroup.visible = value; + Object.getOwnPropertyDescriptor(Q3D.MapLayer.prototype, "visible").set.call(this, value); + } +}); + + +/* +Q3D.PointLayer --> Q3D.VectorLayer +*/ +Q3D.PointLayer = function () { + Q3D.VectorLayer.call(this); + this.type = Q3D.LayerType.Point; +}; + +Q3D.PointLayer.prototype = Object.create(Q3D.VectorLayer.prototype); +Q3D.PointLayer.prototype.constructor = Q3D.PointLayer; + +Q3D.PointLayer.prototype.loadJSONObject = function (jsonObject, scene) { + Q3D.VectorLayer.prototype.loadJSONObject.call(this, jsonObject, scene); + if (jsonObject.type == "layer" && jsonObject.properties.objType == "Model File" && jsonObject.data !== undefined) { + if (this.models === undefined) { + var _this = this; + + this.models = new Q3D.Models(); + this.models.addEventListener("modelLoaded", function (event) { + _this.materials.addFromObject3D(event.model.scene); + _this.requestRender(); + }); + } + else { + this.models.clear(); + } + this.models.loadJSONObject(jsonObject.data.models); + } +}; + +Q3D.PointLayer.prototype.build = function (features) { + var objType = this.properties.objType; + if (objType == "Point") { this.buildPoints(features); return; } + if (objType == "Icon") { this.buildIcons(features); return; } + if (objType == "Model File") { this.buildModels(features); return; } + + var deg2rad = Math.PI / 180, rx = 90 * deg2rad; + var setSR, unitGeom; + + if (this.cachedGeometryType == objType) { + unitGeom = this.geometryCache; + } + + if (objType == "Sphere") { + setSR = function (mesh, geom) { + mesh.scale.set(geom.r, geom.r, geom.r); + }; + unitGeom = unitGeom || new THREE.SphereBufferGeometry(1, 32, 32); + } + else if (objType == "Box") { + setSR = function (mesh, geom) { + mesh.scale.set(geom.w, geom.h, geom.d); + mesh.rotation.x = rx; + }; + unitGeom = unitGeom || new THREE.BoxBufferGeometry(1, 1, 1); + } + else if (objType == "Disk") { + var sz = this.sceneData.zExaggeration; // set 1 if not to be elongated + setSR = function (mesh, geom) { + mesh.scale.set(geom.r, geom.r * sz, 1); + mesh.rotateOnWorldAxis(Q3D.uv.i, -geom.d * deg2rad); + mesh.rotateOnWorldAxis(Q3D.uv.k, -geom.dd * deg2rad); + }; + unitGeom = unitGeom || new THREE.CircleBufferGeometry(1, 32); + } + else if (objType == "Plane") { + var sz = this.sceneData.zExaggeration; // set 1 if not to be elongated + setSR = function (mesh, geom) { + mesh.scale.set(geom.w, geom.l * sz, 1); + mesh.rotateOnWorldAxis(Q3D.uv.i, -geom.d * deg2rad); + mesh.rotateOnWorldAxis(Q3D.uv.k, -geom.dd * deg2rad); + }; + unitGeom = unitGeom || new THREE.PlaneBufferGeometry(1, 1, 1, 1); + } + else { // Cylinder or Cone + setSR = function (mesh, geom) { + mesh.scale.set(geom.r, geom.h, geom.r); + mesh.rotation.x = rx; + }; + unitGeom = unitGeom || ((objType == "Cylinder") ? new THREE.CylinderBufferGeometry(1, 1, 1, 32) : new THREE.CylinderBufferGeometry(0, 1, 1, 32)); + } + + // iteration for features + var materials = this.materials; + var f, geom, z_addend, i, l, mesh, pt; + for (var fidx = 0, flen = features.length; fidx < flen; fidx++) { + f = features[fidx]; + f.objIndices = [] + + geom = f.geom; + z_addend = (geom.h) ? geom.h / 2 : 0; + for (i = 0, l = geom.pts.length; i < l; i++) { + mesh = new THREE.Mesh(unitGeom, materials.mtl(f.mtl)); + setSR(mesh, geom); + + pt = geom.pts[i]; + mesh.position.set(pt[0], pt[1], pt[2] + z_addend); + mesh.userData.properties = f.prop; + + f.objIndices.push(this.addObject(mesh)); + } + } + + this.geometryCache = unitGeom; + this.cachedGeometryType = objType; +}; + +Q3D.PointLayer.prototype.buildPoints = function (features) { + var f, geom, obj; + for (var fidx = 0, flen = features.length; fidx < flen; fidx++) { + f = features[fidx]; + + geom = new THREE.BufferGeometry(); + geom.addAttribute("position", + new THREE.BufferAttribute(new Float32Array(f.geom.pts), 3)); + + obj = new THREE.Points(geom, this.materials.mtl(f.mtl)); + obj.userData.properties = f.prop; + + f.objIndices = [this.addObject(obj)]; + } +}; + +Q3D.PointLayer.prototype.buildIcons = function (features) { + // each feature in this layer + features.forEach(function (f) { + var sprite, + objs = [], + material = this.materials.get(f.mtl); + + f.objIndices = []; + for (var i = 0, l = f.geom.pts.length; i < l; i++) { + sprite = new THREE.Sprite(material.mtl); + sprite.position.fromArray(f.geom.pts[i]); + sprite.userData.properties = f.prop; + + objs.push(sprite); + f.objIndices.push(this.addObject(sprite)); + } + + material.callbackOnLoad(function () { + var img = material.mtl.map.image; + for (var i = 0; i < objs.length; i++) { + // base size is 64 x 64 + objs[i].scale.set(img.width / 64 * f.geom.scale, + img.height / 64 * f.geom.scale, + 1); + objs[i].updateMatrixWorld(); + } + }); + }, this); +}; + +Q3D.PointLayer.prototype.buildModels = function (features) { + var _this = this, + q = new THREE.Quaternion(), + e = new THREE.Euler(), + deg2rad = Math.PI / 180; + + // each feature in this layer + features.forEach(function (f) { + var model = _this.models.get(f.model); + if (model === undefined) { + console.log("Model File: There is a missing model."); + return; + } + + f.objIndices = []; + f.geom.pts.forEach(function (pt) { + model.callbackOnLoad(function (m) { + var obj = m.scene.clone(); + obj.scale.set(f.geom.scale, f.geom.scale, f.geom.scale); + + if (obj.rotation.x) { // == -Math.PI / 2 (z-up model) + // reset coordinate system to z-up and specified rotation + obj.rotation.set(0, 0, 0); + obj.quaternion.multiply(q.setFromEuler(e.set(f.geom.rotateX * deg2rad, + f.geom.rotateY * deg2rad, + f.geom.rotateZ * deg2rad, + f.geom.rotateO || "XYZ"))); + } + else { + // y-up to z-up and specified rotation + obj.quaternion.multiply(q.setFromEuler(e.set(f.geom.rotateX * deg2rad, + f.geom.rotateY * deg2rad, + f.geom.rotateZ * deg2rad, + f.geom.rotateO || "XYZ"))); + obj.quaternion.multiply(q.setFromEuler(e.set(Math.PI / 2, 0, 0))); + } + + var parent = new THREE.Group(); + parent.scale.set(1, 1, _this.sceneData.zExaggeration); + parent.position.fromArray(pt); + parent.userData.properties = f.prop; + parent.add(obj); + + f.objIndices.push(_this.addObject(parent)); + }); + }); + }); +}; + +Q3D.PointLayer.prototype.buildLabels = function (features) { + Q3D.VectorLayer.prototype.buildLabels.call(this, features, function (f) { return f.geom.pts; }); +}; + + +/* +Q3D.LineLayer --> Q3D.VectorLayer +*/ +Q3D.LineLayer = function () { + Q3D.VectorLayer.call(this); + this.type = Q3D.LayerType.Line; +}; + +Q3D.LineLayer.prototype = Object.create(Q3D.VectorLayer.prototype); +Q3D.LineLayer.prototype.constructor = Q3D.LineLayer; + +Q3D.LineLayer.prototype.loadJSONObject = function (jsonObject, scene) { + Q3D.VectorLayer.prototype.loadJSONObject.call(this, jsonObject, scene); +}; + +Q3D.LineLayer.prototype.build = function (features) { + var createObject, + objType = this.properties.objType, + materials = this.materials, + sceneData = this.sceneData; + + if (objType == this._lastObjType && this._createObject !== undefined) { + createObject = this._createObject; + } + else if (objType == "Line") { + createObject = function (f, line) { + var pt, vertices = []; + for (var i = 0, l = line.length; i < l; i++) { + pt = line[i]; + vertices.push(pt[0], pt[1], pt[2]); + } + var geom = new THREE.BufferGeometry(); + geom.addAttribute("position", new THREE.Float32BufferAttribute(vertices, 3)); + + var obj = new THREE.Line(geom, materials.mtl(f.mtl)); + if (obj.material instanceof THREE.LineDashedMaterial) obj.computeLineDistances(); + return obj; + }; + } + else if (objType == "Pipe" || objType == "Cone") { + var jointGeom, cylinGeom; + if (objType == "Pipe") { + jointGeom = new THREE.SphereBufferGeometry(1, 32, 32); + cylinGeom = new THREE.CylinderBufferGeometry(1, 1, 1, 32); + } + else { + cylinGeom = new THREE.CylinderBufferGeometry(0, 1, 1, 32); + } + + var mesh, pt0 = new THREE.Vector3(), pt1 = new THREE.Vector3(), sub = new THREE.Vector3(), axis = Q3D.uv.j; + + createObject = function (f, line) { + var group = new Q3D.Group(); + + pt0.set(line[0][0], line[0][1], line[0][2]); + for (var i = 1, l = line.length; i < l; i++) { + pt1.set(line[i][0], line[i][1], line[i][2]); + + mesh = new THREE.Mesh(cylinGeom, materials.mtl(f.mtl)); + mesh.scale.set(f.geom.r, pt0.distanceTo(pt1), f.geom.r); + mesh.position.set((pt0.x + pt1.x) / 2, (pt0.y + pt1.y) / 2, (pt0.z + pt1.z) / 2); + mesh.quaternion.setFromUnitVectors(axis, sub.subVectors(pt1, pt0).normalize()); + group.add(mesh); + + if (jointGeom && i < l - 1) { + mesh = new THREE.Mesh(jointGeom, materials.mtl(f.mtl)); + mesh.scale.set(f.geom.r, f.geom.r, f.geom.r); + mesh.position.copy(pt1); + group.add(mesh); + } + + pt0.copy(pt1); + } + return group; + }; + } + else if (objType == "Box") { + // In this method, box corners are exposed near joint when both azimuth and slope of + // the segments of both sides are different. Also, some unnecessary faces are created. + var faces = [], vi; + vi = [[0, 5, 4], [4, 5, 1], // left turn - top, side, bottom + [3, 0, 7], [7, 0, 4], + [6, 3, 2], [2, 3, 7], + [4, 1, 0], [0, 1, 5], // right turn - top, side, bottom + [1, 2, 5], [5, 2, 6], + [2, 7, 6], [6, 7, 3]]; + + for (var j = 0; j < 12; j++) { + faces.push(new THREE.Face3(vi[j][0], vi[j][1], vi[j][2])); + } + + createObject = function (f, line) { + var geometry = new THREE.Geometry(), + group = new Q3D.Group(); // used in debug mode + + var geom, mesh, dist, quat, rx, rz, wh4, vb4, vf4; + var pt0 = new THREE.Vector3(), pt1 = new THREE.Vector3(), sub = new THREE.Vector3(), + pt = new THREE.Vector3(), ptM = new THREE.Vector3(), scale1 = new THREE.Vector3(1, 1, 1), + matrix = new THREE.Matrix4(), quat = new THREE.Quaternion(); + + pt0.set(line[0][0], line[0][1], line[0][2]); + for (var i = 1, l = line.length; i < l; i++) { + pt1.set(line[i][0], line[i][1], line[i][2]); + dist = pt0.distanceTo(pt1); + sub.subVectors(pt1, pt0); + rx = Math.atan2(sub.z, Math.sqrt(sub.x * sub.x + sub.y * sub.y)); + rz = Math.atan2(sub.y, sub.x) - Math.PI / 2; + ptM.set((pt0.x + pt1.x) / 2, (pt0.y + pt1.y) / 2, (pt0.z + pt1.z) / 2); // midpoint + quat.setFromEuler(new THREE.Euler(rx, 0, rz, "ZXY")); + matrix.compose(ptM, quat, scale1); + + // place a box to the segment + geom = new THREE.BoxGeometry(f.geom.w, dist, f.geom.h); + geom.applyMatrix(matrix); + geometry.merge(geom); + + // joint + // 4 vertices of backward side of current segment + wh4 = [[-f.geom.w / 2, f.geom.h / 2], + [f.geom.w / 2, f.geom.h / 2], + [f.geom.w / 2, -f.geom.h / 2], + [-f.geom.w / 2, -f.geom.h / 2]]; + vb4 = []; + for (j = 0; j < 4; j++) { + pt.set(wh4[j][0], -dist / 2, wh4[j][1]); + pt.applyMatrix4(matrix); + vb4.push(pt.clone()); + } + + if (vf4) { + geom = new THREE.Geometry(); + geom.vertices = vf4.concat(vb4); + geom.faces = faces; + geometry.merge(geom); + } + + // 4 vertices of forward side + vf4 = []; + for (j = 0; j < 4; j++) { + pt.set(wh4[j][0], dist / 2, wh4[j][1]); + pt.applyMatrix4(matrix); + vf4.push(new THREE.Vector3(pt.x, pt.y, pt.z)); + } + + pt0.copy(pt1); + } + + geometry.faceVertexUvs = [[]]; + geometry.mergeVertices(); + geometry.computeFaceNormals(); + if (Q3D.Config.exportMode) geometry = new THREE.BufferGeometry().fromGeometry(geometry); + return new THREE.Mesh(geometry, materials.mtl(f.mtl)); + }; + } + else if (objType == "Wall") { + var z0 = sceneData.zShift * sceneData.zScale; + + createObject = function (f, line) { + var pt; + var vertices = []; + for (var i = 0, l = line.length; i < l; i++) { + pt = line[i]; + vertices.push(new THREE.Vector3(pt[0], pt[1], pt[2])); + } + var bzFunc = function (x, y) { return z0 + f.geom.bh; }; + return new THREE.Mesh(Q3D.Utils.createWallGeometry(vertices, bzFunc), + materials.mtl(f.mtl)); + }; + } + + // each feature in this layer + var f, i, l, obj; + for (var fidx = 0, flen = features.length; fidx < flen; fidx++) { + f = features[fidx]; + f.objIndices = []; + + for (i = 0, l = f.geom.lines.length; i < l; i++) { + obj = createObject(f, f.geom.lines[i]); + obj.userData.properties = f.prop; + + f.objIndices.push(this.addObject(obj)); + } + } + + this._lastObjType = objType; + this._createObject = createObject; +}; + +Q3D.LineLayer.prototype.buildLabels = function (features) { + // Line layer doesn't support label + // Q3D.VectorLayer.prototype.buildLabels.call(this, features); +}; + + +/* +Q3D.PolygonLayer --> Q3D.VectorLayer +*/ +Q3D.PolygonLayer = function () { + Q3D.VectorLayer.call(this); + this.type = Q3D.LayerType.Polygon; + + // for overlay + this.borderVisible = true; + this.sideVisible = true; +}; + +Q3D.PolygonLayer.prototype = Object.create(Q3D.VectorLayer.prototype); +Q3D.PolygonLayer.prototype.constructor = Q3D.PolygonLayer; + +Q3D.PolygonLayer.prototype.loadJSONObject = function (jsonObject, scene) { + Q3D.VectorLayer.prototype.loadJSONObject.call(this, jsonObject, scene); +}; + +Q3D.PolygonLayer.prototype.build = function (features) { + var createObject, + materials = this.materials, + sceneData = this.sceneData; + + if (this.properties.objType == this._lastObjType && this._createObject !== undefined) { + createObject = this._createObject; + } + else if (this.properties.objType == "Polygon") { + createObject = function (f) { + var geom = new THREE.BufferGeometry(); + geom.addAttribute("position", new THREE.Float32BufferAttribute(f.geom.triangles.v, 3)); + geom.setIndex(f.geom.triangles.f); + if (!Q3D.Config.exportMode) { + geom = new THREE.Geometry().fromBufferGeometry(geom); // Flat shading doesn't work with combination of + // BufferGeometry and Lambert/Toon material. + } + return new THREE.Mesh(geom, materials.mtl(f.mtl)); + }; + } + else if (this.properties.objType == "Extruded") { + var createSubObject = function (f, polygon, z) { + var i, l, j, m; + + var shape = new THREE.Shape(Q3D.Utils.arrayToVec2Array(polygon[0])); + for (i = 1, l = polygon.length; i < l; i++) { + shape.holes.push(new THREE.Path(Q3D.Utils.arrayToVec2Array(polygon[i]))); + } + + // extruded geometry + var geom = new THREE.ExtrudeBufferGeometry(shape, {bevelEnabled: false, depth: f.geom.h}); + var mesh = new THREE.Mesh(geom, materials.mtl(f.mtl.face)); + mesh.position.z = z; + + if (f.mtl.edge !== undefined) { + // edge + var edge, bnd, p, v, + h = f.geom.h, + mtl = materials.mtl(f.mtl.edge); + + for (i = 0, l = polygon.length; i < l; i++) { + bnd = polygon[i]; + + v = []; + for (j = 0, m = bnd.length; j < m; j++) { + v.push(bnd[j][0], bnd[j][1], 0); + } + + geom = new THREE.BufferGeometry(); + geom.addAttribute("position", new THREE.Float32BufferAttribute(v, 3)); + + edge = new THREE.Line(geom, mtl); + mesh.add(edge); + + edge = new THREE.Line(geom, mtl); + edge.position.z = h; + mesh.add(edge); + + // vertical lines + for (j = 0, m = bnd.length - 1; j < m; j++) { + v = [bnd[j][0], bnd[j][1], 0, + bnd[j][0], bnd[j][1], h]; + + geom = new THREE.BufferGeometry(); + geom.addAttribute("position", new THREE.Float32BufferAttribute(v, 3)); + + edge = new THREE.Line(geom, mtl); + mesh.add(edge); + } + } + } + return mesh; + }; + + createObject = function (f) { + if (f.geom.polygons.length == 1) return createSubObject(f, f.geom.polygons[0], f.geom.centroids[0][2]); + + var group = new THREE.Group(); + for (var i = 0, l = f.geom.polygons.length; i < l; i++) { + group.add(createSubObject(f, f.geom.polygons[i], f.geom.centroids[i][2])); + } + return group; + }; + } + else if (this.properties.objType == "Overlay") { + createObject = function (f) { + + var vertices = f.geom.triangles.v, + base_width = sceneData.width, + base_height = sceneData.height, + uvs = []; + + for (var i = 0, l = vertices.length; i < l; i += 3) { + uvs.push(vertices[i] / base_width + 0.5, vertices[i + 1] / base_height + 0.5); + } + + var geom = new THREE.BufferGeometry(); + geom.setIndex(f.geom.triangles.f); + geom.addAttribute("position", new THREE.Float32BufferAttribute(vertices, 3)); + geom.addAttribute("uv", new THREE.Float32BufferAttribute(uvs, 2)); + geom.computeVertexNormals(); + + var mesh = new THREE.Mesh(geom, materials.mtl(f.mtl.face)); + + // borders + if (f.geom.brdr !== undefined) { + var bnds, i, l, j, m; + for (i = 0, l = f.geom.brdr.length; i < l; i++) { + bnds = f.geom.brdr[i]; + for (j = 0, m = bnds.length; j < m; j++) { + geom = new THREE.BufferGeometry(), + geom.addAttribute("position", new THREE.Float32BufferAttribute(bnds[j], 3)); + + mesh.add(new THREE.Line(geom, materials.mtl(f.mtl.brdr))); + } + } + } + return mesh; + }; + } + + // each feature in this layer + var f, obj; + for (var i = 0, l = features.length; i < l; i++) { + f = features[i]; + obj = createObject(f); + obj.userData.properties = f.prop; + + f.objIndices = [this.addObject(obj)]; + } + + this._lastObjType = this.properties.objType; + this._createObject = createObject; +}; + +Q3D.PolygonLayer.prototype.buildLabels = function (features) { + Q3D.VectorLayer.prototype.buildLabels.call(this, features, function (f) { return f.geom.centroids; }); +}; + +Q3D.PolygonLayer.prototype.setBorderVisible = function (visible) { + if (this.properties.objType != "Overlay") return; + + this.objectGroup.children.forEach(function (parent) { + for (var i = 0, l = parent.children.length; i < l; i++) { + var obj = parent.children[i]; + if (obj instanceof THREE.Line) obj.visible = visible; + } + }); + this.borderVisible = visible; +}; + +Q3D.PolygonLayer.prototype.setSideVisible = function (visible) { + if (this.properties.objType != "Overlay") return; + + this.objectGroup.children.forEach(function (parent) { + for (var i = 0, l = parent.children.length; i < l; i++) { + var obj = parent.children[i]; + if (obj instanceof THREE.Mesh) obj.visible = visible; + } + }); + this.sideVisible = visible; +}; + +/* +Q3D.Model +*/ +Q3D.Model = function () { + this.loaded = false; +}; + +Q3D.Model.prototype = { + + constructor: Q3D.Model, + + // callback is called when model has been completely loaded + load: function (url, callback) { + var _this = this; + Q3D.application.loadModelFile(url, function (model) { + _this.model = model; + _this._loadCompleted(callback); + }); + }, + + loadJSONObject: function (jsonObject, callback) { + this.load(jsonObject.url, callback); + }, + + _loadCompleted: function (anotherCallback) { + this.loaded = true; + + if (this._callbacks !== undefined) { + for (var i = 0; i < this._callbacks.length; i++) { + this._callbacks[i](this.model); + } + this._callbacks = []; + } + + if (anotherCallback) anotherCallback(this.model); + }, + + callbackOnLoad: function (callback) { + if (this.loaded) return callback(this.model); + + if (this._callbacks === undefined) this._callbacks = []; + this._callbacks.push(callback); + } + +}; + + +/* +Q3D.Models +*/ +Q3D.Models = function () { + this.models = []; + this.cache = {}; +}; + +Q3D.Models.prototype = Object.create(THREE.EventDispatcher.prototype); +Q3D.Models.prototype.constructor = Q3D.Models; + +Q3D.Models.prototype.loadJSONObject = function (jsonObject) { + var _this = this; + var callback = function (model) { + _this.dispatchEvent({type: "modelLoaded", model: model}); + }; + + var model, url; + for (var i = 0, l = jsonObject.length; i < l; i++) { + url = jsonObject[i].url; + + if (this.cache[url] !== undefined) { + model = this.cache[url]; + } + else { + model = new Q3D.Model(); + model.load(url, callback); + this.cache[url] = model; + } + + this.models.push(model); + } +}; + +Q3D.Models.prototype.get = function (index) { + return this.models[index]; +}; + +Q3D.Models.prototype.clear = function () { + this.models = []; +}; + + +// Q3D.Utils - Utilities +Q3D.Utils = {}; + +// Put a stick to given position (for debug) +Q3D.Utils.putStick = function (x, y, zFunc, h) { + if (Q3D.Utils._stick_mat === undefined) Q3D.Utils._stick_mat = new THREE.LineBasicMaterial({color: 0xff0000}); + if (h === undefined) h = 0.2; + if (zFunc === undefined) { + zFunc = function (x, y) { return Q3D.application.scene.mapLayers[0].getZ(x, y); }; + } + var z = zFunc(x, y); + var geom = new THREE.Geometry(); + geom.vertices.push(new THREE.Vector3(x, y, z + h), new THREE.Vector3(x, y, z)); + var stick = new THREE.Line(geom, Q3D.Utils._stick_mat); + Q3D.application.scene.add(stick); +}; + +// convert latitude and longitude in degrees to the following format +// Ndd°mm′ss.ss″, Eddd°mm′ss.ss″ +Q3D.Utils.convertToDMS = function (lat, lon) { + function toDMS(degrees) { + var deg = Math.floor(degrees), + m = (degrees - deg) * 60, + min = Math.floor(m), + sec = (m - min) * 60; + return deg + "°" + ("0" + min).slice(-2) + "′" + ((sec < 10) ? "0" : "") + sec.toFixed(2) + "″"; + } + + return ((lat < 0) ? "S" : "N") + toDMS(Math.abs(lat)) + ", " + + ((lon < 0) ? "W" : "E") + toDMS(Math.abs(lon)); +}; + +Q3D.Utils.createWallGeometry = function (vertices, bzFunc, buffer_geom) { + var geom = new THREE.Geometry(), + pt = vertices[0]; + geom.vertices.push( + new THREE.Vector3(pt.x, pt.y, pt.z), + new THREE.Vector3(pt.x, pt.y, bzFunc(pt.x, pt.y))); + + for (var i = 1, i2 = 1, l = vertices.length; i < l; i++, i2+=2) { + pt = vertices[i]; + geom.vertices.push( + new THREE.Vector3(pt.x, pt.y, pt.z), + new THREE.Vector3(pt.x, pt.y, bzFunc(pt.x, pt.y))); + + geom.faces.push( + new THREE.Face3(i2 - 1, i2, i2 + 1), + new THREE.Face3(i2 + 1, i2, i2 + 2)); + } + geom.computeFaceNormals(); + + if (buffer_geom || Q3D.Config.exportMode) { + return new THREE.BufferGeometry().fromGeometry(geom); + } + return geom; +}; + +Q3D.Utils.arrayToVec2Array = function (points) { + var pt, pts = []; + for (var i = 0, l = points.length; i < l; i++) { + pt = points[i]; + pts.push(new THREE.Vector2(pt[0], pt[1])); + } + return pts; +}; + +Q3D.Utils.arrayToVec3Array = function (points, zFunc) { + var pt, pts = []; + if (zFunc === undefined) { + for (var i = 0, l = points.length; i < l; i++) { + pt = points[i]; + pts.push(new THREE.Vector3(pt[0], pt[1], pt[2])); + } + } + else { + for (var i = 0, l = points.length; i < l; i++) { + pt = points[i]; + pts.push(new THREE.Vector3(pt[0], pt[1], zFunc(pt[0], pt[1]))); + } + } + return pts; +}; + +Q3D.Utils.arrayToFace3Array = function (faces) { + var f, fs = []; + for (var i = 0, l = faces.length; i < l; i++) { + f = faces[i]; + fs.push(new THREE.Face3(f[0], f[1], f[2])); + } + return fs; +}; + +Q3D.Utils.setGeometryUVs = function (geom, base_width, base_height) { + var face, v, uvs = []; + for (var i = 0, l = geom.vertices.length; i < l; i++) { + v = geom.vertices[i]; + uvs.push(new THREE.Vector2(v.x / base_width + 0.5, v.y / base_height + 0.5)); + } + + geom.faceVertexUvs[0] = []; + for (var i = 0, l = geom.faces.length; i < l; i++) { + face = geom.faces[i]; + geom.faceVertexUvs[0].push([uvs[face.a], uvs[face.b], uvs[face.c]]); + } +}; diff --git a/docs/examples/24/qgis2threejs.png b/docs/examples/24/qgis2threejs.png new file mode 100644 index 00000000..1d003067 Binary files /dev/null and b/docs/examples/24/qgis2threejs.png differ diff --git a/docs/examples/24/threejs/license b/docs/examples/24/threejs/license new file mode 100644 index 00000000..d3400897 --- /dev/null +++ b/docs/examples/24/threejs/license @@ -0,0 +1,21 @@ +The MIT License + +Copyright © 2010-2019 three.js authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/docs/examples/24/threejs/orbitcontrols.js b/docs/examples/24/threejs/orbitcontrols.js new file mode 100644 index 00000000..6df44d4e --- /dev/null +++ b/docs/examples/24/threejs/orbitcontrols.js @@ -0,0 +1,1072 @@ +/** + * @author qiao / https://github.com/qiao + * @author mrdoob / http://mrdoob.com + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author erich666 / http://erichaines.com + */ + +// This set of controls performs orbiting, dollying (zooming), and panning. +// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). +// +// Orbit - left mouse / touch: one-finger move +// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish +// Pan - right mouse, or left mouse + ctrl/metaKey, or arrow keys / touch: two-finger move + +THREE.OrbitControls = function ( object, domElement ) { + + this.object = object; + + this.domElement = ( domElement !== undefined ) ? domElement : document; + + // Set to false to disable this control + this.enabled = true; + + // "target" sets the location of focus, where the object orbits around + this.target = new THREE.Vector3(); + + // How far you can dolly in and out ( PerspectiveCamera only ) + this.minDistance = 0; + this.maxDistance = Infinity; + + // How far you can zoom in and out ( OrthographicCamera only ) + this.minZoom = 0; + this.maxZoom = Infinity; + + // How far you can orbit vertically, upper and lower limits. + // Range is 0 to Math.PI radians. + this.minPolarAngle = 0; // radians + this.maxPolarAngle = Math.PI; // radians + + // How far you can orbit horizontally, upper and lower limits. + // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ]. + this.minAzimuthAngle = - Infinity; // radians + this.maxAzimuthAngle = Infinity; // radians + + // Set to true to enable damping (inertia) + // If damping is enabled, you must call controls.update() in your animation loop + this.enableDamping = false; + this.dampingFactor = 0.25; + + // This option actually enables dollying in and out; left as "zoom" for backwards compatibility. + // Set to false to disable zooming + this.enableZoom = true; + this.zoomSpeed = 1.0; + + // Set to false to disable rotating + this.enableRotate = true; + this.rotateSpeed = 1.0; + + // Set to false to disable panning + this.enablePan = true; + this.panSpeed = 1.0; + this.screenSpacePanning = false; // if true, pan in screen-space + this.keyPanSpeed = 7.0; // pixels moved per arrow key push + + // Set to true to automatically rotate around the target + // If auto-rotate is enabled, you must call controls.update() in your animation loop + this.autoRotate = false; + this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 + + // Set to false to disable use of the keys + this.enableKeys = true; + + // The four arrow keys + this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; + + // Mouse buttons + this.mouseButtons = { LEFT: THREE.MOUSE.LEFT, MIDDLE: THREE.MOUSE.MIDDLE, RIGHT: THREE.MOUSE.RIGHT }; + + // for reset + this.target0 = this.target.clone(); + this.position0 = this.object.position.clone(); + this.zoom0 = this.object.zoom; + + // + // public methods + // + + this.getPolarAngle = function () { + + return spherical.phi; + + }; + + this.getAzimuthalAngle = function () { + + return spherical.theta; + + }; + + this.saveState = function () { + + scope.target0.copy( scope.target ); + scope.position0.copy( scope.object.position ); + scope.zoom0 = scope.object.zoom; + + }; + + this.reset = function () { + + scope.target.copy( scope.target0 ); + scope.object.position.copy( scope.position0 ); + scope.object.zoom = scope.zoom0; + + scope.object.updateProjectionMatrix(); + scope.dispatchEvent( changeEvent ); + + scope.update(); + + state = STATE.NONE; + + }; + + // this method is exposed, but perhaps it would be better if we can make it private... + this.update = function () { + + var offset = new THREE.Vector3(); + + // so camera.up is the orbit axis + var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ); + var quatInverse = quat.clone().inverse(); + + var lastPosition = new THREE.Vector3(); + var lastQuaternion = new THREE.Quaternion(); + + return function update() { + + var position = scope.object.position; + + offset.copy( position ).sub( scope.target ); + + // rotate offset to "y-axis-is-up" space + offset.applyQuaternion( quat ); + + // angle from z-axis around y-axis + spherical.setFromVector3( offset ); + + if ( scope.autoRotate && state === STATE.NONE ) { + + rotateLeft( getAutoRotationAngle() ); + + } + + spherical.theta += sphericalDelta.theta; + spherical.phi += sphericalDelta.phi; + + // restrict theta to be between desired limits + spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) ); + + // restrict phi to be between desired limits + spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) ); + + spherical.makeSafe(); + + + spherical.radius *= scale; + + // restrict radius to be between desired limits + spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); + + // move target to panned location + scope.target.add( panOffset ); + + offset.setFromSpherical( spherical ); + + // rotate offset back to "camera-up-vector-is-up" space + offset.applyQuaternion( quatInverse ); + + position.copy( scope.target ).add( offset ); + + scope.object.lookAt( scope.target ); + + if ( scope.enableDamping === true ) { + + sphericalDelta.theta *= ( 1 - scope.dampingFactor ); + sphericalDelta.phi *= ( 1 - scope.dampingFactor ); + + panOffset.multiplyScalar( 1 - scope.dampingFactor ); + + } else { + + sphericalDelta.set( 0, 0, 0 ); + + panOffset.set( 0, 0, 0 ); + + } + + scale = 1; + + // update condition is: + // min(camera displacement, camera rotation in radians)^2 > EPS + // using small-angle approximation cos(x/2) = 1 - x^2 / 8 + + if ( zoomChanged || + lastPosition.distanceToSquared( scope.object.position ) > EPS || + 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { + + scope.dispatchEvent( changeEvent ); + + lastPosition.copy( scope.object.position ); + lastQuaternion.copy( scope.object.quaternion ); + zoomChanged = false; + + return true; + + } + + return false; + + }; + + }(); + + this.dispose = function () { + + scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false ); + scope.domElement.removeEventListener( 'mousedown', onMouseDown, false ); + scope.domElement.removeEventListener( 'wheel', onMouseWheel, false ); + + scope.domElement.removeEventListener( 'touchstart', onTouchStart, false ); + scope.domElement.removeEventListener( 'touchend', onTouchEnd, false ); + scope.domElement.removeEventListener( 'touchmove', onTouchMove, false ); + + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + + window.removeEventListener( 'keydown', onKeyDown, false ); + + //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? + + }; + + // + // internals + // + + var scope = this; + + var changeEvent = { type: 'change' }; + var startEvent = { type: 'start' }; + var endEvent = { type: 'end' }; + + var STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4 }; + + var state = STATE.NONE; + + var EPS = 0.000001; + + // current position in spherical coordinates + var spherical = new THREE.Spherical(); + var sphericalDelta = new THREE.Spherical(); + + var scale = 1; + var panOffset = new THREE.Vector3(); + var zoomChanged = false; + + var rotateStart = new THREE.Vector2(); + var rotateEnd = new THREE.Vector2(); + var rotateDelta = new THREE.Vector2(); + + var panStart = new THREE.Vector2(); + var panEnd = new THREE.Vector2(); + var panDelta = new THREE.Vector2(); + + var dollyStart = new THREE.Vector2(); + var dollyEnd = new THREE.Vector2(); + var dollyDelta = new THREE.Vector2(); + + function getAutoRotationAngle() { + + return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; + + } + + function getZoomScale() { + + return Math.pow( 0.95, scope.zoomSpeed ); + + } + + function rotateLeft( angle ) { + + sphericalDelta.theta -= angle; + + } + + function rotateUp( angle ) { + + sphericalDelta.phi -= angle; + + } + + var panLeft = function () { + + var v = new THREE.Vector3(); + + return function panLeft( distance, objectMatrix ) { + + v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix + v.multiplyScalar( - distance ); + + panOffset.add( v ); + + }; + + }(); + + var panUp = function () { + + var v = new THREE.Vector3(); + + return function panUp( distance, objectMatrix ) { + + if ( scope.screenSpacePanning === true ) { + + v.setFromMatrixColumn( objectMatrix, 1 ); + + } else { + + v.setFromMatrixColumn( objectMatrix, 0 ); + v.crossVectors( scope.object.up, v ); + + } + + v.multiplyScalar( distance ); + + panOffset.add( v ); + + }; + + }(); + + // deltaX and deltaY are in pixels; right and down are positive + var pan = function () { + + var offset = new THREE.Vector3(); + + return function pan( deltaX, deltaY ) { + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + if ( scope.object.isPerspectiveCamera ) { + + // perspective + var position = scope.object.position; + offset.copy( position ).sub( scope.target ); + var targetDistance = offset.length(); + + // half of the fov is center to top of screen + targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 ); + + // we use only clientHeight here so aspect ratio does not distort speed + panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix ); + panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix ); + + } else if ( scope.object.isOrthographicCamera ) { + + // orthographic + panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix ); + panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix ); + + } else { + + // camera neither orthographic nor perspective + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); + scope.enablePan = false; + + } + + }; + + }(); + + function dollyIn( dollyScale ) { + + if ( scope.object.isPerspectiveCamera ) { + + scale /= dollyScale; + + } else if ( scope.object.isOrthographicCamera ) { + + scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) ); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + scope.enableZoom = false; + + } + + } + + function dollyOut( dollyScale ) { + + if ( scope.object.isPerspectiveCamera ) { + + scale *= dollyScale; + + } else if ( scope.object.isOrthographicCamera ) { + + scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) ); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + scope.enableZoom = false; + + } + + } + + // + // event callbacks - update the object state + // + + function handleMouseDownRotate( event ) { + + //console.log( 'handleMouseDownRotate' ); + + rotateStart.set( event.clientX, event.clientY ); + + } + + function handleMouseDownDolly( event ) { + + //console.log( 'handleMouseDownDolly' ); + + dollyStart.set( event.clientX, event.clientY ); + + } + + function handleMouseDownPan( event ) { + + //console.log( 'handleMouseDownPan' ); + + panStart.set( event.clientX, event.clientY ); + + } + + function handleMouseMoveRotate( event ) { + + //console.log( 'handleMouseMoveRotate' ); + + rotateEnd.set( event.clientX, event.clientY ); + + rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height + + rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); + + rotateStart.copy( rotateEnd ); + + scope.update(); + + } + + function handleMouseMoveDolly( event ) { + + //console.log( 'handleMouseMoveDolly' ); + + dollyEnd.set( event.clientX, event.clientY ); + + dollyDelta.subVectors( dollyEnd, dollyStart ); + + if ( dollyDelta.y > 0 ) { + + dollyIn( getZoomScale() ); + + } else if ( dollyDelta.y < 0 ) { + + dollyOut( getZoomScale() ); + + } + + dollyStart.copy( dollyEnd ); + + scope.update(); + + } + + function handleMouseMovePan( event ) { + + //console.log( 'handleMouseMovePan' ); + + panEnd.set( event.clientX, event.clientY ); + + panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); + + pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + scope.update(); + + } + + function handleMouseUp( event ) { + + // console.log( 'handleMouseUp' ); + + } + + function handleMouseWheel( event ) { + + // console.log( 'handleMouseWheel' ); + + var delta = 0; + + if ( event.deltaY !== undefined ) { + + delta = event.deltaY; + + } else if ( event.wheelDelta !== undefined ) { // WebKit @minorua + + delta = - event.wheelDelta; + + } + + if ( delta < 0 ) { + + dollyOut( getZoomScale() ); + + } else if ( delta > 0 ) { + + dollyIn( getZoomScale() ); + + } + + scope.update(); + + } + + function handleKeyDown( event ) { + + //console.log( 'handleKeyDown' ); + + switch ( event.keyCode ) { + + case scope.keys.UP: + pan( 0, scope.keyPanSpeed ); + scope.update(); + break; + + case scope.keys.BOTTOM: + pan( 0, - scope.keyPanSpeed ); + scope.update(); + break; + + case scope.keys.LEFT: + pan( scope.keyPanSpeed, 0 ); + scope.update(); + break; + + case scope.keys.RIGHT: + pan( - scope.keyPanSpeed, 0 ); + scope.update(); + break; + + } + + } + + function handleTouchStartRotate( event ) { + + //console.log( 'handleTouchStartRotate' ); + + rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + } + + function handleTouchStartDollyPan( event ) { + + //console.log( 'handleTouchStartDollyPan' ); + + if ( scope.enableZoom ) { + + var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; + var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; + + var distance = Math.sqrt( dx * dx + dy * dy ); + + dollyStart.set( 0, distance ); + + } + + if ( scope.enablePan ) { + + var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); + var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); + + panStart.set( x, y ); + + } + + } + + function handleTouchMoveRotate( event ) { + + //console.log( 'handleTouchMoveRotate' ); + + rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height + + rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); + + rotateStart.copy( rotateEnd ); + + scope.update(); + + } + + function handleTouchMoveDollyPan( event ) { + + //console.log( 'handleTouchMoveDollyPan' ); + + if ( scope.enableZoom ) { + + var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; + var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; + + var distance = Math.sqrt( dx * dx + dy * dy ); + + dollyEnd.set( 0, distance ); + + dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) ); + + dollyIn( dollyDelta.y ); + + dollyStart.copy( dollyEnd ); + + } + + if ( scope.enablePan ) { + + var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); + var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); + + panEnd.set( x, y ); + + panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); + + pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + } + + scope.update(); + + } + + function handleTouchEnd( event ) { + + //console.log( 'handleTouchEnd' ); + + } + + // + // event handlers - FSM: listen for events and reset state + // + + function onMouseDown( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + switch ( event.button ) { + + case scope.mouseButtons.LEFT: + + if ( event.ctrlKey || event.metaKey ) { + + if ( scope.enablePan === false ) return; + + handleMouseDownPan( event ); + + state = STATE.PAN; + + } else { + + if ( scope.enableRotate === false ) return; + + handleMouseDownRotate( event ); + + state = STATE.ROTATE; + + } + + break; + + case scope.mouseButtons.MIDDLE: + + if ( scope.enableZoom === false ) return; + + handleMouseDownDolly( event ); + + state = STATE.DOLLY; + + break; + + case scope.mouseButtons.RIGHT: + + if ( scope.enablePan === false ) return; + + handleMouseDownPan( event ); + + state = STATE.PAN; + + break; + + } + + if ( state !== STATE.NONE ) { + + document.addEventListener( 'mousemove', onMouseMove, false ); + document.addEventListener( 'mouseup', onMouseUp, false ); + + scope.dispatchEvent( startEvent ); + + } + + } + + function onMouseMove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + switch ( state ) { + + case STATE.ROTATE: + + if ( scope.enableRotate === false ) return; + + handleMouseMoveRotate( event ); + + break; + + case STATE.DOLLY: + + if ( scope.enableZoom === false ) return; + + handleMouseMoveDolly( event ); + + break; + + case STATE.PAN: + + if ( scope.enablePan === false ) return; + + handleMouseMovePan( event ); + + break; + + } + + } + + function onMouseUp( event ) { + + if ( scope.enabled === false ) return; + + handleMouseUp( event ); + + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + + scope.dispatchEvent( endEvent ); + + state = STATE.NONE; + + } + + function onMouseWheel( event ) { + + if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return; + + event.preventDefault(); + event.stopPropagation(); + + scope.dispatchEvent( startEvent ); + + handleMouseWheel( event ); + + scope.dispatchEvent( endEvent ); + + } + + function onKeyDown( event ) { + + if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return; + + handleKeyDown( event ); + + } + + function onTouchStart( event ) { + + if ( scope.enabled === false ) return; + + // event.preventDefault(); // comment out @minorua + + switch ( event.touches.length ) { + + case 1: // one-fingered touch: rotate + + if ( scope.enableRotate === false ) return; + + handleTouchStartRotate( event ); + + state = STATE.TOUCH_ROTATE; + + break; + + case 2: // two-fingered touch: dolly-pan + + if ( scope.enableZoom === false && scope.enablePan === false ) return; + + handleTouchStartDollyPan( event ); + + state = STATE.TOUCH_DOLLY_PAN; + + break; + + default: + + state = STATE.NONE; + + } + + if ( state !== STATE.NONE ) { + + scope.dispatchEvent( startEvent ); + + } + + } + + function onTouchMove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + event.stopPropagation(); + + switch ( event.touches.length ) { + + case 1: // one-fingered touch: rotate + + if ( scope.enableRotate === false ) return; + if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed? + + handleTouchMoveRotate( event ); + + break; + + case 2: // two-fingered touch: dolly-pan + + if ( scope.enableZoom === false && scope.enablePan === false ) return; + if ( state !== STATE.TOUCH_DOLLY_PAN ) return; // is this needed? + + handleTouchMoveDollyPan( event ); + + break; + + default: + + state = STATE.NONE; + + } + + } + + function onTouchEnd( event ) { + + if ( scope.enabled === false ) return; + + handleTouchEnd( event ); + + scope.dispatchEvent( endEvent ); + + state = STATE.NONE; + + } + + function onContextMenu( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + } + + // expose functions @minorua + this.panLeft = panLeft; + this.rotateLeft = rotateLeft; + this.rotateUp = rotateUp; + this.dollyIn = dollyIn; + this.dollyOut = dollyOut; + this.getZoomScale = getZoomScale; + + // + + scope.domElement.addEventListener( 'contextmenu', onContextMenu, false ); + + scope.domElement.addEventListener( 'mousedown', onMouseDown, false ); + scope.domElement.addEventListener( 'wheel', onMouseWheel, false ); + scope.domElement.addEventListener( 'mousewheel', onMouseWheel, false ); // WebKit @minorua + + scope.domElement.addEventListener( 'touchstart', onTouchStart, false ); + scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); + scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); + + window.addEventListener( 'keydown', onKeyDown, false ); + + // force an update at start + + this.update(); + +}; + +THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); +THREE.OrbitControls.prototype.constructor = THREE.OrbitControls; + +Object.defineProperties( THREE.OrbitControls.prototype, { + + center: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .center has been renamed to .target' ); + return this.target; + + } + + }, + + // backward compatibility + + noZoom: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); + return ! this.enableZoom; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); + this.enableZoom = ! value; + + } + + }, + + noRotate: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); + return ! this.enableRotate; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); + this.enableRotate = ! value; + + } + + }, + + noPan: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); + return ! this.enablePan; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); + this.enablePan = ! value; + + } + + }, + + noKeys: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); + return ! this.enableKeys; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); + this.enableKeys = ! value; + + } + + }, + + staticMoving: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); + return ! this.enableDamping; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); + this.enableDamping = ! value; + + } + + }, + + dynamicDampingFactor: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); + return this.dampingFactor; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); + this.dampingFactor = value; + + } + + } + +} ); diff --git a/docs/examples/24/threejs/three.min.js b/docs/examples/24/threejs/three.min.js new file mode 100644 index 00000000..af2a3848 --- /dev/null +++ b/docs/examples/24/threejs/three.min.js @@ -0,0 +1,996 @@ +// threejs.org/license +(function(k,xa){"object"===typeof exports&&"undefined"!==typeof module?xa(exports):"function"===typeof define&&define.amd?define(["exports"],xa):(k=k||self,xa(k.THREE={}))})(this,function(k){function xa(){}function v(a,b){this.x=a||0;this.y=b||0}function na(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._w=void 0!==d?d:1}function n(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}function ta(){this.elements=[1,0,0,0,1,0,0,0,1];0h)return!1}return!0}function nb(a,b){this.center=void 0!==a?a:new n;this.radius=void 0!==b?b:0}function Sb(a,b){this.origin=void 0!==a?a:new n;this.direction=void 0!==b?b:new n}function ia(a,b,c){this.a=void 0!==a?a:new n;this.b=void 0!==b?b:new n;this.c=void 0!==c?c:new n}function J(a,b,c){return void 0===b&&void 0=== +c?this.set(a):this.setRGB(a,b,c)}function Sf(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a}function Tf(a){return.04045>a?.0773993808*a:Math.pow(.9478672986*a+.0521327014,2.4)}function Uf(a){return.0031308>a?12.92*a:1.055*Math.pow(a,.41666)-.055}function yc(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d&&d.isVector3?d:new n;this.vertexNormals=Array.isArray(d)?d:[];this.color=e&&e.isColor?e:new J;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex= +void 0!==f?f:0}function Q(){Object.defineProperty(this,"id",{value:Ni++});this.uuid=O.generateUUID();this.name="";this.type="Material";this.lights=this.fog=!0;this.blending=1;this.side=0;this.vertexTangents=this.flatShading=!1;this.vertexColors=0;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=3;this.depthWrite=this.depthTest=!0;this.stencilFunc=519;this.stencilRef=0;this.stencilMask= +255;this.stencilZPass=this.stencilZFail=this.stencilFail=7680;this.stencilWrite=!1;this.clippingPlanes=null;this.clipShadows=this.clipIntersection=!1;this.shadowSide=null;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1;this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.dithering=!1;this.alphaTest=0;this.premultipliedAlpha=!1;this.toneMapped=this.visible=!0;this.userData={};this.needsUpdate=!0}function ya(a){Q.call(this);this.type="MeshBasicMaterial";this.color=new J(16777215);this.lightMap= +this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.lights=this.morphTargets=this.skinning=!1;this.setValues(a)}function N(a,b,c){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.name="";this.array=a;this.itemSize= +b;this.count=void 0!==a?a.length/b:0;this.normalized=!0===c;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0}function xd(a,b,c){N.call(this,new Int8Array(a),b,c)}function yd(a,b,c){N.call(this,new Uint8Array(a),b,c)}function zd(a,b,c){N.call(this,new Uint8ClampedArray(a),b,c)}function Ad(a,b,c){N.call(this,new Int16Array(a),b,c)}function Tb(a,b,c){N.call(this,new Uint16Array(a),b,c)}function Bd(a,b,c){N.call(this,new Int32Array(a),b,c)}function Ub(a,b,c){N.call(this,new Uint32Array(a), +b,c)}function A(a,b,c){N.call(this,new Float32Array(a),b,c)}function Cd(a,b,c){N.call(this,new Float64Array(a),b,c)}function dh(){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}function eh(a){if(0===a.length)return-Infinity;for(var b=a[0],c=1,d= +a.length;cb&&(b=a[c]);return b}function D(){Object.defineProperty(this,"id",{value:Oi+=2});this.uuid=O.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};this.userData={}}function ra(a,b){B.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new D;this.material=void 0!==b?b:new ya({color:16777215*Math.random()});this.drawMode= +0;this.updateMorphTargets()}function fh(a,b,c,d,e,f,g,h){if(null===(1===b.side?d.intersectTriangle(g,f,e,!0,h):d.intersectTriangle(e,f,g,2!==b.side,h)))return null;De.copy(h);De.applyMatrix4(a.matrixWorld);b=c.ray.origin.distanceTo(De);return bc.far?null:{distance:b,point:De.clone(),object:a}}function Ee(a,b,c,d,e,f,g,h,l,m,p){Vb.fromBufferAttribute(e,l);Wb.fromBufferAttribute(e,m);Xb.fromBufferAttribute(e,p);e=a.morphTargetInfluences;if(b.morphTargets&&f&&e){Vf.set(0,0,0);Wf.set(0,0,0); +Xf.set(0,0,0);for(var u=0,r=f.length;ug;g++)a.setRenderTarget(f,g),a.clear(b,c,d);a.setRenderTarget(e)}}function Cb(a,b,c){Ka.call(this,a,b,c)}function Zb(a,b,c,d,e,f,g,h,l,m,p,u){ba.call(this,null,f,g,h,l,m,d,e,p,u);this.image={data:a,width:b,height:c};this.magFilter=void 0!==l?l:1003;this.minFilter=void 0!==m?m:1003;this.flipY=this.generateMipmaps=!1;this.unpackAlignment=1}function cb(a,b){this.normal=void 0!==a?a:new n(1,0,0);this.constant=void 0!==b?b:0}function Ed(a,b,c,d,e,f){this.planes=[void 0!==a?a: +new cb,void 0!==b?b:new cb,void 0!==c?c:new cb,void 0!==d?d:new cb,void 0!==e?e:new cb,void 0!==f?f:new cb]}function Zf(){function a(e,f){!1!==c&&(d(e,f),b.requestAnimationFrame(a))}var b=null,c=!1,d=null;return{start:function(){!0!==c&&null!==d&&(b.requestAnimationFrame(a),c=!0)},stop:function(){c=!1},setAnimationLoop:function(a){d=a},setContext:function(a){b=a}}}function Qi(a){function b(b,c){var d=b.array,e=b.dynamic?35048:35044,h=a.createBuffer();a.bindBuffer(c,h);a.bufferData(c,d,e);b.onUploadCallback(); +c=5126;d instanceof Float32Array?c=5126:d instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):d instanceof Uint16Array?c=5123:d instanceof Int16Array?c=5122:d instanceof Uint32Array?c=5125:d instanceof Int32Array?c=5124:d instanceof Int8Array?c=5120:d instanceof Uint8Array&&(c=5121);return{buffer:h,type:c,bytesPerElement:d.BYTES_PER_ELEMENT,version:b.version}}var c=new WeakMap;return{get:function(a){a.isInterleavedBufferAttribute&&(a=a.data); +return c.get(a)},remove:function(b){b.isInterleavedBufferAttribute&&(b=b.data);var d=c.get(b);d&&(a.deleteBuffer(d.buffer),c.delete(b))},update:function(d,e){d.isInterleavedBufferAttribute&&(d=d.data);var f=c.get(d);if(void 0===f)c.set(d,b(d,e));else if(f.versionm;m++){if(u=d[m])if(h=u[0],l=u[1]){p&&e.addAttribute("morphTarget"+m,p[h]);f&&e.addAttribute("morphNormal"+m,f[h]);c[m]=l;continue}c[m]=0}g.getUniforms().setValue(a,"morphTargetInfluences",c)}}}function aj(a,b){var c= +{};return{update:function(d){var e=b.render.frame,f=d.geometry,g=a.get(d,f);c[g.id]!==e&&(f.isGeometry&&g.updateFromObject(d),a.update(g),c[g.id]=e);return g},dispose:function(){c={}}}}function pb(a,b,c,d,e,f,g,h,l,m){a=void 0!==a?a:[];ba.call(this,a,void 0!==b?b:301,c,d,e,f,void 0!==g?g:1022,h,l,m);this.flipY=!1}function Ec(a,b,c,d){ba.call(this,null);this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Fc(a,b, +c,d){ba.call(this,null);this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Gc(a,b,c){var d=a[0];if(0>=d||0/gm, +function(a,c){a=K[c];if(void 0===a)throw Error("Can not resolve #include <"+c+">");return ag(a)})}function zh(a){return a.replace(/#pragma unroll_loop[\s]+?for \( int i = (\d+); i < (\d+); i \+\+ \) \{([\s\S]+?)(?=\})\}/g,function(a,c,d,e){a="";for(c=parseInt(c);cc;c++)b.probe.push(new n);var d=new n,e=new P,f=new P;return{setup:function(c,h,l){for(var g=0,p=0,u=0,k=0;9>k;k++)b.probe[k].set(0,0,0);var q=h=0,t=0,y=0,n=0,z=0,x=0,C=0;l=l.matrixWorldInverse;c.sort(Uj);k=0;for(var W=c.length;kCa;Ca++)b.probe[Ca].addScaledVector(E.sh.coefficients[Ca],v);else if(E.isDirectionalLight){var I=a.get(E);I.color.copy(E.color).multiplyScalar(E.intensity);I.direction.setFromMatrixPosition(E.matrixWorld);d.setFromMatrixPosition(E.target.matrixWorld);I.direction.sub(d);I.direction.transformDirection(l);if(I.shadow=E.castShadow)v=E.shadow,I.shadowBias=v.bias,I.shadowRadius=v.radius,I.shadowMapSize=v.mapSize,b.directionalShadowMap[h]=Ca,b.directionalShadowMatrix[h]= +E.shadow.matrix,z++;b.directional[h]=I;h++}else if(E.isSpotLight){I=a.get(E);I.position.setFromMatrixPosition(E.matrixWorld);I.position.applyMatrix4(l);I.color.copy(Fa).multiplyScalar(v);I.distance=A;I.direction.setFromMatrixPosition(E.matrixWorld);d.setFromMatrixPosition(E.target.matrixWorld);I.direction.sub(d);I.direction.transformDirection(l);I.coneCos=Math.cos(E.angle);I.penumbraCos=Math.cos(E.angle*(1-E.penumbra));I.decay=E.decay;if(I.shadow=E.castShadow)v=E.shadow,I.shadowBias=v.bias,I.shadowRadius= +v.radius,I.shadowMapSize=v.mapSize,b.spotShadowMap[t]=Ca,b.spotShadowMatrix[t]=E.shadow.matrix,C++;b.spot[t]=I;t++}else if(E.isRectAreaLight)I=a.get(E),I.color.copy(Fa).multiplyScalar(v),I.position.setFromMatrixPosition(E.matrixWorld),I.position.applyMatrix4(l),f.identity(),e.copy(E.matrixWorld),e.premultiply(l),f.extractRotation(e),I.halfWidth.set(.5*E.width,0,0),I.halfHeight.set(0,.5*E.height,0),I.halfWidth.applyMatrix4(f),I.halfHeight.applyMatrix4(f),b.rectArea[y]=I,y++;else if(E.isPointLight){I= +a.get(E);I.position.setFromMatrixPosition(E.matrixWorld);I.position.applyMatrix4(l);I.color.copy(E.color).multiplyScalar(E.intensity);I.distance=E.distance;I.decay=E.decay;if(I.shadow=E.castShadow)v=E.shadow,I.shadowBias=v.bias,I.shadowRadius=v.radius,I.shadowMapSize=v.mapSize,I.shadowCameraNear=v.camera.near,I.shadowCameraFar=v.camera.far,b.pointShadowMap[q]=Ca,b.pointShadowMatrix[q]=E.shadow.matrix,x++;b.point[q]=I;q++}else E.isHemisphereLight&&(I=a.get(E),I.direction.setFromMatrixPosition(E.matrixWorld), +I.direction.transformDirection(l),I.direction.normalize(),I.skyColor.copy(E.color).multiplyScalar(v),I.groundColor.copy(E.groundColor).multiplyScalar(v),b.hemi[n]=I,n++)}b.ambient[0]=g;b.ambient[1]=p;b.ambient[2]=u;c=b.hash;if(c.directionalLength!==h||c.pointLength!==q||c.spotLength!==t||c.rectAreaLength!==y||c.hemiLength!==n||c.numDirectionalShadows!==z||c.numPointShadows!==x||c.numSpotShadows!==C)b.directional.length=h,b.spot.length=t,b.rectArea.length=y,b.point.length=q,b.hemi.length=n,b.directionalShadowMap.length= +z,b.pointShadowMap.length=x,b.spotShadowMap.length=C,b.directionalShadowMatrix.length=z,b.pointShadowMatrix.length=x,b.spotShadowMatrix.length=C,c.directionalLength=h,c.pointLength=q,c.spotLength=t,c.rectAreaLength=y,c.hemiLength=n,c.numDirectionalShadows=z,c.numPointShadows=x,c.numSpotShadows=C,b.version=Wj++},state:b}}function Bh(){var a=new Vj,b=[],c=[];return{init:function(){b.length=0;c.length=0},state:{lightsArray:b,shadowsArray:c,lights:a},setupLights:function(d){a.setup(b,c,d)},pushLight:function(a){b.push(a)}, +pushShadow:function(a){c.push(a)}}}function Xj(){function a(c){c=c.target;c.removeEventListener("dispose",a);b.delete(c)}var b=new WeakMap;return{get:function(c,d){if(!1===b.has(c)){var e=new Bh;b.set(c,new WeakMap);b.get(c).set(d,e);c.addEventListener("dispose",a)}else!1===b.get(c).has(d)?(e=new Bh,b.get(c).set(d,e)):e=b.get(c).get(d);return e},dispose:function(){b=new WeakMap}}}function Eb(a){Q.call(this);this.type="MeshDepthMaterial";this.depthPacking=3200;this.morphTargets=this.skinning=!1;this.displacementMap= +this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.lights=this.fog=!1;this.setValues(a)}function Fb(a){Q.call(this);this.type="MeshDistanceMaterial";this.referencePosition=new n;this.nearDistance=1;this.farDistance=1E3;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.lights=this.fog=!1;this.setValues(a)}function Ch(a,b,c){function d(b, +c,d,e,f,g){var h=b.geometry;var l=m;var r=b.customDepthMaterial;d.isPointLight&&(l=p,r=b.customDistanceMaterial);r?l=r:(r=!1,c.morphTargets&&(h&&h.isBufferGeometry?r=h.morphAttributes&&h.morphAttributes.position&&0\nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\n \n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n for ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n #ifdef HORIZONAL_PASS\n vec2 distribution = decodeHalfRGBA ( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n mean += distribution.x;\n squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n #else\n float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean * HALF_SAMPLE_RATE;\n squared_mean = squared_mean * HALF_SAMPLE_RATE;\n float std_dev = pow( squared_mean - mean * mean, 0.5 );\n gl_FragColor = encodeHalfRGBA( vec2( mean, std_dev ) );\n}"}), +t=q.clone();t.defines.HORIZONAL_PASS=1;var n=new D;n.addAttribute("position",new N(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));var w=new ra(n,q);for(n=0;4!==n;++n){var z=0!==(n&1),x=0!==(n&2),C=new Eb({depthPacking:3201,morphTargets:z,skinning:x});m[n]=C;z=new Fb({morphTargets:z,skinning:x});p[n]=z}var W=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=1;this.render=function(d,m,p){if(!1!==W.enabled&&(!1!==W.autoUpdate||!1!==W.needsUpdate)&&0!==d.length){var u=a.getRenderTarget(), +k=a.getActiveCubeFace(),r=a.getActiveMipmapLevel(),n=a.state;n.setBlending(0);n.buffers.color.setClear(1,1,1,1);n.buffers.depth.setTest(!0);n.setScissorTest(!1);for(var y=0,x=d.length;yc||g.y>c)console.warn("THREE.WebGLShadowMap:",C,"has shadow exceeding max texture size, reducing"),g.x>c&&(h.x=Math.floor(c/U.x), +g.x=h.x*U.x,S.mapSize.x=h.x),g.y>c&&(h.y=Math.floor(c/U.y),g.y=h.y*U.y,S.mapSize.y=h.y);null!==S.map||S.isPointLightShadow||3!==this.type||(U={minFilter:1006,magFilter:1006,format:1023},S.map=new Ka(g.x,g.y,U),S.map.texture.name=C.name+".shadowMap",S.mapPass=new Ka(g.x,g.y,U),S.camera.updateProjectionMatrix());null===S.map&&(U={minFilter:1003,magFilter:1003,format:1023},S.map=new Ka(g.x,g.y,U),S.map.texture.name=C.name+".shadowMap",S.camera.updateProjectionMatrix());a.setRenderTarget(S.map);a.clear(); +U=S.getViewportCount();for(var z=0;zd||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof HTMLImageElement||"undefined"!==typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?O.floorPowerOfTwo: +Math.floor,b=d(e*a.width),e=d(e*a.height),void 0===I&&(I=h(b,e)),c=c?h(b,e):I,c.width=b,c.height=e,c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+b+"x"+e+")."),c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+").")}return a}function m(a){return O.isPowerOfTwo(a.width)&&O.isPowerOfTwo(a.height)}function p(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&& +1006!==a.minFilter}function u(b,c,e,f){a.generateMipmap(b);d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function k(a,c){if(!e.isWebGL2)return a;var d=a;6403===a&&(5126===c&&(d=33326),5131===c&&(d=33325),5121===c&&(d=33321));6407===a&&(5126===c&&(d=34837),5131===c&&(d=34843),5121===c&&(d=32849));6408===a&&(5126===c&&(d=34836),5131===c&&(d=34842),5121===c&&(d=32856));33325===d||33326===d||34842===d||34836===d?b.get("EXT_color_buffer_float"):(34843===d||34837===d)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead."); +return d}function q(a){return 1003===a||1004===a||1005===a?9728:9729}function t(b){b=b.target;b.removeEventListener("dispose",t);var c=d.get(b);void 0!==c.__webglInit&&(a.deleteTexture(c.__webglTexture),d.remove(b));b.isVideoTexture&&Ca.delete(b);g.memory.textures--}function n(b){b=b.target;b.removeEventListener("dispose",n);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e= +0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);d.remove(b.texture);d.remove(b)}g.memory.textures--}function w(a,b){var e=d.get(a);if(a.isVideoTexture){var f=g.render.frame;Ca.get(a)!==f&&(Ca.set(a,f),a.update())}if(0q;q++)t[q]=r||g?g?b.image[q].image: +b.image[q]:l(b.image[q],!1,!0,e.maxCubemapSize);var n=t[0],y=m(n)||e.isWebGL2,w=f.convert(b.format),x=f.convert(b.type),U=k(w,x);C(34067,b,y);if(r){for(q=0;6>q;q++){var S=t[q].mipmaps;for(r=0;rq;q++)if(g)for(c.texImage2D(34069+q,0,U,t[q].width,t[q].height,0,w,x,t[q].data),r=0;r=e.maxTextures&&console.warn("THREE.WebGLTextures: Trying to use "+a+" texture units while this GPU supports only "+e.maxTextures);H+=1;return a};this.resetTextureUnits=function(){H=0};this.setTexture2D=w;this.setTexture2DArray=function(a,b){var e=d.get(a);0q;q++)h.__webglFramebuffer[q]=a.createFramebuffer();else if(h.__webglFramebuffer=a.createFramebuffer(),q)if(e.isWebGL2){h.__webglMultisampledFramebuffer=a.createFramebuffer();h.__webglColorRenderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,h.__webglColorRenderbuffer);q=f.convert(b.texture.format);var y=f.convert(b.texture.type);q=k(q,y);y=B(b);a.renderbufferStorageMultisample(36161,y,q,b.width,b.height);a.bindFramebuffer(36160,h.__webglMultisampledFramebuffer); +a.framebufferRenderbuffer(36160,36064,36161,h.__webglColorRenderbuffer);a.bindRenderbuffer(36161,null);b.depthBuffer&&(h.__webglDepthRenderbuffer=a.createRenderbuffer(),A(h.__webglDepthRenderbuffer,b,!0));a.bindFramebuffer(36160,null)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.");if(r){c.bindTexture(34067,l.__webglTexture);C(34067,b.texture,t);for(q=0;6>q;q++)v(h.__webglFramebuffer[q],b,36064,34069+q);p(b.texture,t)&&u(34067,b.texture,b.width, +b.height);c.bindTexture(34067,null)}else c.bindTexture(3553,l.__webglTexture),C(3553,b.texture,t),v(h.__webglFramebuffer,b,36064,3553),p(b.texture,t)&&u(3553,b.texture,b.width,b.height),c.bindTexture(3553,null);if(b.depthBuffer){h=d.get(b);l=!0===b.isWebGLRenderTargetCube;if(b.depthTexture){if(l)throw Error("target.depthTexture not supported in Cube render targets");if(b&&b.isWebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported");a.bindFramebuffer(36160,h.__webglFramebuffer); +if(!b.depthTexture||!b.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(b.depthTexture).__webglTexture&&b.depthTexture.image.width===b.width&&b.depthTexture.image.height===b.height||(b.depthTexture.image.width=b.width,b.depthTexture.image.height=b.height,b.depthTexture.needsUpdate=!0);w(b.depthTexture,0);h=d.get(b.depthTexture).__webglTexture;if(1026===b.depthTexture.format)a.framebufferTexture2D(36160,36096,3553,h,0);else if(1027=== +b.depthTexture.format)a.framebufferTexture2D(36160,33306,3553,h,0);else throw Error("Unknown depthTexture format");}else if(l)for(h.__webglDepthbuffer=[],l=0;6>l;l++)a.bindFramebuffer(36160,h.__webglFramebuffer[l]),h.__webglDepthbuffer[l]=a.createRenderbuffer(),A(h.__webglDepthbuffer[l],b);else a.bindFramebuffer(36160,h.__webglFramebuffer),h.__webglDepthbuffer=a.createRenderbuffer(),A(h.__webglDepthbuffer,b);a.bindFramebuffer(36160,null)}};this.updateRenderTargetMipmap=function(a){var b=a.texture, +f=m(a)||e.isWebGL2;if(p(b,f)){f=a.isWebGLRenderTargetCube?34067:3553;var g=d.get(b).__webglTexture;c.bindTexture(f,g);u(f,b,a.width,a.height);c.bindTexture(f,null)}};this.updateMultisampleRenderTarget=function(b){if(b.isWebGLMultisampleRenderTarget)if(e.isWebGL2){var c=d.get(b);a.bindFramebuffer(36008,c.__webglMultisampledFramebuffer);a.bindFramebuffer(36009,c.__webglFramebuffer);c=b.width;var f=b.height,g=16384;b.depthBuffer&&(g|=256);b.stencilBuffer&&(g|=1024);a.blitFramebuffer(0,0,c,f,0,0,c,f, +g,9728)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.")};this.safeSetTexture2D=function(a,b){a&&a.isWebGLRenderTarget&&(!1===J&&(console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."),J=!0),a=a.texture);w(a,b)};this.safeSetTextureCube=function(a,b){a&&a.isWebGLRenderTargetCube&&(!1===F&&(console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."), +F=!0),a=a.texture);a&&a.isCubeTexture||Array.isArray(a.image)&&6===a.image.length?z(a,b):x(a,b)}}function Eh(a,b,c){return{convert:function(a){if(1E3===a)return 10497;if(1001===a)return 33071;if(1002===a)return 33648;if(1003===a)return 9728;if(1004===a)return 9984;if(1005===a)return 9986;if(1006===a)return 9729;if(1007===a)return 9985;if(1008===a)return 9987;if(1009===a)return 5121;if(1017===a)return 32819;if(1018===a)return 32820;if(1019===a)return 33635;if(1010===a)return 5120;if(1011===a)return 5122; +if(1012===a)return 5123;if(1013===a)return 5124;if(1014===a)return 5125;if(1015===a)return 5126;if(1016===a){if(c.isWebGL2)return 5131;var d=b.get("OES_texture_half_float");if(null!==d)return d.HALF_FLOAT_OES}if(1021===a)return 6406;if(1022===a)return 6407;if(1023===a)return 6408;if(1024===a)return 6409;if(1025===a)return 6410;if(1026===a)return 6402;if(1027===a)return 34041;if(1028===a)return 6403;if(100===a)return 32774;if(101===a)return 32778;if(102===a)return 32779;if(200===a)return 0;if(201=== +a)return 1;if(202===a)return 768;if(203===a)return 769;if(204===a)return 770;if(205===a)return 771;if(206===a)return 772;if(207===a)return 773;if(208===a)return 774;if(209===a)return 775;if(210===a)return 776;if(33776===a||33777===a||33778===a||33779===a)if(d=b.get("WEBGL_compressed_texture_s3tc"),null!==d){if(33776===a)return d.COMPRESSED_RGB_S3TC_DXT1_EXT;if(33777===a)return d.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(33778===a)return d.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(33779===a)return d.COMPRESSED_RGBA_S3TC_DXT5_EXT}if(35840=== +a||35841===a||35842===a||35843===a)if(d=b.get("WEBGL_compressed_texture_pvrtc"),null!==d){if(35840===a)return d.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(35841===a)return d.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(35842===a)return d.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(35843===a)return d.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(36196===a&&(d=b.get("WEBGL_compressed_texture_etc1"),null!==d))return d.COMPRESSED_RGB_ETC1_WEBGL;if(37808===a||37809===a||37810===a||37811===a||37812===a||37813===a||37814===a||37815===a||37816=== +a||37817===a||37818===a||37819===a||37820===a||37821===a)if(d=b.get("WEBGL_compressed_texture_astc"),null!==d)return a;if(103===a||104===a){if(c.isWebGL2){if(103===a)return 32775;if(104===a)return 32776}d=b.get("EXT_blend_minmax");if(null!==d){if(103===a)return d.MIN_EXT;if(104===a)return d.MAX_EXT}}if(1020===a){if(c.isWebGL2)return 34042;d=b.get("WEBGL_depth_texture");if(null!==d)return d.UNSIGNED_INT_24_8_WEBGL}return 0}}}function Hc(){B.call(this);this.type="Group"}function Id(a){la.call(this); +this.cameras=a||[]}function Fh(a,b,c){Gh.setFromMatrixPosition(b.matrixWorld);Hh.setFromMatrixPosition(c.matrixWorld);var d=Gh.distanceTo(Hh),e=b.projectionMatrix.elements,f=c.projectionMatrix.elements,g=e[14]/(e[10]-1);c=e[14]/(e[10]+1);var h=(e[9]+1)/e[5],l=(e[9]-1)/e[5],m=(e[8]-1)/e[0],p=(f[8]+1)/f[0];e=g*m;f=g*p;p=d/(-m+p);m=p*-m;b.matrixWorld.decompose(a.position,a.quaternion,a.scale);a.translateX(m);a.translateZ(p);a.matrixWorld.compose(a.position,a.quaternion,a.scale);a.matrixWorldInverse.getInverse(a.matrixWorld); +b=g+p;g=c+p;a.projectionMatrix.makePerspective(e-m,f+(d-m),h*c/g*b,l*c/g*b,b,g)}function cg(a){function b(){return null!==h&&!0===h.isPresenting}function c(){if(b()){var c=h.getEyeParameters("left");e=2*c.renderWidth*q;f=c.renderHeight*q;Fa=a.getPixelRatio();a.getSize(E);a.setDrawingBufferSize(e,f,1);x.viewport.set(0,0,e/2,f);C.viewport.set(e/2,0,e/2,f);B.start();g.dispatchEvent({type:"sessionstart"})}else g.enabled&&a.setDrawingBufferSize(E.width,E.height,Fa),B.stop(),g.dispatchEvent({type:"sessionend"})} +function d(a,b){null!==b&&4===b.length&&a.set(b[0]*e,b[1]*f,b[2]*e,b[3]*f)}var e,f,g=this,h=null,l=null,m=null,p=[],u=new P,k=new P,q=1,t="local-floor";"undefined"!==typeof window&&"VRFrameData"in window&&(l=new window.VRFrameData,window.addEventListener("vrdisplaypresentchange",c,!1));var y=new P,w=new na,z=new n,x=new la;x.viewport=new da;x.layers.enable(1);var C=new la;C.viewport=new da;C.layers.enable(2);var W=new Id([x,C]);W.layers.enable(1);W.layers.enable(2);var E=new v,Fa,A=[];this.enabled= +!1;this.getController=function(a){var b=p[a];void 0===b&&(b=new Hc,b.matrixAutoUpdate=!1,b.visible=!1,p[a]=b);return b};this.getDevice=function(){return h};this.setDevice=function(a){void 0!==a&&(h=a);B.setContext(a)};this.setFramebufferScaleFactor=function(a){q=a};this.setReferenceSpaceType=function(a){t=a};this.setPoseTarget=function(a){void 0!==a&&(m=a)};this.getCamera=function(a){var c="local-floor"===t?1.6:0;if(!1===b())return a.position.set(0,c,0),a.rotation.set(0,0,0),a;h.depthNear=a.near; +h.depthFar=a.far;h.getFrameData(l);if("local-floor"===t){var e=h.stageParameters;e?u.fromArray(e.sittingToStandingTransform):u.makeTranslation(0,c,0)}c=l.pose;e=null!==m?m:a;e.matrix.copy(u);e.matrix.decompose(e.position,e.quaternion,e.scale);null!==c.orientation&&(w.fromArray(c.orientation),e.quaternion.multiply(w));null!==c.position&&(w.setFromRotationMatrix(u),z.fromArray(c.position),z.applyQuaternion(w),e.position.add(z));e.updateMatrixWorld();x.near=a.near;C.near=a.near;x.far=a.far;C.far=a.far; +x.matrixWorldInverse.fromArray(l.leftViewMatrix);C.matrixWorldInverse.fromArray(l.rightViewMatrix);k.getInverse(u);"local-floor"===t&&(x.matrixWorldInverse.multiply(k),C.matrixWorldInverse.multiply(k));a=e.parent;null!==a&&(y.getInverse(a.matrixWorld),x.matrixWorldInverse.multiply(y),C.matrixWorldInverse.multiply(y));x.matrixWorld.getInverse(x.matrixWorldInverse);C.matrixWorld.getInverse(C.matrixWorldInverse);x.projectionMatrix.fromArray(l.leftProjectionMatrix);C.projectionMatrix.fromArray(l.rightProjectionMatrix); +Fh(W,x,C);a=h.getLayers();a.length&&(a=a[0],d(x.viewport,a.leftBounds),d(C.viewport,a.rightBounds));a:for(a=0;af.matrixWorld.determinant();ha.setMaterial(e,h);var l=r(a,c,e,f),m=!1;if(b!==d.id||Y!==l.id||ba!==(!0===e.wireframe))b=d.id,Y=l.id,ba=!0===e.wireframe,m=!0;f.morphTargetInfluences&&(xa.update(f,d,e,l), +m=!0);h=d.index;var p=d.attributes.position;c=1;!0===e.wireframe&&(h=wa.getWireframeAttribute(d),c=2);a=za;if(null!==h){var k=ua.get(h);a=Ba;a.setIndex(k)}if(m){if(d&&d.isInstancedBufferGeometry&&!Ea.isWebGL2&&null===oa.get("ANGLE_instanced_arrays"))console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");else{ha.initAttributes();m=d.attributes;l=l.getAttributes();var u=e.defaultAttributeValues; +for(v in l){var q=l[v];if(0<=q){var t=m[v];if(void 0!==t){var n=t.normalized,y=t.itemSize,w=ua.get(t);if(void 0!==w){var x=w.buffer,z=w.type;w=w.bytesPerElement;if(t.isInterleavedBufferAttribute){var C=t.data,E=C.stride;t=t.offset;C&&C.isInstancedInterleavedBuffer?(ha.enableAttributeAndDivisor(q,C.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=C.meshPerAttribute*C.count)):ha.enableAttribute(q);M.bindBuffer(34962,x);M.vertexAttribPointer(q,y,z,n,E*w,t*w)}else t.isInstancedBufferAttribute? +(ha.enableAttributeAndDivisor(q,t.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=t.meshPerAttribute*t.count)):ha.enableAttribute(q),M.bindBuffer(34962,x),M.vertexAttribPointer(q,y,z,n,0,0)}}else if(void 0!==u&&(n=u[v],void 0!==n))switch(n.length){case 2:M.vertexAttrib2fv(q,n);break;case 3:M.vertexAttrib3fv(q,n);break;case 4:M.vertexAttrib4fv(q,n);break;default:M.vertexAttrib1fv(q,n)}}}ha.disableUnusedAttributes()}null!==h&&M.bindBuffer(34963,k.buffer)}k=Infinity;null!==h?k=h.count: +void 0!==p&&(k=p.count);h=d.drawRange.start*c;p=null!==g?g.start*c:0;var v=Math.max(h,p);g=Math.max(0,Math.min(k,h+d.drawRange.count*c,p+(null!==g?g.count*c:Infinity))-1-v+1);if(0!==g){if(f.isMesh)if(!0===e.wireframe)ha.setLineWidth(e.wireframeLinewidth*(null===K?fa:1)),a.setMode(1);else switch(f.drawMode){case 0:a.setMode(4);break;case 1:a.setMode(5);break;case 2:a.setMode(6)}else f.isLine?(e=e.linewidth,void 0===e&&(e=1),ha.setLineWidth(e*(null===K?fa:1)),f.isLineSegments?a.setMode(1):f.isLineLoop? +a.setMode(2):a.setMode(3)):f.isPoints?a.setMode(0):f.isSprite&&a.setMode(4);d&&d.isInstancedBufferGeometry?0e.far||f.push({distance:a,distanceToRay:Math.sqrt(h), +point:c,index:b,face:null,object:g}))}function hg(a,b,c,d,e,f,g,h,l){ba.call(this,a,b,c,d,e,f,g,h,l);this.format=void 0!==g?g:1022;this.minFilter=void 0!==f?f:1006;this.magFilter=void 0!==e?e:1006;this.generateMipmaps=!1}function Lc(a,b,c,d,e,f,g,h,l,m,p,k){ba.call(this,null,f,g,h,l,m,d,e,p,k);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1}function Od(a,b,c,d,e,f,g,h,l){ba.call(this,a,b,c,d,e,f,g,h,l);this.needsUpdate=!0}function Pd(a,b,c,d,e,f,g,h,l,m){m=void 0!== +m?m:1026;if(1026!==m&&1027!==m)throw Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");void 0===c&&1026===m&&(c=1012);void 0===c&&1027===m&&(c=1020);ba.call(this,null,d,e,f,g,h,m,c,l);this.image={width:a,height:b};this.magFilter=void 0!==g?g:1003;this.minFilter=void 0!==h?h:1003;this.generateMipmaps=this.flipY=!1}function Mc(a){D.call(this);this.type="WireframeGeometry";var b=[],c,d,e,f=[0,0],g={},h=["a","b","c"];if(a&&a.isGeometry){var l=a.faces;var m=0;for(d= +l.length;mc;c++){var k=p[h[c]];var r=p[h[(c+1)%3]];f[0]=Math.min(k,r);f[1]=Math.max(k,r);k=f[0]+","+f[1];void 0===g[k]&&(g[k]={index1:f[0],index2:f[1]})}}for(k in g)m=g[k],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&a.isBufferGeometry)if(h=new n,null!==a.index){l=a.attributes.position;p=a.index;var q=a.groups;0===q.length&&(q=[{start:0,count:p.count,materialIndex:0}]);a=0;for(e=q.length;ac;c++)k=p.getX(m+c),r=p.getX(m+(c+1)%3),f[0]=Math.min(k,r),f[1]=Math.max(k,r),k=f[0]+","+f[1],void 0===g[k]&&(g[k]={index1:f[0],index2:f[1]});for(k in g)m=g[k],h.fromBufferAttribute(l,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(l,m.index2),b.push(h.x,h.y,h.z)}else for(l=a.attributes.position,m=0,d=l.count/3;mc;c++)g=3*m+c,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z);this.addAttribute("position", +new A(b,3))}function Qd(a,b,c){G.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new Nc(a,b,c));this.mergeVertices()}function Nc(a,b,c){D.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h=new n,l=new n,m=new n,p=new n,k=new n,r,q;3>a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.");var t=b+1;for(r=0;r<=c;r++){var y= +r/c;for(q=0;q<=b;q++){var w=q/b;a(w,y,l);e.push(l.x,l.y,l.z);0<=w-1E-5?(a(w-1E-5,y,m),p.subVectors(l,m)):(a(w+1E-5,y,m),p.subVectors(m,l));0<=y-1E-5?(a(w,y-1E-5,m),k.subVectors(l,m)):(a(w,y+1E-5,m),k.subVectors(m,l));h.crossVectors(p,k).normalize();f.push(h.x,h.y,h.z);g.push(w,y)}}for(r=0;rd&&1===a.x&&(l[b]=a.x-1);0===c.x&&0===c.z&&(l[b]=d/2/Math.PI+.5)}D.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c= +c||1;d=d||0;var h=[],l=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;he&&(.2>b&&(l[a+0]+=1),.2>c&&(l[a+2]+=1),.2>d&&(l[a+4]+=1))})();this.addAttribute("position",new A(h,3));this.addAttribute("normal",new A(h.slice(),3));this.addAttribute("uv",new A(l,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Sd(a,b){G.call(this); +this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Oc(a,b));this.mergeVertices()}function Oc(a,b){pa.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="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Td(a,b){G.call(this);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new bc(a,b));this.mergeVertices()}function bc(a,b){pa.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="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Ud(a,b){G.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Pc(a,b));this.mergeVertices()}function Pc(a,b){var c=(1+Math.sqrt(5))/2;pa.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7, +6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Vd(a,b){G.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Qc(a,b));this.mergeVertices()}function Qc(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;pa.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="DodecahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Wd(a,b,c,d,e,f){G.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};void 0!== +f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new cc(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function cc(a,b,c,d,e){function f(e){p=a.getPointAt(e/b,p);var f=g.normals[e];e=g.binormals[e];for(r=0;r<=d;r++){var m=r/d*Math.PI*2,k=Math.sin(m);m=-Math.cos(m);l.x=m*f.x+k*e.x;l.y=m*f.y+k*e.y;l.z=m*f.z+k*e.z;l.normalize();t.push(l.x,l.y,l.z);h.x=p.x+c*l.x;h.y=p.y+c*l.y;h.z=p.z+c*l.z;q.push(h.x, +h.y,h.z)}}D.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,l=new n,m=new v,p=new n,k,r,q=[],t=[],y=[],w=[];for(k=0;k=b;e-=d)f=Mh(e,a[e],a[e+1],f);f&&dc(f,f.next)&&(Zd(f),f=f.next);return f}function $d(a,b){if(!a)return a;b||(b=a);do{var c=!1;if(a.steiner||!dc(a,a.next)&&0!==ua(a.prev,a,a.next))a=a.next;else{Zd(a);a=b=a.prev;if(a===a.next)break;c=!0}}while(c||a!==b);return b} +function ae(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,l=h;do null===l.z&&(l.z=ig(l.x,l.y,d,e,f)),l.prevZ=l.prev,l=l.nextZ=l.next;while(l!==h);l.prevZ.nextZ=null;l.prevZ=null;h=l;var m,p,k,r,q=1;do{l=h;var t=h=null;for(p=0;l;){p++;var n=l;for(m=k=0;mn!==t.next.y>n&&t.next.y!==t.y&&k<(t.next.x-t.x)*(n-t.y)/(t.next.y-t.y)+t.x&&(p=!p),t=t.next;while(t!==l);t=p}l=t}if(l){a=Oh(g,h);g=$d(g,g.next);a=$d(a,a.next);ae(g,b,c,d,e,f);ae(a,b,c,d,e,f);break a}h= +h.next}g=g.next}while(g!==a)}break}}}}function ak(a,b,c,d){var e=a.prev,f=a.next;if(0<=ua(e,a,f))return!1;var g=e.x>a.x?e.x>f.x?e.x:f.x:a.x>f.x?a.x:f.x,h=e.y>a.y?e.y>f.y?e.y:f.y:a.y>f.y?a.y:f.y,l=ig(e.x=l&&d&&d.z<=b;){if(c!==a.prev&&c!==a.next&&Tc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=ua(c.prev,c,c.next))return!1;c=c.prevZ;if(d!==a.prev&&d!==a.next&&Tc(e.x,e.y,a.x,a.y, +f.x,f.y,d.x,d.y)&&0<=ua(d.prev,d,d.next))return!1;d=d.nextZ}for(;c&&c.z>=l;){if(c!==a.prev&&c!==a.next&&Tc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=ua(c.prev,c,c.next))return!1;c=c.prevZ}for(;d&&d.z<=b;){if(d!==a.prev&&d!==a.next&&Tc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=ua(d.prev,d,d.next))return!1;d=d.nextZ}return!0}function bk(a,b){return a.x-b.x}function ck(a,b){var c=b,d=a.x,e=a.y,f=-Infinity;do{if(e<=c.y&&e>=c.next.y&&c.next.y!==c.y){var g=c.x+(e-c.y)*(c.next.x-c.x)/(c.next.y-c.y);if(g<=d&&g>f){f= +g;if(g===d){if(e===c.y)return c;if(e===c.next.y)return c.next}var h=c.x=c.x&&c.x>=g&&d!==c.x&&Tc(eh.x)&&be(c,a)&&(h=c,m=p)}c=c.next}return h}function ig(a,b,c,d,e){a=32767*(a-c)*e;b=32767*(b-d)*e;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135;a=(a|a<<2)&858993459;b=(b|b<<8)&16711935;b=(b| +b<<4)&252645135;b=(b|b<<2)&858993459;return(a|a<<1)&1431655765|((b|b<<1)&1431655765)<<1}function dk(a){var b=a,c=a;do{if(b.xua(a.prev,a,a.next)?0<=ua(a,b,a.next)&&0<=ua(a,a.prev,b):0>ua(a,b,a.prev)||0>ua(a,a.next,b)}function Oh(a,b){var c=new jg(a.i,a.x,a.y),d=new jg(b.i,b.x,b.y),e=a.next,f=b.prev;a.next=b;b.prev=a;c.next=e;e.prev=c;d.next=c;c.prev=d;f.next=d;d.prev=f;return d}function Mh(a,b,c,d){a=new jg(a,b,c);d?(a.next=d.next,a.prev=d,d.next.prev=a,d.next=a):(a.prev=a,a.next=a);return a}function Zd(a){a.next.prev=a.prev;a.prev.next=a.next;a.prevZ&&(a.prevZ.nextZ= +a.nextZ);a.nextZ&&(a.nextZ.prevZ=a.prevZ)}function jg(a,b,c){this.i=a;this.x=b;this.y=c;this.nextZ=this.prevZ=this.z=this.next=this.prev=null;this.steiner=!1}function Ph(a){var b=a.length;2Number.EPSILON){var l=Math.sqrt(h),m=Math.sqrt(f*f+g*g);h=b.x-e/l;b=b.y+d/l;g=((c.x-g/m-h)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=h+d*g-a.x;d=b+e*g-a.y;e=f*f+d*d;if(2>=e)return new v(f,d);e=Math.sqrt(e/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?(f=-e,e=Math.sqrt(h)):(f=d,d=e,e=Math.sqrt(h/2));return new v(f/e,d/e)}function h(a,b){for(L=a.length;0<=--L;){var c=L;var f=L-1;0>f&&(f=a.length-1);var g,h=x+2*D;for(g=0;gk;k++){var n=m[f[k]];var r=m[f[(k+1)%3]];d[0]=Math.min(n,r);d[1]=Math.max(n,r);n=d[0]+","+d[1];void 0===e[n]?e[n]={index1:d[0],index2:d[1],face1:h,face2:void 0}:e[n].face2=h}for(n in e)if(d=e[n],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.addAttribute("position",new A(c,3))}function hc(a,b,c,d,e,f,g,h){G.call(this);this.type="CylinderGeometry"; +this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new rb(a,b,c,d,e,f,g,h));this.mergeVertices()}function rb(a,b,c,d,e,f,g,h){function l(c){var e,f=new v,l=new n,p=0,y=!0===c?a:b,x=!0===c?1:-1;var A=t;for(e=1;e<=d;e++)u.push(0,w*x,0),r.push(0,x,0),q.push(.5,.5),t++;var B=t;for(e=0;e<=d;e++){var D=e/d*h+g,F=Math.cos(D);D=Math.sin(D);l.x=y*D;l.y=w*x;l.z=y*F;u.push(l.x,l.y,l.z);r.push(0,x,0);f.x=.5*F+ +.5;f.y=.5*D*x+.5;q.push(f.x,f.y);t++}for(e=0;ethis.duration&&this.resetDuration()}function fk(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return $c;case "vector":case "vector2":case "vector3":case "vector4":return ad; +case "color":return Re;case "quaternion":return ke;case "bool":case "boolean":return Qe;case "string":return Te}throw Error("THREE.KeyframeTrack: Unsupported typeName: "+a);}function gk(a){if(void 0===a.type)throw Error("THREE.KeyframeTrack: track type undefined, can not parse");var b=fk(a.type);if(void 0===a.times){var c=[],d=[];Z.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)}function kg(a,b,c){var d=this,e= +!1,f=0,g=0,h=void 0;this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){g++;if(!1===e&&void 0!==d.onStart)d.onStart(a,f,g);e=!0};this.itemEnd=function(a){f++;if(void 0!==d.onProgress)d.onProgress(a,f,g);if(f===g&&(e=!1,void 0!==d.onLoad))d.onLoad()};this.itemError=function(a){if(void 0!==d.onError)d.onError(a)};this.resolveURL=function(a){return h?h(a):a};this.setURLModifier=function(a){h=a;return this}}function aa(a){this.manager=void 0!==a?a:Th;this.crossOrigin= +"anonymous";this.resourcePath=this.path=""}function Na(a){aa.call(this,a)}function lg(a){aa.call(this,a)}function mg(a){aa.call(this,a);this._parser=null}function Ue(a){aa.call(this,a);this._parser=null}function bd(a){aa.call(this,a)}function Ve(a){aa.call(this,a)}function We(a){aa.call(this,a)}function F(){this.type="Curve";this.arcLengthDivisions=200}function Ia(a,b,c,d,e,f,g,h){F.call(this);this.type="EllipseCurve";this.aX=a||0;this.aY=b||0;this.xRadius=c||1;this.yRadius=d||1;this.aStartAngle= +e||0;this.aEndAngle=f||2*Math.PI;this.aClockwise=g||!1;this.aRotation=h||0}function cd(a,b,c,d,e,f){Ia.call(this,a,b,c,c,d,e,f);this.type="ArcCurve"}function ng(){var a=0,b=0,c=0,d=0;return{initCatmullRom:function(e,f,g,h,l){e=l*(g-e);h=l*(h-f);a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},initNonuniformCatmullRom:function(e,f,g,h,l,m,k){e=((f-e)/l-(g-e)/(l+m)+(g-f)/m)*m;h=((g-f)/m-(h-f)/(m+k)+(h-g)/k)*m;a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},calc:function(e){var f=e*e;return a+b*e+c*f+d*f*e}}}function sa(a, +b,c,d){F.call(this);this.type="CatmullRomCurve3";this.points=a||[];this.closed=b||!1;this.curveType=c||"centripetal";this.tension=d||.5}function Uh(a,b,c,d,e){b=.5*(d-b);e=.5*(e-c);var f=a*a;return(2*c-2*d+b+e)*a*f+(-3*c+3*d-2*b-e)*f+b*a+c}function le(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}function me(a,b,c,d,e){var f=1-a,g=1-a;return f*f*f*b+3*g*g*a*c+3*(1-a)*a*a*d+a*a*a*e}function Sa(a,b,c,d){F.call(this);this.type="CubicBezierCurve";this.v0=a||new v;this.v1=b||new v;this.v2=c||new v; +this.v3=d||new v}function gb(a,b,c,d){F.call(this);this.type="CubicBezierCurve3";this.v0=a||new n;this.v1=b||new n;this.v2=c||new n;this.v3=d||new n}function Da(a,b){F.call(this);this.type="LineCurve";this.v1=a||new v;this.v2=b||new v}function Ta(a,b){F.call(this);this.type="LineCurve3";this.v1=a||new n;this.v2=b||new n}function Ua(a,b,c){F.call(this);this.type="QuadraticBezierCurve";this.v0=a||new v;this.v1=b||new v;this.v2=c||new v}function hb(a,b,c){F.call(this);this.type="QuadraticBezierCurve3"; +this.v0=a||new n;this.v1=b||new n;this.v2=c||new n}function Va(a){F.call(this);this.type="SplineCurve";this.points=a||[]}function sb(){F.call(this);this.type="CurvePath";this.curves=[];this.autoClose=!1}function Wa(a){sb.call(this);this.type="Path";this.currentPoint=new v;a&&this.setFromPoints(a)}function Jb(a){Wa.call(this,a);this.uuid=O.generateUUID();this.type="Shape";this.holes=[]}function V(a,b){B.call(this);this.type="Light";this.color=new J(a);this.intensity=void 0!==b?b:1;this.receiveShadow= +void 0}function Xe(a,b,c){V.call(this,a,c);this.type="HemisphereLight";this.castShadow=void 0;this.position.copy(B.DefaultUp);this.updateMatrix();this.groundColor=new J(b)}function ib(a){this.camera=a;this.bias=0;this.radius=1;this.mapSize=new v(512,512);this.mapPass=this.map=null;this.matrix=new P;this._frustum=new Ed;this._frameExtents=new v(1,1);this._viewportCount=1;this._viewports=[new da(0,0,1,1)]}function Ye(){ib.call(this,new la(50,1,.5,500))}function Ze(a,b,c,d,e,f){V.call(this,a,b);this.type= +"SpotLight";this.position.copy(B.DefaultUp);this.updateMatrix();this.target=new B;Object.defineProperty(this,"power",{get:function(){return this.intensity*Math.PI},set:function(a){this.intensity=a/Math.PI}});this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.penumbra=void 0!==e?e:0;this.decay=void 0!==f?f:1;this.shadow=new Ye}function og(){ib.call(this,new la(90,1,.5,500));this._frameExtents=new v(4,2);this._viewportCount=6;this._viewports=[new da(2,1,1,1),new da(0,1,1,1),new da(3, +1,1,1),new da(1,1,1,1),new da(3,0,1,1),new da(1,0,1,1)];this._cubeDirections=[new n(1,0,0),new n(-1,0,0),new n(0,0,1),new n(0,0,-1),new n(0,1,0),new n(0,-1,0)];this._cubeUps=[new n(0,1,0),new n(0,1,0),new n(0,1,0),new n(0,1,0),new n(0,0,1),new n(0,0,-1)]}function $e(a,b,c,d){V.call(this,a,b);this.type="PointLight";Object.defineProperty(this,"power",{get:function(){return 4*this.intensity*Math.PI},set:function(a){this.intensity=a/(4*Math.PI)}});this.distance=void 0!==c?c:0;this.decay=void 0!==d?d: +1;this.shadow=new og}function ne(a,b,c,d,e,f){bb.call(this);this.type="OrthographicCamera";this.zoom=1;this.view=null;this.left=void 0!==a?a:-1;this.right=void 0!==b?b:1;this.top=void 0!==c?c:1;this.bottom=void 0!==d?d:-1;this.near=void 0!==e?e:.1;this.far=void 0!==f?f:2E3;this.updateProjectionMatrix()}function af(){ib.call(this,new ne(-5,5,5,-5,.5,500))}function bf(a,b){V.call(this,a,b);this.type="DirectionalLight";this.position.copy(B.DefaultUp);this.updateMatrix();this.target=new B;this.shadow= +new af}function cf(a,b){V.call(this,a,b);this.type="AmbientLight";this.castShadow=void 0}function df(a,b,c,d){V.call(this,a,b);this.type="RectAreaLight";this.width=void 0!==c?c:10;this.height=void 0!==d?d:10}function ef(a){aa.call(this,a);this.textures={}}function ff(){D.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0}function gf(a,b,c,d){"number"===typeof c&&(d=c,c=!1,console.error("THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.")); +N.call(this,a,b,c);this.meshPerAttribute=d||1}function hf(a){aa.call(this,a)}function jf(a){aa.call(this,a)}function pg(a){"undefined"===typeof createImageBitmap&&console.warn("THREE.ImageBitmapLoader: createImageBitmap() not supported.");"undefined"===typeof fetch&&console.warn("THREE.ImageBitmapLoader: fetch() not supported.");aa.call(this,a);this.options=void 0}function qg(){this.type="ShapePath";this.color=new J;this.subPaths=[];this.currentPath=null}function rg(a){this.type="Font";this.data= +a}function sg(a){aa.call(this,a)}function kf(a){aa.call(this,a)}function lf(){this.coefficients=[];for(var a=0;9>a;a++)this.coefficients.push(new n)}function Xa(a,b){V.call(this,void 0,b);this.sh=void 0!==a?a:new lf}function tg(a,b,c){Xa.call(this,void 0,c);a=(new J).set(a);c=(new J).set(b);b=new n(a.r,a.g,a.b);a=new n(c.r,c.g,c.b);c=Math.sqrt(Math.PI);var d=c*Math.sqrt(.75);this.sh.coefficients[0].copy(b).add(a).multiplyScalar(c);this.sh.coefficients[1].copy(b).sub(a).multiplyScalar(d)}function ug(a, +b){Xa.call(this,void 0,b);a=(new J).set(a);this.sh.coefficients[0].set(a.r,a.g,a.b).multiplyScalar(2*Math.sqrt(Math.PI))}function Vh(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new la;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new la;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1;this._cache={focus:null,fov:null,aspect:null,near:null,far:null,zoom:null,eyeSep:null}}function vg(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime= +this.oldTime=this.startTime=0;this.running=!1}function wg(){B.call(this);this.type="AudioListener";this.context=xg.getContext();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0;this._clock=new vg}function dd(a){B.call(this);this.type="Audio";this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=this.startTime= +0;this.duration=void 0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this.filters=[]}function yg(a){dd.call(this,a);this.panner=this.context.createPanner();this.panner.panningModel="HRTF";this.panner.connect(this.gain)}function zg(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)}function Ag(a,b,c){this.binding=a;this.valueSize= +c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a=Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function Wh(a,b,c){c=c||ma.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function ma(a,b,c){this.path=b;this.parsedPath=c||ma.parseTrackName(b);this.node=ma.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function Xh(){this.uuid= +O.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_=0;var a={};this._indicesByUUID=a;for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length},get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function Yh(a,b,c){this._mixer=a;this._clip=b;this._localRoot= +c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity; +this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart=!0}function Bg(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1}function mf(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Cg(a,b,c){ac.call(this,a,b);this.meshPerAttribute=c||1}function Zh(a,b,c,d){this.ray=new Sb(a,b);this.near=c||0;this.far=d||Infinity;this.camera=null;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}}})}function $h(a,b){return a.distance-b.distance}function Dg(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;dc;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1, +Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new A(b,3));b=new Y({fog:!1});this.cone=new R(a,b);this.add(this.cone);this.update()}function ci(a){var b=[];a&&a.isBone&&b.push(a);for(var c=0;ca?-1:0ve;ve++)qa[ve]=(16>ve?"0":"")+ +ve.toString(16);var O={DEG2RAD:Math.PI/180,RAD2DEG:180/Math.PI,generateUUID:function(){var a=4294967295*Math.random()|0,b=4294967295*Math.random()|0,c=4294967295*Math.random()|0,d=4294967295*Math.random()|0;return(qa[a&255]+qa[a>>8&255]+qa[a>>16&255]+qa[a>>24&255]+"-"+qa[b&255]+qa[b>>8&255]+"-"+qa[b>>16&15|64]+qa[b>>24&255]+"-"+qa[c&63|128]+qa[c>>8&255]+"-"+qa[c>>16&255]+qa[c>>24&255]+qa[d&255]+qa[d>>8&255]+qa[d>>16&255]+qa[d>>24&255]).toUpperCase()},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)},lerp:function(a,b,c){return(1-c)*a+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)},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(a){return a*O.DEG2RAD},radToDeg:function(a){return a*O.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},ceilPowerOfTwo:function(a){return Math.pow(2,Math.ceil(Math.log(a)/Math.LN2))},floorPowerOfTwo:function(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))}};Object.defineProperties(v.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(v.prototype, +{isVector2:!0,set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x=a;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);}return this},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){return this.multiplyScalar(1/a)},applyMatrix3:function(a){var b=this.x,c=this.y;a=a.elements;this.x=a[0]*b+a[3]*c+a[6];this.y= +a[1]*b+a[4]*c+a[7];return this},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(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c|| +1).multiplyScalar(Math.max(a,Math.min(b,c)))},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},cross:function(a){return this.x*a.y-this.y*a.x},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||1)},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a},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},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},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){return this.subVectors(b,a).multiplyScalar(c).add(a)},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},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a,b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}});Object.assign(na,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var h= +c[d+0],l=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var k=e[f+1],n=e[f+2];e=e[f+3];if(c!==e||h!==d||l!==k||m!==n){f=1-g;var r=h*d+l*k+m*n+c*e,q=0<=r?1:-1,t=1-r*r;t>Number.EPSILON&&(t=Math.sqrt(t),r=Math.atan2(t,r*q),f=Math.sin(f*r)/t,g=Math.sin(g*r)/t);q*=g;h=h*f+d*q;l=l*f+k*q;m=m*f+n*q;c=c*f+e*q;f===1-g&&(g=1/Math.sqrt(h*h+l*l+m*m+c*c),h*=g,l*=g,m*=g,c*=g)}a[b]=h;a[b+1]=l;a[b+2]=m;a[b+3]=c}});Object.defineProperties(na.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}}, +y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this._onChangeCallback()}}});Object.assign(na.prototype,{isQuaternion:!0,set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(a){this._x= +a.x;this._y=a.y;this._z=a.z;this._w=a.w;this._onChangeCallback();return this},setFromEuler:function(a,b){if(!a||!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z;a=a.order;var f=Math.cos,g=Math.sin,h=f(c/2),l=f(d/2);f=f(e/2);c=g(c/2);d=g(d/2);e=g(e/2);"XYZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"YXZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z= +h*l*e-c*d*f,this._w=h*l*f+c*d*e):"ZXY"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"ZYX"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f+c*d*e):"YZX"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f-c*d*e):"XZY"===a&&(this._x=c*l*f-h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f+c*d*e);!1!==b&&this._onChangeCallback();return this},setFromAxisAngle:function(a,b){b/=2;var c=Math.sin(b); +this._x=a.x*c;this._y=a.y*c;this._z=a.z*c;this._w=Math.cos(b);this._onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],l=b[6];b=b[10];var m=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(l-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(g+l)/ +c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+l)/c,this._z=.25*c);this._onChangeCallback();return this},setFromUnitVectors:function(a,b){var c=a.dot(b)+1;1E-6>c?(c=0,Math.abs(a.x)>Math.abs(a.z)?(this._x=-a.y,this._y=a.x,this._z=0):(this._x=0,this._y=-a.z,this._z=a.y)):(this._x=a.y*b.z-a.z*b.y,this._y=a.z*b.x-a.x*b.z,this._z=a.x*b.y-a.y*b.x);this._w=c;return this.normalize()},angleTo:function(a){return 2*Math.acos(Math.abs(O.clamp(this.dot(a),-1,1)))},rotateTowards:function(a, +b){var c=this.angleTo(a);if(0===c)return this;this.slerp(a,Math.min(1,b/c));return this},inverse:function(){return this.conjugate()},conjugate:function(){this._x*=-1;this._y*=-1;this._z*=-1;this._onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a= +this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this._onChangeCallback();return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z;a=a._w; +var f=b._x,g=b._y,h=b._z;b=b._w;this._x=c*b+a*f+d*h-e*g;this._y=d*b+a*g+e*f-c*h;this._z=e*b+a*h+c*g-d*f;this._w=a*b-c*f-d*g-e*h;this._onChangeCallback();return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;a=1-g*g;if(a<=Number.EPSILON)return g=1-b,this._w=g* +f+b*this._w,this._x=g*c+b*this._x,this._y=g*d+b*this._y,this._z=g*e+b*this._z,this.normalize(),this._onChangeCallback(),this;a=Math.sqrt(a);var h=Math.atan2(a,g);g=Math.sin((1-b)*h)/a;b=Math.sin(b*h)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;this._onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2]; +this._w=a[b+3];this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});var Ig=new n,fi=new na;Object.assign(n.prototype,{isVector3:!0,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;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);}return this},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(a){a&&a.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(fi.setFromEuler(a))},applyAxisAngle:function(a,b){return this.applyQuaternion(fi.setFromAxisAngle(a,b))},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;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,l=a*c+g*b-e*d,m=a*d+e*c-f*b;b=-e*b-f*c-g*d;this.x=h*a+b*-e+l*-g-m*-f;this.y=l*a+b*-f+m*-e-h*-g;this.z=m*a+b*-g+h*-f-l*-e;return this}, +project:function(a){return this.applyMatrix4(a.matrixWorldInverse).applyMatrix4(a.projectionMatrix)},unproject:function(a){return this.applyMatrix4(a.projectionMatrixInverse).applyMatrix4(a.matrixWorld)},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;return this.normalize()},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(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a, +Math.min(b,this.z));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},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)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+ +Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},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){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){return void 0!==b?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b)):this.crossVectors(this, +a)},crossVectors:function(a,b){var c=a.x,d=a.y;a=a.z;var e=b.x,f=b.y;b=b.z;this.x=d*b-a*f;this.y=a*e-c*b;this.z=c*f-d*e;return this},projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(a){Ig.copy(this).projectOnVector(a);return this.sub(Ig)},reflect:function(a){return this.sub(Ig.copy(a).multiplyScalar(2*this.dot(a)))},angleTo:function(a){a=this.dot(a)/Math.sqrt(this.lengthSq()*a.lengthSq());return Math.acos(O.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},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){return this.setFromSphericalCoords(a.radius,a.phi,a.theta)},setFromSphericalCoords:function(a,b,c){var d=Math.sin(b)*a;this.x=d*Math.sin(c);this.y=Math.cos(b)*a;this.z=d*Math.cos(c);return this},setFromCylindrical:function(a){return this.setFromCylindricalCoords(a.radius,a.theta, +a.y)},setFromCylindricalCoords:function(a,b,c){this.x=a*Math.sin(b);this.y=c;this.z=a*Math.cos(b);return this},setFromMatrixPosition:function(a){a=a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},setFromMatrixScale:function(a){var b=this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a,2).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){return this.fromArray(a.elements,4*b)},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},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});var pc=new n;Object.assign(ta.prototype,{isMatrix3:!0,set:function(a, +b,c,d,e,f,g,h,l){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=l;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this}, +applyToBufferAttribute:function(a){for(var b=0,c=a.count;bc;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);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}});var md,Kb={getDataURL:function(a){if("undefined"==typeof HTMLCanvasElement)return a.src;if(!(a instanceof HTMLCanvasElement)){void 0===md&&(md=document.createElementNS("http://www.w3.org/1999/xhtml", +"canvas"));md.width=a.width;md.height=a.height;var b=md.getContext("2d");a instanceof ImageData?b.putImageData(a,0,0):b.drawImage(a,0,0,a.width,a.height);a=md}return 2048a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y);return a}});Object.defineProperty(ba.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.defineProperties(da.prototype,{width:{get:function(){return this.z},set:function(a){this.z=a}},height:{get:function(){return this.w},set:function(a){this.w=a}}});Object.assign(da.prototype,{isVector4:!0,set:function(a,b,c,d){this.x= +a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;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);}return this},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){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){a=a.elements;var b=a[0];var c=a[4];var d=a[8],e=a[1],f=a[5],g=a[9];var h=a[2];var l=a[6];var m=a[10];if(.01>Math.abs(c-e)&&.01>Math.abs(d-h)&&.01>Math.abs(g-l)){if(.1>Math.abs(c+e)&&.1>Math.abs(d+h)&&.1>Math.abs(g+l)&&.1>Math.abs(b+f+m-3))return this.set(1,0,0,0),this;a=Math.PI; +b=(b+1)/2;f=(f+1)/2;m=(m+1)/2;c=(c+e)/4;d=(d+h)/4;g=(g+l)/4;b>f&&b>m?.01>b?(l=0,c=h=.707106781):(l=Math.sqrt(b),h=c/l,c=d/l):f>m?.01>f?(l=.707106781,h=0,c=.707106781):(h=Math.sqrt(f),l=c/h,c=g/h):.01>m?(h=l=.707106781,c=0):(c=Math.sqrt(m),l=d/c,h=g/c);this.set(l,h,c,a);return this}a=Math.sqrt((l-g)*(l-g)+(d-h)*(d-h)+(e-c)*(e-c));.001>Math.abs(a)&&(a=1);this.x=(l-g)/a;this.y=(d-h)/a;this.z=(e-c)/a;this.w=Math.acos((b+f+m-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(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b, +this.y));this.z=Math.max(a,Math.min(b,this.z));this.w=Math.max(a,Math.min(b,this.w));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},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)},manhattanLength: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()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},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){return this.subVectors(b,a).multiplyScalar(c).add(a)},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},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector4: offset has been removed from .fromBufferAttribute()."); +this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);this.w=a.getW(b);return this}});Ka.prototype=Object.assign(Object.create(xa.prototype),{constructor:Ka,isWebGLRenderTarget:!0,setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.texture.image.width=a,this.texture.image.height=b,this.dispose();this.viewport.set(0,0,a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport); +this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});Pf.prototype=Object.assign(Object.create(Ka.prototype),{constructor:Pf,isWebGLMultisampleRenderTarget:!0,copy:function(a){Ka.prototype.copy.call(this,a);this.samples=a.samples;return this}});var Ja=new n,ja=new P,hk=new n(0,0,0),ik=new n(1,1,1),Lb=new n,rf=new n,za=new n;Object.assign(P.prototype,{isMatrix4:!0, +set:function(a,b,c,d,e,f,g,h,l,m,k,n,r,q,t,y){var p=this.elements;p[0]=a;p[4]=b;p[8]=c;p[12]=d;p[1]=e;p[5]=f;p[9]=g;p[13]=h;p[2]=l;p[6]=m;p[10]=k;p[14]=n;p[3]=r;p[7]=q;p[11]=t;p[15]=y;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 P).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11]; +b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return this},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){a.setFromMatrixColumn(this,0);b.setFromMatrixColumn(this,1);c.setFromMatrixColumn(this,2);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(a){var b=this.elements,c=a.elements,d=1/Ja.setFromMatrixColumn(a,0).length(), +e=1/Ja.setFromMatrixColumn(a,1).length();a=1/Ja.setFromMatrixColumn(a,2).length();b[0]=c[0]*d;b[1]=c[1]*d;b[2]=c[2]*d;b[3]=0;b[4]=c[4]*e;b[5]=c[5]*e;b[6]=c[6]*e;b[7]=0;b[8]=c[8]*a;b[9]=c[9]*a;b[10]=c[10]*a;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromEuler:function(a){a&&a.isEuler||console.error("THREE.Matrix4: .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,f=Math.cos(c);c=Math.sin(c);var g=Math.cos(d); +d=Math.sin(d);var h=Math.cos(e);e=Math.sin(e);if("XYZ"===a.order){a=f*h;var l=f*e,m=c*h,k=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=l+m*d;b[5]=a-k*d;b[9]=-c*g;b[2]=k-a*d;b[6]=m+l*d;b[10]=f*g}else"YXZ"===a.order?(a=g*h,l=g*e,m=d*h,k=d*e,b[0]=a+k*c,b[4]=m*c-l,b[8]=f*d,b[1]=f*e,b[5]=f*h,b[9]=-c,b[2]=l*c-m,b[6]=k+a*c,b[10]=f*g):"ZXY"===a.order?(a=g*h,l=g*e,m=d*h,k=d*e,b[0]=a-k*c,b[4]=-f*e,b[8]=m+l*c,b[1]=l+m*c,b[5]=f*h,b[9]=k-a*c,b[2]=-f*d,b[6]=c,b[10]=f*g):"ZYX"===a.order?(a=f*h,l=f*e,m=c*h,k=c*e,b[0]=g*h, +b[4]=m*d-l,b[8]=a*d+k,b[1]=g*e,b[5]=k*d+a,b[9]=l*d-m,b[2]=-d,b[6]=c*g,b[10]=f*g):"YZX"===a.order?(a=f*g,l=f*d,m=c*g,k=c*d,b[0]=g*h,b[4]=k-a*e,b[8]=m*e+l,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=l*e+m,b[10]=a-k*e):"XZY"===a.order&&(a=f*g,l=f*d,m=c*g,k=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+k,b[5]=f*h,b[9]=l*e-m,b[2]=m*e-l,b[6]=c*h,b[10]=k*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},makeRotationFromQuaternion:function(a){return this.compose(hk,a,ik)},lookAt:function(a,b, +c){var d=this.elements;za.subVectors(a,b);0===za.lengthSq()&&(za.z=1);za.normalize();Lb.crossVectors(c,za);0===Lb.lengthSq()&&(1===Math.abs(c.z)?za.x+=1E-4:za.z+=1E-4,za.normalize(),Lb.crossVectors(c,za));Lb.normalize();rf.crossVectors(za,Lb);d[0]=Lb.x;d[4]=rf.x;d[8]=za.x;d[1]=Lb.y;d[5]=rf.y;d[9]=za.y;d[2]=Lb.z;d[6]=rf.z;d[10]=za.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)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements;b=this.elements;a=c[0];var e=c[4],f=c[8],g=c[12],h=c[1],l=c[5],m=c[9],k=c[13],n=c[2],r=c[6],q=c[10],t=c[14],y=c[3],w=c[7],z=c[11];c=c[15];var x=d[0],v=d[4],A=d[8],E=d[12],B=d[1],D=d[5],F=d[9],G=d[13],I=d[2],H=d[6],J=d[10],K=d[14],N=d[3],O=d[7],P=d[11];d=d[15];b[0]=a*x+e*B+f*I+g*N;b[4]=a*v+e*D+f*H+g*O;b[8]=a*A+e*F+f*J+ +g*P;b[12]=a*E+e*G+f*K+g*d;b[1]=h*x+l*B+m*I+k*N;b[5]=h*v+l*D+m*H+k*O;b[9]=h*A+l*F+m*J+k*P;b[13]=h*E+l*G+m*K+k*d;b[2]=n*x+r*B+q*I+t*N;b[6]=n*v+r*D+q*H+t*O;b[10]=n*A+r*F+q*J+t*P;b[14]=n*E+r*G+q*K+t*d;b[3]=y*x+w*B+z*I+c*N;b[7]=y*v+w*D+z*H+c*O;b[11]=y*A+w*F+z*J+c*P;b[15]=y*E+w*G+z*K+c*d;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},applyToBufferAttribute:function(a){for(var b= +0,c=a.count;bthis.determinant()&&(e=-e);a.x=d[12];a.y=d[13];a.z=d[14];ja.copy(this);a=1/e;d=1/f;var h=1/g;ja.elements[0]*=a;ja.elements[1]*=a;ja.elements[2]*=a;ja.elements[4]*=d;ja.elements[5]*=d;ja.elements[6]*=d;ja.elements[8]*=h;ja.elements[9]*=h;ja.elements[10]*=h;b.setFromRotationMatrix(ja);c.x=e;c.y=f;c.z=g;return this},makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs."); +var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(c-d);g[9]=(c+d)/(c-d);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),l=1/(c-d),m=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*l;g[9]=0;g[13]=-((c+d)*l);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+e)*m);g[3]=0;g[7]=0;g[11]=0;g[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,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);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}});var gi=new P,hi=new na;Qb.RotationOrders= +"XYZ YZX ZXY XZY YXZ ZYX".split(" ");Qb.DefaultOrder="XYZ";Object.defineProperties(Qb.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},order:{get:function(){return this._order},set:function(a){this._order=a;this._onChangeCallback()}}});Object.assign(Qb.prototype,{isEuler:!0,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=O.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],l=e[5],m=e[9],k=e[2],n=e[6];e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.9999999>Math.abs(g)? +(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(n,l),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.9999999>Math.abs(m)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h,l)):(this._y=Math.atan2(-k,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(n,-1,1)),.9999999>Math.abs(n)?(this._y=Math.atan2(-k,e),this._z=Math.atan2(-f,l)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(k,-1,1)),.9999999>Math.abs(k)?(this._x=Math.atan2(n,e),this._z=Math.atan2(h,a)): +(this._x=0,this._z=Math.atan2(-f,l))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.9999999>Math.abs(h)?(this._x=Math.atan2(-m,l),this._y=Math.atan2(-k,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.9999999>Math.abs(f)?(this._x=Math.atan2(n,l),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;!1!==c&&this._onChangeCallback();return this},setFromQuaternion:function(a, +b,c){gi.makeRotationFromQuaternion(a);return this.setFromRotationMatrix(gi,b,c)},setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(a){hi.setFromEuler(this);return this.setFromQuaternion(hi,a)},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 n(this._x,this._y,this._z)},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});Object.assign(Qf.prototype,{set:function(a){this.mask=1<e&&(e=m);k>f&&(f=k);n>g&&(g=n)}this.min.set(b,c,d); +this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,l=a.count;he&&(e=m);k>f&&(f=k);n>g&&(g=n)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box3: .getParameter() target is now required"),b=new n);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y), +(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},intersectsSphere:function(a){this.clampPoint(a.center,jb);return jb.distanceToSquared(a.center)<=a.radius*a.radius},intersectsPlane:function(a){if(0=-a.constant},intersectsTriangle:function(a){if(this.isEmpty())return!1;this.getCenter(xe);tf.subVectors(this.max,xe);od.subVectors(a.a,xe);pd.subVectors(a.b,xe);qd.subVectors(a.c,xe);Mb.subVectors(pd,od);Nb.subVectors(qd,pd);qc.subVectors(od,qd);a=[0,-Mb.z,Mb.y,0,-Nb.z,Nb.y,0,-qc.z, +qc.y,Mb.z,0,-Mb.x,Nb.z,0,-Nb.x,qc.z,0,-qc.x,-Mb.y,Mb.x,0,-Nb.y,Nb.x,0,-qc.y,qc.x,0];if(!Rf(a,od,pd,qd,tf))return!1;a=[1,0,0,0,1,0,0,0,1];if(!Rf(a,od,pd,qd,tf))return!1;uf.crossVectors(Mb,Nb);a=[uf.x,uf.y,uf.z];return Rf(a,od,pd,qd,tf)},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box3: .clampPoint() target is now required"),b=new n);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return jb.copy(a).clamp(this.min,this.max).sub(a).length()},getBoundingSphere:function(a){void 0=== +a&&console.error("THREE.Box3: .getBoundingSphere() target is now required");this.getCenter(a.center);a.radius=.5*this.getSize(jb).length();return a},intersect:function(a){this.min.max(a.min);this.max.min(a.max);this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(a){if(this.isEmpty())return this;wb[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(a);wb[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(a); +wb[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(a);wb[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(a);wb[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(a);wb[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(a);wb[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(a);wb[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(a);this.setFromPoints(wb);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&& +a.max.equals(this.max)}});var nk=new ab;Object.assign(nb.prototype,{set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(a,b){var c=this.center;void 0!==b?c.copy(b):nk.setFromPoints(a).getCenter(c);for(var d=b=0,e=a.length;d= +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},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(a.distanceToPoint(this.center))<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a); +void 0===b&&(console.warn("THREE.Sphere: .clampPoint() target is now required"),b=new n);b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center));return b},getBoundingBox:function(a){void 0===a&&(console.warn("THREE.Sphere: .getBoundingBox() target is now required"),a=new ab);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}});var xb=new n,Jg=new n,vf=new n,Ob=new n,Kg=new n,wf=new n,Lg=new n;Object.assign(Sb.prototype,{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){void 0===b&&(console.warn("THREE.Ray: .at() target is now required"), +b=new n);return b.copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(a){this.origin.copy(this.at(a,xb));return this},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Ray: .closestPointToPoint() target is now required"),b=new n);b.subVectors(a,this.origin);a=b.dot(this.direction);return 0>a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))}, +distanceSqToPoint:function(a){var b=xb.subVectors(a,this.origin).dot(this.direction);if(0>b)return this.origin.distanceToSquared(a);xb.copy(this.direction).multiplyScalar(b).add(this.origin);return xb.distanceToSquared(a)},distanceSqToSegment:function(a,b,c,d){Jg.copy(a).add(b).multiplyScalar(.5);vf.copy(b).sub(a).normalize();Ob.copy(this.origin).sub(Jg);var e=.5*a.distanceTo(b),f=-this.direction.dot(vf),g=Ob.dot(this.direction),h=-Ob.dot(vf),l=Ob.lengthSq(),m=Math.abs(1-f*f);if(0=-k?b<=k?(e=1/m,a*=e,b*=e,f=a*(a+f*b+2*g)+b*(f*a+b+2*h)+l):(b=e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):(b=-e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):b<=-k?(a=Math.max(0,-(-f*e+g)),b=0a)return null;a=Math.sqrt(a-d);d=c-a;c+=a;return 0>d&&0>c?null:0>d?this.at(c,b):this.at(d,b)},intersectsSphere:function(a){return this.distanceSqToPoint(a.center)<=a.radius*a.radius},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){a=this.distanceToPlane(a);return null===a?null:this.at(a,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a,b){var c=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z,f=this.origin;if(0<=c){var g=(a.min.x-f.x)*c;c*=a.max.x-f.x}else g=(a.max.x-f.x)*c,c*=a.min.x-f.x;if(0<=d){var h=(a.min.y-f.y)*d;d*=a.max.y-f.y}else h=(a.max.y- +f.y)*d,d*=a.min.y-f.y;if(g>d||h>c)return null;if(h>g||g!==g)g=h;if(da||h>c)return null;if(h>g||g!==g)g=h;if(ac?null:this.at(0<=g?g:c,b)},intersectsBox:function(a){return null!==this.intersectBox(a,xb)},intersectTriangle:function(a,b,c,d,e){Kg.subVectors(b,a);wf.subVectors(c,a);Lg.crossVectors(Kg,wf);b=this.direction.dot(Lg);if(0b)d=-1,b=-b;else return null; +Ob.subVectors(this.origin,a);a=d*this.direction.dot(wf.crossVectors(Ob,wf));if(0>a)return null;c=d*this.direction.dot(Kg.cross(Ob));if(0>c||a+c>b)return null;a=-d*Ob.dot(Lg);return 0>a?null:this.at(a/b,e)},applyMatrix4:function(a){this.origin.applyMatrix4(a);this.direction.transformDirection(a);return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});var Ya=new n,yb=new n,Mg=new n,zb=new n,rd=new n,sd=new n,mi=new n,Ng=new n,Og=new n,Pg=new n;Object.assign(ia, +{getNormal:function(a,b,c,d){void 0===d&&(console.warn("THREE.Triangle: .getNormal() target is now required"),d=new n);d.subVectors(c,b);Ya.subVectors(a,b);d.cross(Ya);a=d.lengthSq();return 0=zb.x+zb.y},getUV:function(a,b,c,d,e,f,g,h){this.getBarycoord(a,b,c,d,zb);h.set(0,0);h.addScaledVector(e,zb.x);h.addScaledVector(f,zb.y);h.addScaledVector(g,zb.z);return h},isFrontFacing:function(a,b,c,d){Ya.subVectors(c,b);yb.subVectors(a,b);return 0>Ya.cross(yb).dot(d)?!0:!1}});Object.assign(ia.prototype,{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},getArea:function(){Ya.subVectors(this.c,this.b);yb.subVectors(this.a,this.b);return.5*Ya.cross(yb).length()},getMidpoint:function(a){void 0===a&&(console.warn("THREE.Triangle: .getMidpoint() target is now required"), +a=new n);return a.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},getNormal:function(a){return ia.getNormal(this.a,this.b,this.c,a)},getPlane:function(a){void 0===a&&(console.warn("THREE.Triangle: .getPlane() target is now required"),a=new n);return a.setFromCoplanarPoints(this.a,this.b,this.c)},getBarycoord:function(a,b){return ia.getBarycoord(a,this.a,this.b,this.c,b)},getUV:function(a,b,c,d,e){return ia.getUV(a,this.a,this.b,this.c,b,c,d,e)},containsPoint:function(a){return ia.containsPoint(a, +this.a,this.b,this.c)},isFrontFacing:function(a){return ia.isFrontFacing(this.a,this.b,this.c,a)},intersectsBox:function(a){return a.intersectsTriangle(this)},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),b=new n);var c=this.a,d=this.b,e=this.c;rd.subVectors(d,c);sd.subVectors(e,c);Ng.subVectors(a,c);var f=rd.dot(Ng),g=sd.dot(Ng);if(0>=f&&0>=g)return b.copy(c);Og.subVectors(a,d);var h=rd.dot(Og),l=sd.dot(Og);if(0<=h&&l<= +h)return b.copy(d);var m=f*l-h*g;if(0>=m&&0<=f&&0>=h)return d=f/(f-h),b.copy(c).addScaledVector(rd,d);Pg.subVectors(a,e);a=rd.dot(Pg);var k=sd.dot(Pg);if(0<=k&&a<=k)return b.copy(e);f=a*g-f*k;if(0>=f&&0<=g&&0>=k)return m=g/(g-k),b.copy(c).addScaledVector(sd,m);g=h*k-a*l;if(0>=g&&0<=l-h&&0<=a-k)return mi.subVectors(e,d),m=(l-h)/(l-h+(a-k)),b.copy(d).addScaledVector(mi,m);e=1/(g+f+m);d=f*e;m*=e;return b.copy(c).addScaledVector(rd,d).addScaledVector(sd,m)},equals:function(a){return a.a.equals(this.a)&& +a.b.equals(this.b)&&a.c.equals(this.c)}});var ok={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017, +darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504, +green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734, +lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734, +palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407, +steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},Aa={h:0,s:0,l:0},xf={h:0,s:0,l:0};Object.assign(J.prototype,{isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a=Math.floor(a); +this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){a=O.euclideanModulo(a,1);b=O.clamp(b,0,1);c=O.clamp(c,0,1);0===b?this.r=this.g=this.b=c:(b=.5>=c?c*(1+b):c+b-c*b,c=2*c-b,this.r=Sf(c,b,a+1/3),this.g=Sf(c,b,a),this.b=Sf(c,b,a-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)){d=parseFloat(c[1])/360;var e=parseInt(c[2],10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}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=h?l/(e+f):l/(2-e-f);switch(e){case b:g=(c- +d)/l+(cthis.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;d.stencilWrite=this.stencilWrite;d.stencilFunc= +this.stencilFunc;d.stencilRef=this.stencilRef;d.stencilMask=this.stencilMask;d.stencilFail=this.stencilFail;d.stencilZFail=this.stencilZFail;d.stencilZPass=this.stencilZPass;this.rotation&&0!==this.rotation&&(d.rotation=this.rotation);!0===this.polygonOffset&&(d.polygonOffset=!0);0!==this.polygonOffsetFactor&&(d.polygonOffsetFactor=this.polygonOffsetFactor);0!==this.polygonOffsetUnits&&(d.polygonOffsetUnits=this.polygonOffsetUnits);this.linewidth&&1!==this.linewidth&&(d.linewidth=this.linewidth); +void 0!==this.dashSize&&(d.dashSize=this.dashSize);void 0!==this.gapSize&&(d.gapSize=this.gapSize);void 0!==this.scale&&(d.scale=this.scale);!0===this.dithering&&(d.dithering=!0);0g;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;c\n\t#include \n}", +fragmentShader:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}",side:1,blending:0});d.uniforms.tEquirect.value=b;b=new ra(new Bb(5, +5,5),d);c.add(b);d=new Dc(1,10,1);d.renderTarget=this;d.renderTarget.texture.name="CubeCameraTexture";d.update(a,c);b.geometry.dispose();b.material.dispose();return this};Zb.prototype=Object.create(ba.prototype);Zb.prototype.constructor=Zb;Zb.prototype.isDataTexture=!0;var Ug=new n,qk=new n,rk=new ta;Object.assign(cb.prototype,{isPlane:!0,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(a,b,c){b=Ug.subVectors(c,b).cross(qk.subVectors(a,b)).normalize();this.setFromNormalAndCoplanarPoint(b,a);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*= +-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){void 0===b&&(console.warn("THREE.Plane: .projectPoint() target is now required"),b=new n);return b.copy(this.normal).multiplyScalar(-this.distanceToPoint(a)).add(a)},intersectLine:function(a,b){void 0===b&&(console.warn("THREE.Plane: .intersectLine() target is now required"),b=new n);var c= +a.delta(Ug),d=this.normal.dot(c);if(0===d){if(0===this.distanceToPoint(a.start))return b.copy(a.start)}else if(d=-(a.start.dot(this.normal)+this.constant)/d,!(0>d||1b&&0a&&0c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],l=c[6],k=c[7],n=c[8],u=c[9],r=c[10],q=c[11],t=c[12],y=c[13],w=c[14];c=c[15];b[0].setComponents(f-a,k-g,q-n,c-t).normalize();b[1].setComponents(f+a,k+g,q+n,c+t).normalize();b[2].setComponents(f+ +d,k+h,q+u,c+y).normalize();b[3].setComponents(f-d,k-h,q-u,c-y).normalize();b[4].setComponents(f-e,k-l,q-r,c-w).normalize();b[5].setComponents(f+e,k+l,q+r,c+w).normalize();return this},intersectsObject:function(a){var b=a.geometry;null===b.boundingSphere&&b.computeBoundingSphere();td.copy(b.boundingSphere).applyMatrix4(a.matrixWorld);return this.intersectsSphere(td)},intersectsSprite:function(a){td.center.set(0,0,0);td.radius=.7071067811865476;td.applyMatrix4(a.matrixWorld);return this.intersectsSphere(td)}, +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)c;c++){var d=b[c];Af.x=0d.distanceToPoint(Af))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}});var K={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif", +alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif",aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif", +aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif",begin_vertex:"vec3 transformed = vec3( position );",beginnormal_vertex:"vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif",bsdfs:"vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif", +bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif", +clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif", +clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif", +color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}", +cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif", +defaultnormal_vertex:"vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = normalMatrix * objectTangent;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif", +emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",encodings_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",encodings_pars_fragment:"\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}", +envmap_fragment:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif", +envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif", +envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, roughness );\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif", +envmap_vertex:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif",fog_vertex:"#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif", +fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif", +gradientmap_pars_fragment:"#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif", +lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_vertex:"vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif", +lights_pars_begin:"uniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif", +lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)", +lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = saturate( clearcoat );\tmaterial.clearcoatRoughness = clamp( clearcoatRoughness, 0.04, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif", +lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}", +lights_fragment_begin:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif", +lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif", +lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n#endif", +logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif",map_fragment:"#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif", +map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",map_particle_fragment:"#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif",map_particle_pars_fragment:"#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif", +metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif", +morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif", +normal_fragment_begin:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;", +normal_fragment_maps:"#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, normalScale, normalMap );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif", +normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec2 normalScale, in sampler2D normalMap ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy *= normalScale;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvec3 NfromST = cross( S, T );\n\t\t\tif( dot( NfromST, N ) > 0.0 ) {\n\t\t\t\tS *= -1.0;\n\t\t\t\tT *= -1.0;\n\t\t\t}\n\t\t#else\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif", +clearcoat_normal_fragment_begin:"#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif",clearcoat_normal_fragment_maps:"#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, clearcoatNormal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = clearcoatNormalScale * mapN.xy;\n\t\tclearcoatNormal = normalize( vTBN * mapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatNormalScale, clearcoatNormalMap );\n\t#endif\n#endif", +clearcoat_normalmap_pars_fragment:"#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif",packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 encodeHalfRGBA ( vec2 v ) {\n\tvec4 encoded = vec4( 0.0 );\n\tconst vec2 offset = vec2( 1.0 / 255.0, 0.0 );\n\tencoded.xy = vec2( v.x, fract( v.x * 255.0 ) );\n\tencoded.xy = encoded.xy - ( encoded.yy * offset );\n\tencoded.zw = vec2( v.y, fract( v.y * 255.0 ) );\n\tencoded.zw = encoded.zw - ( encoded.ww * offset );\n\treturn encoded;\n}\nvec2 decodeHalfRGBA( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}", +premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif", +roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn decodeHalfRGBA( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = ( floor( uv * size - 0.5 ) + 0.5 ) * texelSize;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif", +shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif", +shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif", +shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}", +skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif", +skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif", +specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}", +uv_pars_fragment:"#ifdef USE_UV\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#ifdef USE_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif",uv_vertex:"#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif",uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif", +worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif",background_frag:"uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}",background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}", +cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}",cube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}", +depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}", +depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +distanceRGBA_frag:"#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}", +distanceRGBA_vert:"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}", +equirect_frag:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}", +equirect_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}",linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}", +meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshbasic_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshlambert_frag:"uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshlambert_vert:"#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshmatcap_frag:"#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshmatcap_vert:"#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}", +meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshphysical_frag:"#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSPARENCY\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSPARENCY\n\tuniform float transparency;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSPARENCY\n\t\tdiffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshphysical_vert:"#define STANDARD\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}", +normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}", +normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}", +points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +points_vert:"uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}", +shadow_frag:"uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}",shadow_vert:"#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}", +sprite_vert:"uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"}, +H={common:{diffuse:{value:new J(15658734)},opacity:{value:1},map:{value:null},uvTransform:{value:new ta},alphaMap:{value:null}},specularmap:{specularMap:{value:null}},envmap:{envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},refractionRatio:{value:.98},maxMipLevel:{value:0}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1}},emissivemap:{emissiveMap:{value:null}},bumpmap:{bumpMap:{value:null},bumpScale:{value:1}},normalmap:{normalMap:{value:null}, +normalScale:{value:new v(1,1)}},displacementmap:{displacementMap:{value:null},displacementScale:{value:1},displacementBias:{value:0}},roughnessmap:{roughnessMap:{value:null}},metalnessmap:{metalnessMap:{value:null}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:2.5E-4},fogNear:{value:1},fogFar:{value:2E3},fogColor:{value:new J(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{},shadow:{},shadowBias:{}, +shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},spotShadowMap:{value:[]},spotShadowMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}}, +pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}}},points:{diffuse:{value:new J(15658734)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},uvTransform:{value:new ta}},sprite:{diffuse:{value:new J(15658734)},opacity:{value:1},center:{value:new v(.5,.5)},rotation:{value:0},map:{value:null},uvTransform:{value:new ta}}}, +db={basic:{uniforms:ka([H.common,H.specularmap,H.envmap,H.aomap,H.lightmap,H.fog]),vertexShader:K.meshbasic_vert,fragmentShader:K.meshbasic_frag},lambert:{uniforms:ka([H.common,H.specularmap,H.envmap,H.aomap,H.lightmap,H.emissivemap,H.fog,H.lights,{emissive:{value:new J(0)}}]),vertexShader:K.meshlambert_vert,fragmentShader:K.meshlambert_frag},phong:{uniforms:ka([H.common,H.specularmap,H.envmap,H.aomap,H.lightmap,H.emissivemap,H.bumpmap,H.normalmap,H.displacementmap,H.gradientmap,H.fog,H.lights,{emissive:{value:new J(0)}, +specular:{value:new J(1118481)},shininess:{value:30}}]),vertexShader:K.meshphong_vert,fragmentShader:K.meshphong_frag},standard:{uniforms:ka([H.common,H.envmap,H.aomap,H.lightmap,H.emissivemap,H.bumpmap,H.normalmap,H.displacementmap,H.roughnessmap,H.metalnessmap,H.fog,H.lights,{emissive:{value:new J(0)},roughness:{value:.5},metalness:{value:.5},envMapIntensity:{value:1}}]),vertexShader:K.meshphysical_vert,fragmentShader:K.meshphysical_frag},matcap:{uniforms:ka([H.common,H.bumpmap,H.normalmap,H.displacementmap, +H.fog,{matcap:{value:null}}]),vertexShader:K.meshmatcap_vert,fragmentShader:K.meshmatcap_frag},points:{uniforms:ka([H.points,H.fog]),vertexShader:K.points_vert,fragmentShader:K.points_frag},dashed:{uniforms:ka([H.common,H.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:K.linedashed_vert,fragmentShader:K.linedashed_frag},depth:{uniforms:ka([H.common,H.displacementmap]),vertexShader:K.depth_vert,fragmentShader:K.depth_frag},normal:{uniforms:ka([H.common,H.bumpmap,H.normalmap, +H.displacementmap,{opacity:{value:1}}]),vertexShader:K.normal_vert,fragmentShader:K.normal_frag},sprite:{uniforms:ka([H.sprite,H.fog]),vertexShader:K.sprite_vert,fragmentShader:K.sprite_frag},background:{uniforms:{uvTransform:{value:new ta},t2D:{value:null}},vertexShader:K.background_vert,fragmentShader:K.background_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:K.cube_vert,fragmentShader:K.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:K.equirect_vert, +fragmentShader:K.equirect_frag},distanceRGBA:{uniforms:ka([H.common,H.displacementmap,{referencePosition:{value:new n},nearDistance:{value:1},farDistance:{value:1E3}}]),vertexShader:K.distanceRGBA_vert,fragmentShader:K.distanceRGBA_frag},shadow:{uniforms:ka([H.lights,H.fog,{color:{value:new J(0)},opacity:{value:1}}]),vertexShader:K.shadow_vert,fragmentShader:K.shadow_frag}};db.physical={uniforms:ka([db.standard.uniforms,{transparency:{value:0},clearcoat:{value:0},clearcoatRoughness:{value:0},sheen:{value:new J(0)}, +clearcoatNormalScale:{value:new v(1,1)},clearcoatNormalMap:{value:null}}]),vertexShader:K.meshphysical_vert,fragmentShader:K.meshphysical_frag};Fd.prototype=Object.create(G.prototype);Fd.prototype.constructor=Fd;$b.prototype=Object.create(D.prototype);$b.prototype.constructor=$b;pb.prototype=Object.create(ba.prototype);pb.prototype.constructor=pb;pb.prototype.isCubeTexture=!0;Object.defineProperty(pb.prototype,"images",{get:function(){return this.image},set:function(a){this.image=a}});Ec.prototype= +Object.create(ba.prototype);Ec.prototype.constructor=Ec;Ec.prototype.isDataTexture2DArray=!0;Fc.prototype=Object.create(ba.prototype);Fc.prototype.constructor=Fc;Fc.prototype.isDataTexture3D=!0;var qh=new ba,kj=new Ec,mj=new Fc,rh=new pb,kh=[],mh=[],ph=new Float32Array(16),oh=new Float32Array(9),nh=new Float32Array(4);sh.prototype.updateCache=function(a){var b=this.cache;a instanceof Float32Array&&b.length!==a.length&&(this.cache=new Float32Array(a.length));Ga(b,a)};th.prototype.setValue=function(a, +b,c){for(var d=this.seq,e=0,f=d.length;e!==f;++e){var g=d[e];g.setValue(a,b[g.id],c)}};var $f=/([\w\d_]+)(\])?(\[|\.)?/g;Db.prototype.setValue=function(a,b,c,d){b=this.map[b];void 0!==b&&b.setValue(a,c,d)};Db.prototype.setOptional=function(a,b,c){b=b[c];void 0!==b&&this.setValue(a,c,b)};Db.upload=function(a,b,c,d){for(var e=0,f=b.length;e!==f;++e){var g=b[e],h=c[g.id];!1!==h.needsUpdate&&g.setValue(a,h.value,d)}};Db.seqWithValue=function(a,b){for(var c=[],d=0,e=a.length;d!==e;++d){var f=a[d];f.id in +b&&c.push(f)}return c};var Nj=0,Wj=0;Eb.prototype=Object.create(Q.prototype);Eb.prototype.constructor=Eb;Eb.prototype.isMeshDepthMaterial=!0;Eb.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.depthPacking=a.depthPacking;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth= +a.wireframeLinewidth;return this};Fb.prototype=Object.create(Q.prototype);Fb.prototype.constructor=Fb;Fb.prototype.isMeshDistanceMaterial=!0;Fb.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.referencePosition.copy(a.referencePosition);this.nearDistance=a.nearDistance;this.farDistance=a.farDistance;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias= +a.displacementBias;return this};Hc.prototype=Object.assign(Object.create(B.prototype),{constructor:Hc,isGroup:!0});Id.prototype=Object.assign(Object.create(la.prototype),{constructor:Id,isArrayCamera:!0});var Gh=new n,Hh=new n;Object.assign(cg.prototype,xa.prototype);Object.assign(Ih.prototype,xa.prototype);Object.assign(Je.prototype,{isFogExp2:!0,clone:function(){return new Je(this.color,this.density)},toJSON:function(){return{type:"FogExp2",color:this.color.getHex(),density:this.density}}});Object.assign(Ke.prototype, +{isFog:!0,clone:function(){return new Ke(this.color,this.near,this.far)},toJSON:function(){return{type:"Fog",color:this.color.getHex(),near:this.near,far:this.far}}});Object.defineProperty(ac.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(ac.prototype,{isInterleavedBuffer:!0,onUploadCallback:function(){},setArray:function(a){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.count=void 0!==a?a.length/this.stride: +0;this.array=a;return this},setDynamic:function(a){this.dynamic=a;return this},copy:function(a){this.array=new a.array.constructor(a.array);this.count=a.count;this.stride=a.stride;this.dynamic=a.dynamic;return this},copyAt:function(a,b,c){a*=this.stride;c*=b.stride;for(var d=0,e=this.stride;da.far||b.push({distance:e,point:ye.clone(),uv:ia.getUV(ye,Bf,ze,Cf,oi,Vg,pi,new v),face:null,object:this})},clone:function(){return(new this.constructor(this.material)).copy(this)},copy:function(a){B.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});var Df=new n,qi=new n;Md.prototype=Object.assign(Object.create(B.prototype),{constructor:Md,isLOD:!0,copy:function(a){B.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b=b[c].distance)b[c-1].object.visible=!1,b[c].object.visible=!0;else break;for(;cc||(h.applyMatrix4(this.matrixWorld),r=a.ray.origin.distanceTo(h),ra.far||b.push({distance:r,point:e.clone().applyMatrix4(this.matrixWorld),index:d,face:null,faceIndex:null,object:this}))}}else for(d=0,u=p.length/3-1;dc||(h.applyMatrix4(this.matrixWorld),r=a.ray.origin.distanceTo(h),ra.far||b.push({distance:r,point:e.clone().applyMatrix4(this.matrixWorld), +index:d,face:null,faceIndex:null,object:this}))}else if(d.isGeometry)for(f=d.vertices,g=f.length,d=0;dc||(h.applyMatrix4(this.matrixWorld),r=a.ray.origin.distanceTo(h),ra.far||b.push({distance:r,point:e.clone().applyMatrix4(this.matrixWorld),index:d,face:null,faceIndex:null,object:this}))}},clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});var Ff=new n,Gf=new n;R.prototype=Object.assign(Object.create(ca.prototype), +{constructor:R,isLineSegments:!0,computeLineDistances:function(){var a=this.geometry;if(a.isBufferGeometry)if(null===a.index){for(var b=a.attributes.position,c=[],d=0,e=b.count;d=a.HAVE_CURRENT_DATA&& +(this.needsUpdate=!0)}});Lc.prototype=Object.create(ba.prototype);Lc.prototype.constructor=Lc;Lc.prototype.isCompressedTexture=!0;Od.prototype=Object.create(ba.prototype);Od.prototype.constructor=Od;Od.prototype.isCanvasTexture=!0;Pd.prototype=Object.create(ba.prototype);Pd.prototype.constructor=Pd;Pd.prototype.isDepthTexture=!0;Mc.prototype=Object.create(D.prototype);Mc.prototype.constructor=Mc;Qd.prototype=Object.create(G.prototype);Qd.prototype.constructor=Qd;Nc.prototype=Object.create(D.prototype); +Nc.prototype.constructor=Nc;Rd.prototype=Object.create(G.prototype);Rd.prototype.constructor=Rd;pa.prototype=Object.create(D.prototype);pa.prototype.constructor=pa;Sd.prototype=Object.create(G.prototype);Sd.prototype.constructor=Sd;Oc.prototype=Object.create(pa.prototype);Oc.prototype.constructor=Oc;Td.prototype=Object.create(G.prototype);Td.prototype.constructor=Td;bc.prototype=Object.create(pa.prototype);bc.prototype.constructor=bc;Ud.prototype=Object.create(G.prototype);Ud.prototype.constructor= +Ud;Pc.prototype=Object.create(pa.prototype);Pc.prototype.constructor=Pc;Vd.prototype=Object.create(G.prototype);Vd.prototype.constructor=Vd;Qc.prototype=Object.create(pa.prototype);Qc.prototype.constructor=Qc;Wd.prototype=Object.create(G.prototype);Wd.prototype.constructor=Wd;cc.prototype=Object.create(D.prototype);cc.prototype.constructor=cc;cc.prototype.toJSON=function(){var a=D.prototype.toJSON.call(this);a.path=this.parameters.path.toJSON();return a};Xd.prototype=Object.create(G.prototype);Xd.prototype.constructor= +Xd;Rc.prototype=Object.create(D.prototype);Rc.prototype.constructor=Rc;Yd.prototype=Object.create(G.prototype);Yd.prototype.constructor=Yd;Sc.prototype=Object.create(D.prototype);Sc.prototype.constructor=Sc;var tk={triangulate:function(a,b,c){c=c||2;var d=b&&b.length,e=d?b[0]*c:a.length,f=Lh(a,0,e,c,!0),g=[];if(!f||f.next===f.prev)return g;var h;if(d){var l=c;d=[];var k;var n=0;for(k=b.length;n80*c){var q=h=a[0];var t=d=a[1];for(l=c;lh&&(h=n),b>d&&(d=b);h=Math.max(h-q,d-t);h=0!==h?1/h:0}ae(f,g,c,q,t,h);return g}},qb={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;eqb.area(a)},triangulateShape:function(a,b){var c=[],d=[],e=[];Ph(a);Qh(c,a);var f=a.length;b.forEach(Ph); +for(a=0;aMath.abs(g-l)?[new v(a,1-c),new v(h,1-d),new v(k,1-e),new v(u,1-b)]:[new v(g,1-c),new v(l,1-d),new v(n,1-e),new v(r,1-b)]}};ce.prototype=Object.create(G.prototype); +ce.prototype.constructor=ce;Uc.prototype=Object.create(eb.prototype);Uc.prototype.constructor=Uc;de.prototype=Object.create(G.prototype);de.prototype.constructor=de;Ib.prototype=Object.create(D.prototype);Ib.prototype.constructor=Ib;ee.prototype=Object.create(G.prototype);ee.prototype.constructor=ee;Vc.prototype=Object.create(D.prototype);Vc.prototype.constructor=Vc;fe.prototype=Object.create(G.prototype);fe.prototype.constructor=fe;Wc.prototype=Object.create(D.prototype);Wc.prototype.constructor= +Wc;fc.prototype=Object.create(G.prototype);fc.prototype.constructor=fc;fc.prototype.toJSON=function(){var a=G.prototype.toJSON.call(this);return Sh(this.parameters.shapes,a)};gc.prototype=Object.create(D.prototype);gc.prototype.constructor=gc;gc.prototype.toJSON=function(){var a=D.prototype.toJSON.call(this);return Sh(this.parameters.shapes,a)};Xc.prototype=Object.create(D.prototype);Xc.prototype.constructor=Xc;hc.prototype=Object.create(G.prototype);hc.prototype.constructor=hc;rb.prototype=Object.create(D.prototype); +rb.prototype.constructor=rb;ge.prototype=Object.create(hc.prototype);ge.prototype.constructor=ge;he.prototype=Object.create(rb.prototype);he.prototype.constructor=he;ie.prototype=Object.create(G.prototype);ie.prototype.constructor=ie;Yc.prototype=Object.create(D.prototype);Yc.prototype.constructor=Yc;var Ba=Object.freeze({WireframeGeometry:Mc,ParametricGeometry:Qd,ParametricBufferGeometry:Nc,TetrahedronGeometry:Sd,TetrahedronBufferGeometry:Oc,OctahedronGeometry:Td,OctahedronBufferGeometry:bc,IcosahedronGeometry:Ud, +IcosahedronBufferGeometry:Pc,DodecahedronGeometry:Vd,DodecahedronBufferGeometry:Qc,PolyhedronGeometry:Rd,PolyhedronBufferGeometry:pa,TubeGeometry:Wd,TubeBufferGeometry:cc,TorusKnotGeometry:Xd,TorusKnotBufferGeometry:Rc,TorusGeometry:Yd,TorusBufferGeometry:Sc,TextGeometry:ce,TextBufferGeometry:Uc,SphereGeometry:de,SphereBufferGeometry:Ib,RingGeometry:ee,RingBufferGeometry:Vc,PlaneGeometry:Fd,PlaneBufferGeometry:$b,LatheGeometry:fe,LatheBufferGeometry:Wc,ShapeGeometry:fc,ShapeBufferGeometry:gc,ExtrudeGeometry:ec, +ExtrudeBufferGeometry:eb,EdgesGeometry:Xc,ConeGeometry:ge,ConeBufferGeometry:he,CylinderGeometry:hc,CylinderBufferGeometry:rb,CircleGeometry:ie,CircleBufferGeometry:Yc,BoxGeometry:Cc,BoxBufferGeometry:Bb});ic.prototype=Object.create(Q.prototype);ic.prototype.constructor=ic;ic.prototype.isShadowMaterial=!0;ic.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.color.copy(a.color);return this};Zc.prototype=Object.create(va.prototype);Zc.prototype.constructor=Zc;Zc.prototype.isRawShaderMaterial= +!0;fb.prototype=Object.create(Q.prototype);fb.prototype.constructor=fb;fb.prototype.isMeshStandardMaterial=!0;fb.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.defines={STANDARD:""};this.color.copy(a.color);this.roughness=a.roughness;this.metalness=a.metalness;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity; +this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.roughnessMap=a.roughnessMap;this.metalnessMap=a.metalnessMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth= +a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};jc.prototype=Object.create(fb.prototype);jc.prototype.constructor=jc;jc.prototype.isMeshPhysicalMaterial=!0;jc.prototype.copy=function(a){fb.prototype.copy.call(this,a);this.defines={STANDARD:"",PHYSICAL:""};this.reflectivity=a.reflectivity;this.clearcoat=a.clearcoat;this.clearcoatRoughness= +a.clearcoatRoughness;this.sheen=a.sheen?(this.sheen||new J).copy(a.sheen):null;this.clearcoatNormalMap=a.clearcoatNormalMap;this.clearcoatNormalScale.copy(a.clearcoatNormalScale);this.transparency=a.transparency;return this};Ra.prototype=Object.create(Q.prototype);Ra.prototype.constructor=Ra;Ra.prototype.isMeshPhongMaterial=!0;Ra.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap= +a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap= +a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};kc.prototype=Object.create(Ra.prototype);kc.prototype.constructor=kc;kc.prototype.isMeshToonMaterial= +!0;kc.prototype.copy=function(a){Ra.prototype.copy.call(this,a);this.gradientMap=a.gradientMap;return this};lc.prototype=Object.create(Q.prototype);lc.prototype.constructor=lc;lc.prototype.isMeshNormalMaterial=!0;lc.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale; +this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};mc.prototype=Object.create(Q.prototype);mc.prototype.constructor=mc;mc.prototype.isMeshLambertMaterial=!0;mc.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap= +a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning; +this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};nc.prototype=Object.create(Q.prototype);nc.prototype.constructor=nc;nc.prototype.isMeshMatcapMaterial=!0;nc.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.defines={MATCAP:""};this.color.copy(a.color);this.matcap=a.matcap;this.map=a.map;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap; +this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.alphaMap=a.alphaMap;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};oc.prototype=Object.create(Y.prototype);oc.prototype.constructor=oc;oc.prototype.isLineDashedMaterial=!0;oc.prototype.copy=function(a){Y.prototype.copy.call(this,a);this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize=a.gapSize;return this};var uk=Object.freeze({ShadowMaterial:ic,SpriteMaterial:Hb, +RawShaderMaterial:Zc,ShaderMaterial:va,PointsMaterial:Qa,MeshPhysicalMaterial:jc,MeshStandardMaterial:fb,MeshPhongMaterial:Ra,MeshToonMaterial:kc,MeshNormalMaterial:lc,MeshLambertMaterial:mc,MeshDepthMaterial:Eb,MeshDistanceMaterial:Fb,MeshBasicMaterial:ya,MeshMatcapMaterial:nc,LineDashedMaterial:oc,LineBasicMaterial:Y,Material:Q}),Z={arraySlice:function(a,b,c){return Z.isTypedArray(a)?new a.constructor(a.subarray(b,void 0!==c?c:a.length)):a.slice(b,c)},convertArray:function(a,b,c){return!a||!c&& +a.constructor===b?a:"number"===typeof b.BYTES_PER_ELEMENT?new b(a):Array.prototype.slice.call(a)},isTypedArray:function(a){return ArrayBuffer.isView(a)&&!(a instanceof DataView)},getKeyframeOrder:function(a){for(var b=a.length,c=Array(b),d=0;d!==b;++d)c[d]=d;c.sort(function(b,c){return a[b]-a[c]});return c},sortedArray:function(a,b,c){for(var d=a.length,e=new a.constructor(d),f=0,g=0;g!==d;++f)for(var h=c[f]*b,l=0;l!==b;++l)e[g++]=a[h+l];return e},flattenJSON:function(a,b,c,d){for(var e=1,f=a[0];void 0!== +f&&void 0===f[d];)f=a[e++];if(void 0!==f){var g=f[d];if(void 0!==g)if(Array.isArray(g)){do g=f[d],void 0!==g&&(b.push(f.time),c.push.apply(c,g)),f=a[e++];while(void 0!==f)}else if(void 0!==g.toArray){do g=f[d],void 0!==g&&(b.push(f.time),g.toArray(c,c.length)),f=a[e++];while(void 0!==f)}else{do g=f[d],void 0!==g&&(b.push(f.time),c.push(g)),f=a[e++];while(void 0!==f)}}}};Object.assign(Ha.prototype,{evaluate:function(a){var b=this.parameterPositions,c=this._cachedIndex,d=b[c],e=b[c-1];a:{b:{c:{d:if(!(a< +d)){for(var f=c+2;;){if(void 0===d){if(a=e)break a;else{f=b[1];a=e)break b}d=c;c=0}}for(;c>>1,ab;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),a=this.getValueSize(),this.times=Z.arraySlice(c,e,f),this.values=Z.arraySlice(this.values,e*a,f*a);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),a=!1);var c=this.times; +b=this.values;var d=c.length;0===d&&(console.error("THREE.KeyframeTrack: Track is empty.",this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if("number"===typeof g&&isNaN(g)){console.error("THREE.KeyframeTrack: Time is not a valid number.",this,f,g);a=!1;break}if(null!==e&&e>g){console.error("THREE.KeyframeTrack: Out of order keys.",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&Z.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("THREE.KeyframeTrack: Value is not a valid number.", +this,f,d);a=!1;break}return a},optimize:function(){for(var a=this.times,b=this.values,c=this.getValueSize(),d=2302===this.getInterpolation(),e=1,f=a.length-1,g=1;gg)e=a+1;else if(0b&&(b=0);1Number.EPSILON&&(g.normalize(),c=Math.acos(O.clamp(d[l-1].dot(d[l]),-1,1)),e[l].applyMatrix4(h.makeRotationAxis(g,c))),f[l].crossVectors(d[l], +e[l]);if(!0===b)for(c=Math.acos(O.clamp(e[0].dot(e[a]),-1,1)),c/=a,0d;)d+=c;for(;d>c;)d-=c;de&&(e=1);1E-4>d&&(d=e);1E-4>l&&(l=e);Wg.initNonuniformCatmullRom(f.x,g.x,h.x,c.x,d,e,l);Xg.initNonuniformCatmullRom(f.y,g.y,h.y,c.y,d,e,l);Yg.initNonuniformCatmullRom(f.z,g.z,h.z,c.z,d, +e,l)}else"catmullrom"===this.curveType&&(Wg.initCatmullRom(f.x,g.x,h.x,c.x,this.tension),Xg.initCatmullRom(f.y,g.y,h.y,c.y,this.tension),Yg.initCatmullRom(f.z,g.z,h.z,c.z,this.tension));b.set(Wg.calc(a),Xg.calc(a),Yg.calc(a));return b};sa.prototype.copy=function(a){F.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;bc.length-2?c.length-1:a+1];c=c[a>c.length-3?c.length-1:a+2];b.set(Uh(d,e.x,f.x,g.x, +c.x),Uh(d,e.y,f.y,g.y,c.y));return b};Va.prototype.copy=function(a){F.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;b=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null},getLength:function(){var a=this.getCurveLengths();return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=!0;this.cacheLengths=null;this.getCurveLengths()},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;cNumber.EPSILON){if(0>k&&(g=b[f],l=-l,h=b[e],k=-k),!(a.yh.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e=k*(a.x-g.x)-l*(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=qb.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);b=[];if(1===f.length){var g=f[0];var h=new Jb;h.curves=g.curves;b.push(h);return b}var l=!e(f[0].getPoints());l=a?!l:l;h=[];var k=[],n=[],u=0;k[u]=void 0;n[u]=[];for(var r=0,q=f.length;rb;b++)this.coefficients[b].copy(a[b]);return this},zero:function(){for(var a=0;9>a;a++)this.coefficients[a].set(0, +0,0);return this},getAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.282095);b.addScale(e[1],.488603*d);b.addScale(e[2],.488603*a);b.addScale(e[3],.488603*c);b.addScale(e[4],1.092548*c*d);b.addScale(e[5],1.092548*d*a);b.addScale(e[6],.315392*(3*a*a-1));b.addScale(e[7],1.092548*c*a);b.addScale(e[8],.546274*(c*c-d*d));return b},getIrradianceAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.886227);b.addScale(e[1], +1.023328*d);b.addScale(e[2],1.023328*a);b.addScale(e[3],1.023328*c);b.addScale(e[4],.858086*c*d);b.addScale(e[5],.858086*d*a);b.addScale(e[6],.743125*a*a-.247708);b.addScale(e[7],.858086*c*a);b.addScale(e[8],.429043*(c*c-d*d));return b},add:function(a){for(var b=0;9>b;b++)this.coefficients[b].add(a.coefficients[b]);return this},scale:function(a){for(var b=0;9>b;b++)this.coefficients[b].multiplyScalar(a);return this},lerp:function(a,b){for(var c=0;9>c;c++)this.coefficients[c].lerp(a.coefficients[c], +b);return this},equals:function(a){for(var b=0;9>b;b++)if(!this.coefficients[b].equals(a.coefficients[b]))return!1;return!0},copy:function(a){return this.set(a.coefficients)},clone:function(){return(new this.constructor).copy(this)},fromArray:function(a,b){void 0===b&&(b=0);for(var c=this.coefficients,d=0;9>d;d++)c[d].fromArray(a,b+3*d);return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);for(var c=this.coefficients,d=0;9>d;d++)c[d].toArray(a,b+3*d);return a}});Object.assign(lf, +{getBasisAt:function(a,b){var c=a.x,d=a.y;a=a.z;b[0]=.282095;b[1]=.488603*d;b[2]=.488603*a;b[3]=.488603*c;b[4]=1.092548*c*d;b[5]=1.092548*d*a;b[6]=.315392*(3*a*a-1);b[7]=1.092548*c*a;b[8]=.546274*(c*c-d*d)}});Xa.prototype=Object.assign(Object.create(V.prototype),{constructor:Xa,isLightProbe:!0,copy:function(a){V.prototype.copy.call(this,a);this.sh.copy(a.sh);this.intensity=a.intensity;return this},toJSON:function(a){return V.prototype.toJSON.call(this,a)}});tg.prototype=Object.assign(Object.create(Xa.prototype), +{constructor:tg,isHemisphereLightProbe:!0,copy:function(a){Xa.prototype.copy.call(this,a);return this},toJSON:function(a){return Xa.prototype.toJSON.call(this,a)}});ug.prototype=Object.assign(Object.create(Xa.prototype),{constructor:ug,isAmbientLightProbe:!0,copy:function(a){Xa.prototype.copy.call(this,a);return this},toJSON:function(a){return Xa.prototype.toJSON.call(this,a)}});var yi=new P,zi=new P;Object.assign(Vh.prototype,{update:function(a){var b=this._cache;if(b.focus!==a.focus||b.fov!==a.fov|| +b.aspect!==a.aspect*this.aspect||b.near!==a.near||b.far!==a.far||b.zoom!==a.zoom||b.eyeSep!==this.eyeSep){b.focus=a.focus;b.fov=a.fov;b.aspect=a.aspect*this.aspect;b.near=a.near;b.far=a.far;b.zoom=a.zoom;b.eyeSep=this.eyeSep;var c=a.projectionMatrix.clone(),d=b.eyeSep/2,e=d*b.near/b.focus,f=b.near*Math.tan(O.DEG2RAD*b.fov*.5)/b.zoom;zi.elements[12]=-d;yi.elements[12]=d;d=-f*b.aspect+e;var g=f*b.aspect+e;c.elements[0]=2*b.near/(g-d);c.elements[8]=(g+d)/(g-d);this.cameraL.projectionMatrix.copy(c);d= +-f*b.aspect-e;g=f*b.aspect-e;c.elements[0]=2*b.near/(g-d);c.elements[8]=(g+d)/(g-d);this.cameraR.projectionMatrix.copy(c)}this.cameraL.matrixWorld.copy(a.matrixWorld).multiply(zi);this.cameraR.matrixWorld.copy(a.matrixWorld).multiply(yi)}});Object.assign(vg.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now();this.elapsedTime=0;this.running=!0},stop:function(){this.getElapsedTime();this.autoStart=this.running=!1},getElapsedTime:function(){this.getDelta(); +return this.elapsedTime},getDelta:function(){var a=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance?Date:performance).now();a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});var uc=new n,Ai=new na,wk=new n,vc=new n;wg.prototype=Object.assign(Object.create(B.prototype),{constructor:wg,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination), +this.gain.connect(this.context.destination),this.filter=null);return this},getFilter:function(){return this.filter},setFilter:function(a){null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination);this.filter=a;this.gain.connect(this.filter);this.filter.connect(this.context.destination);return this},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(a){this.gain.gain.setTargetAtTime(a, +this.context.currentTime,.01);return this},updateMatrixWorld:function(a){B.prototype.updateMatrixWorld.call(this,a);a=this.context.listener;var b=this.up;this.timeDelta=this._clock.getDelta();this.matrixWorld.decompose(uc,Ai,wk);vc.set(0,0,-1).applyQuaternion(Ai);if(a.positionX){var c=this.context.currentTime+this.timeDelta;a.positionX.linearRampToValueAtTime(uc.x,c);a.positionY.linearRampToValueAtTime(uc.y,c);a.positionZ.linearRampToValueAtTime(uc.z,c);a.forwardX.linearRampToValueAtTime(vc.x,c); +a.forwardY.linearRampToValueAtTime(vc.y,c);a.forwardZ.linearRampToValueAtTime(vc.z,c);a.upX.linearRampToValueAtTime(b.x,c);a.upY.linearRampToValueAtTime(b.y,c);a.upZ.linearRampToValueAtTime(b.z,c)}else a.setPosition(uc.x,uc.y,uc.z),a.setOrientation(vc.x,vc.y,vc.z,b.x,b.y,b.z)}});dd.prototype=Object.assign(Object.create(B.prototype),{constructor:dd,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=!1;this.sourceType="audioNode";this.source=a;this.connect();return this}, +setMediaElementSource:function(a){this.hasPlaybackControl=!1;this.sourceType="mediaNode";this.source=this.context.createMediaElementSource(a);this.connect();return this},setBuffer:function(a){this.buffer=a;this.sourceType="buffer";this.autoplay&&this.play();return this},play:function(){if(!0===this.isPlaying)console.warn("THREE.Audio: Audio is already playing.");else if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else{var a=this.context.createBufferSource(); +a.buffer=this.buffer;a.loop=this.loop;a.onended=this.onEnded.bind(this);this.startTime=this.context.currentTime;a.start(this.startTime,this.offset,this.duration);this.isPlaying=!0;this.source=a;this.setDetune(this.detune);this.setPlaybackRate(this.playbackRate);return this.connect()}},pause:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return!0===this.isPlaying&&(this.source.stop(),this.source.onended=null,this.offset+=(this.context.currentTime- +this.startTime)*this.playbackRate,this.isPlaying=!1),this},stop:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this.source.stop(),this.source.onended=null,this.offset=0,this.isPlaying=!1,this},connect:function(){if(0d&&this._mixBufferRegion(c,a,3*b,1-d,b);d=b;for(var f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a,c);for(var d=b;d!==c;++d)a[d]=a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a,b,c,d,e){if(.5<=d)for(d= +0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d){na.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d,e){for(var f=1-d,g=0;g!==e;++g){var h=b+g;a[h]=a[h]*f+a[c+g]*d}}});var yk=/[\[\]\.:\/]/g,zk="[^"+"\\[\\]\\.:\\/".replace("\\.","")+"]",Ak=/((?:WC+[\/:])*)/.source.replace("WC","[^\\[\\]\\.:\\/]"),Bk=/(WCOD+)?/.source.replace("WCOD",zk),Ck=/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC","[^\\[\\]\\.:\\/]"),Dk=/\.(WC+)(?:\[(.+)\])?/.source.replace("WC","[^\\[\\]\\.:\\/]"),Ek=new RegExp("^"+Ak+Bk+ +Ck+Dk+"$"),Fk=["material","materials","bones"];Object.assign(Wh.prototype,{getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a,b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_, +c=a.length;b!==c;++b)a[b].unbind()}});Object.assign(ma,{Composite:Wh,create:function(a,b,c){return a&&a.isAnimationObjectGroup?new ma.Composite(a,b,c):new ma(a,b,c)},sanitizeNodeName:function(a){return a.replace(/\s/g,"_").replace(yk,"")},parseTrackName:function(a){var b=Ek.exec(a);if(!b)throw Error("PropertyBinding: Cannot parse trackName: "+a);b={nodeName:b[2],objectName:b[3],objectIndex:b[4],propertyName:b[5],propertyIndex:b[6]};var c=b.nodeName&&b.nodeName.lastIndexOf(".");if(void 0!==c&&-1!== +c){var d=b.nodeName.substring(c+1);-1!==Fk.indexOf(d)&&(b.nodeName=b.nodeName.substring(0,c),b.objectName=d)}if(null===b.propertyName||0===b.propertyName.length)throw Error("PropertyBinding: can not parse propertyName from trackName: "+a);return b},findNode:function(a,b){if(!b||""===b||"root"===b||"."===b||-1===b||b===a.name||b===a.uuid)return a;if(a.skeleton){var c=a.skeleton.getBoneByName(b);if(void 0!==c)return c}if(a.children){var d=function(a){for(var c=0;c=b){var n=b++,u=a[n];c[u.uuid]=m;a[m]=u;c[k]=n;a[n]=h;h=0;for(k=e;h!==k;++h){u=d[h];var r=u[m];u[m]=u[n];u[n]=r}}}this.nCachedObjects_=b},uncache:function(){for(var a=this._objects,b=a.length,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,h=arguments.length;g!==h;++g){var k=arguments[g].uuid,m=d[k];if(void 0!==m)if(delete d[k],mb||0===c)return;this._startTime=null;b*=c}b*=this._updateTimeScale(a);c=this._updateTime(b);a=this._updateWeight(a);if(0c.parameterPositions[1]&&(this.stopFading(),0===d&&(this.enabled=!1))}}return this._effectiveWeight=b},_updateTimeScale:function(a){var b=0;if(!this.paused){b=this.timeScale;var c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0]; +b*=d;a>c.parameterPositions[1]&&(this.stopWarping(),0===b?this.paused=!0:this.timeScale=b)}}return this._effectiveTimeScale=b},_updateTime:function(a){var b=this.time+a,c=this._clip.duration,d=this.loop,e=this._loopCount,f=2202===d;if(0===a)return-1===e?b:f&&1===(e&1)?c-b:b;if(2200===d)a:{if(-1===e&&(this._loopCount=0,this._setEndings(!0,!0,!1)),b>=c)b=c;else if(0>b)b=0;else{this.time=b;break a}this.clampWhenFinished?this.paused=!0:this.enabled=!1;this.time=b;this._mixer.dispatchEvent({type:"finished", +action:this,direction:0>a?-1:1})}else{-1===e&&(0<=a?(e=0,this._setEndings(!0,0===this.repetitions,f)):this._setEndings(0===this.repetitions,!0,f));if(b>=c||0>b){d=Math.floor(b/c);b-=c*d;e+=Math.abs(d);var g=this.repetitions-e;0>=g?(this.clampWhenFinished?this.paused=!0:this.enabled=!1,this.time=b=0a,this._setEndings(a,!a,f)):this._setEndings(!1,!1,f),this._loopCount=e,this.time=b,this._mixer.dispatchEvent({type:"loop", +action:this,loopDelta:d}))}else this.time=b;if(f&&1===(e&1))return c-b}return b},_setEndings:function(a,b,c){var d=this._interpolantSettings;c?(d.endingStart=2401,d.endingEnd=2401):(d.endingStart=a?this.zeroSlopeAtStart?2401:2400:2402,d.endingEnd=b?this.zeroSlopeAtEnd?2401:2400:2402)},_scheduleFading:function(a,b,c){var d=this._mixer,e=d.time,f=this._weightInterpolant;null===f&&(this._weightInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions;f=f.sampleValues;d[0]=e;f[0]=b;d[1]=e+a;f[1]= +c;return this}});Bg.prototype=Object.assign(Object.create(xa.prototype),{constructor:Bg,_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings;a=a._interpolants;var g=c.uuid,h=this._bindingsByRootAndName,k=h[g];void 0===k&&(k={},h[g]=k);for(h=0;h!==e;++h){var m=d[h],n=m.name,u=k[n];if(void 0===u){u=f[h];if(void 0!==u){null===u._cacheIndex&&(++u.referenceCount,this._addInactiveBinding(u,g,n));continue}u=new Ag(ma.create(c,n,b&&b._propertyBindings[h].binding.parsedPath), +m.ValueTypeName,m.getValueSize());++u.referenceCount;this._addInactiveBinding(u,g,n)}f[h]=u;a[h].resultBuffer=u.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid,c=a._clip.uuid,d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];0===e.useCount++&&(this._lendBinding(e),e.saveOriginalState())}this._lendAction(a)}}, +_deactivateAction:function(a){if(this._isActiveAction(a)){for(var b=a._propertyBindings,c=0,d=b.length;c!==d;++c){var e=b[c];0===--e.useCount&&(e.restoreOriginalState(),this._takeBackBinding(e))}this._takeBackAction(a)}},_initMemoryManager:function(){this._actions=[];this._nActiveActions=0;this._actionsByClip={};this._bindings=[];this._nActiveBindings=0;this._bindingsByRootAndName={};this._controlInterpolants=[];this._nActiveControlInterpolants=0;var a=this;this.stats={actions:{get total(){return a._actions.length}, +get inUse(){return a._nActiveActions}},bindings:{get total(){return a._bindings.length},get inUse(){return a._nActiveBindings}},controlInterpolants:{get total(){return a._controlInterpolants.length},get inUse(){return a._nActiveControlInterpolants}}}},_isActiveAction:function(a){a=a._cacheIndex;return null!==a&&athis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box2: .getParameter() target is now required"), +b=new v);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y?!1:!0},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box2: .clampPoint() target is now required"),b=new v);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return Ci.copy(a).clamp(this.min,this.max).sub(a).length()},intersect:function(a){this.min.max(a.min); +this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});var Di=new n,Kf=new n;Object.assign(Fg.prototype,{set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},getCenter:function(a){void 0=== +a&&(console.warn("THREE.Line3: .getCenter() target is now required"),a=new n);return a.addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){void 0===a&&(console.warn("THREE.Line3: .delta() target is now required"),a=new n);return a.subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a,b){void 0===b&&(console.warn("THREE.Line3: .at() target is now required"),b= +new n);return this.delta(b).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(a,b){Di.subVectors(a,this.start);Kf.subVectors(this.end,this.start);a=Kf.dot(Kf);a=Kf.dot(Di)/a;b&&(a=O.clamp(a,0,1));return a},closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);void 0===c&&(console.warn("THREE.Line3: .closestPointToPoint() target is now required"),c=new n);return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a); +this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}});oe.prototype=Object.create(B.prototype);oe.prototype.constructor=oe;oe.prototype.isImmediateRenderObject=!0;var mb=new n,Ab=new n,bh=new ta,Gk=["a","b","c"];pe.prototype=Object.create(R.prototype);pe.prototype.constructor=pe;pe.prototype.update=function(){this.object.updateMatrixWorld(!0);bh.getNormalMatrix(this.object.matrixWorld);var a=this.object.matrixWorld,b=this.geometry.attributes.position, +c=this.object.geometry;if(c&&c.isGeometry)for(var d=c.vertices,e=c.faces,f=c=0,g=e.length;f +Math.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side=0>b?1:0;this.lookAt(this.plane.normal);B.prototype.updateMatrixWorld.call(this,a)};var Ki=new n,qf,Gg;ub.prototype=Object.create(B.prototype);ub.prototype.constructor=ub;ub.prototype.setDirection=function(a){.99999a.y?this.quaternion.set(1,0,0,0):(Ki.set(a.z,0,-a.x).normalize(),this.quaternion.setFromAxisAngle(Ki,Math.acos(a.y)))};ub.prototype.setLength=function(a, +b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};ub.prototype.setColor=function(a){this.line.material.color.set(a);this.cone.material.color.set(a)};ub.prototype.copy=function(a){B.prototype.copy.call(this,a,!1);this.line.copy(a.line);this.cone.copy(a.cone);return this};ub.prototype.clone=function(){return(new this.constructor).copy(this)};ue.prototype=Object.create(R.prototype); +ue.prototype.constructor=ue;F.create=function(a,b){console.log("THREE.Curve.create() has been deprecated");a.prototype=Object.create(F.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};Object.assign(sb.prototype,{createPointsGeometry:function(a){console.warn("THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");a=this.getPoints(a);return this.createGeometry(a)},createSpacedPointsGeometry:function(a){console.warn("THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead."); +a=this.getSpacedPoints(a);return this.createGeometry(a)},createGeometry:function(a){console.warn("THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");for(var b=new G,c=0,d=a.length;c + + + +Kibi-ji Cycling + + + + + + + + + + + +
    +
    + +
    + + + + + +
    + + +
    +
    + +
    +
    + + + + + + +
    +
    +
    + + +
    +
    +
    +

    Kibi-ji Cycling

    +

    Kibi is an old region name in Japan. I went biking on the Kibi-ji cycling route alone on a day in the spring. +

    + +

    +
    + Biking on this day started in the middle part of the Sasagase River basin. +
    +
    +

    Mannari granite quarry

    + +

    We can see a granite quarry of Mannari Ishi on the left side. My grandfather was a stone mason. +

    + +

    +
    +

    Kibitsuhiko Shrine

    + +

    I passed by the Kibitsuhiko Shrine. I sometimes buy an amulet for road safety there. + +

    [Wikipedia] + +

    + +

    +
    +

    Kibitsu Shrine

    + +

    I passed by the Kibitsu Shrine. + +

    [Wikipedia] + +

    +

    +
    +

    Tsukuriyama-kofun

    + +

    Tsukuriyama-kofun is an ancient keyhole-shaped burial mound. It is said that the burial mound was built in 5th century. + +

    [Wikipedia] + +

    +

    +
    +

    Bicchu-Kokubunji Temple

    + +

    I arrived at the destination on this day. We can see the five-storied pagoda beyond a small canola field. + +

    +

    +
    +
    +
    + + + + diff --git a/docs/examples/27/kibiji/meshline/license b/docs/examples/27/kibiji/meshline/license new file mode 100644 index 00000000..2913a08c --- /dev/null +++ b/docs/examples/27/kibiji/meshline/license @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Jaume Sanchez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/docs/examples/27/kibiji/meshline/three.meshline.js b/docs/examples/27/kibiji/meshline/three.meshline.js new file mode 100644 index 00000000..34f8ac7f --- /dev/null +++ b/docs/examples/27/kibiji/meshline/three.meshline.js @@ -0,0 +1,738 @@ +;(function() { + 'use strict' + + var root = this + + var has_require = typeof require !== 'undefined' + + var THREE = root.THREE || (has_require && require('three')) + if (!THREE) throw new Error('MeshLine requires three.js') + + function MeshLine() { + THREE.BufferGeometry.call(this) + this.type = 'MeshLine' + + this.positions = [] + + this.previous = [] + this.next = [] + this.side = [] + this.width = [] + this.indices_array = [] + this.uvs = [] + this.counters = [] + this._points = [] + this._geom = null + + this.widthCallback = null + + // Used to raycast + this.matrixWorld = new THREE.Matrix4() + + Object.defineProperties(this, { + // this is now a bufferGeometry + // add getter to support previous api + geometry: { + enumerable: true, + get: function() { + return this + }, + }, + geom: { + enumerable: true, + get: function() { + return this._geom + }, + set: function(value) { + this.setGeometry(value, this.widthCallback) + }, + }, + // for declaritive architectures + // to return the same value that sets the points + // eg. this.points = points + // console.log(this.points) -> points + points: { + enumerable: true, + get: function() { + return this._points + }, + set: function(value) { + this.setPoints(value, this.widthCallback) + }, + }, + }) + } + + MeshLine.prototype = Object.create(THREE.BufferGeometry.prototype) + MeshLine.prototype.constructor = MeshLine + MeshLine.prototype.isMeshLine = true + + MeshLine.prototype.setMatrixWorld = function(matrixWorld) { + this.matrixWorld = matrixWorld + } + + // setting via a geometry is rather superfluous + // as you're creating a unecessary geometry just to throw away + // but exists to support previous api + MeshLine.prototype.setGeometry = function(g, c) { + // as the input geometry are mutated we store them + // for later retreival when necessary (declaritive architectures) + this._geometry = g; + if (g instanceof THREE.Geometry) { + this.setPoints(g.vertices, c); + } else if (g instanceof THREE.BufferGeometry) { + this.setPoints(g.getAttribute("position").array, c); + } else { + this.setPoints(g, c); + } + } + + MeshLine.prototype.setPoints = function(points, wcb) { + if (!(points instanceof Float32Array) && !(points instanceof Array)) { + console.error( + "ERROR: The BufferArray of points is not instancied correctly." + ); + return; + } + // as the points are mutated we store them + // for later retreival when necessary (declaritive architectures) + this._points = points; + this.widthCallback = wcb; + this.positions = []; + this.counters = []; + if (window.Q3D !== undefined) { // @minorua + var cumLengths = [0], length = 0; + var i, j, dx, dy, dz, c; + + for (i = 3; i < points.length; i += 3) { + dx = points[i] - points[i - 3]; + dy = points[i + 1] - points[i - 2]; + dz = points[i + 2] - points[i - 1]; + length += Math.sqrt(dx * dx + dy * dy + dz * dz); + cumLengths.push(length); + } + for (i = 0, j = 0; j < points.length; i++, j += 3) { + c = cumLengths[i] / length; + this.positions.push(points[j], points[j + 1], points[j + 2]); + this.positions.push(points[j], points[j + 1], points[j + 2]); + this.counters.push(c); + this.counters.push(c); + } + } else if (points.length && points[0] instanceof THREE.Vector3) { + // could transform Vector3 array into the array used below + // but this approach will only loop through the array once + // and is more performant + for (var j = 0; j < points.length; j++) { + var p = points[j]; + var c = j / points.length; + this.positions.push(p.x, p.y, p.z); + this.positions.push(p.x, p.y, p.z); + this.counters.push(c); + this.counters.push(c); + } + } else { + for (var j = 0; j < points.length; j += 3) { + var c = j / points.length; + this.positions.push(points[j], points[j + 1], points[j + 2]); + this.positions.push(points[j], points[j + 1], points[j + 2]); + this.counters.push(c); + this.counters.push(c); + } + } + this.process(); + } + + function MeshLineRaycast(raycaster, intersects) { + var inverseMatrix = new THREE.Matrix4() + var ray = new THREE.Ray() + var sphere = new THREE.Sphere() + var interRay = new THREE.Vector3() + var geometry = this.geometry + // Checking boundingSphere distance to ray + + sphere.copy(geometry.boundingSphere) + sphere.applyMatrix4(this.matrixWorld) + + if (raycaster.ray.intersectSphere(sphere, interRay) === false) { + return + } + + inverseMatrix.getInverse(this.matrixWorld) + ray.copy(raycaster.ray).applyMatrix4(inverseMatrix) + + var vStart = new THREE.Vector3() + var vEnd = new THREE.Vector3() + var interSegment = new THREE.Vector3() + var step = this instanceof THREE.LineSegments ? 2 : 1 + var index = geometry.index + var attributes = geometry.attributes + + if (index !== null) { + var indices = index.array + var positions = attributes.position.array + var widths = attributes.width.array + + for (var i = 0, l = indices.length - 1; i < l; i += step) { + var a = indices[i] + var b = indices[i + 1] + + vStart.fromArray(positions, a * 3) + vEnd.fromArray(positions, b * 3) + var width = widths[Math.floor(i / 3)] != undefined ? widths[Math.floor(i / 3)] : 1 + var precision = raycaster.params.Line.threshold + (this.material.lineWidth * width) / 2 + var precisionSq = precision * precision + + var distSq = ray.distanceSqToSegment(vStart, vEnd, interRay, interSegment) + + if (distSq > precisionSq) continue + + interRay.applyMatrix4(this.matrixWorld) //Move back to world space for distance calculation + + var distance = raycaster.ray.origin.distanceTo(interRay) + + if (distance < raycaster.near || distance > raycaster.far) continue + + intersects.push({ + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4(this.matrixWorld), + index: i, + face: null, + faceIndex: null, + object: this, + }) + // make event only fire once + i = l + } + } + } + MeshLine.prototype.raycast = MeshLineRaycast + MeshLine.prototype.compareV3 = function(a, b) { + var aa = a * 6 + var ab = b * 6 + return ( + this.positions[aa] === this.positions[ab] && + this.positions[aa + 1] === this.positions[ab + 1] && + this.positions[aa + 2] === this.positions[ab + 2] + ) + } + + MeshLine.prototype.copyV3 = function(a) { + var aa = a * 6 + return [this.positions[aa], this.positions[aa + 1], this.positions[aa + 2]] + } + + MeshLine.prototype.process = function() { + var l = this.positions.length / 6 + + this.previous = [] + this.next = [] + this.side = [] + this.width = [] + this.indices_array = [] + this.uvs = [] + + var w + + var v + // initial previous points + if (this.compareV3(0, l - 1)) { + v = this.copyV3(l - 2) + } else { + v = this.copyV3(0) + } + this.previous.push(v[0], v[1], v[2]) + this.previous.push(v[0], v[1], v[2]) + + for (var j = 0; j < l; j++) { + // sides + this.side.push(1) + this.side.push(-1) + + // widths + if (this.widthCallback) w = this.widthCallback(j / (l - 1)) + else w = 1 + this.width.push(w) + this.width.push(w) + + // uvs + this.uvs.push(j / (l - 1), 0) + this.uvs.push(j / (l - 1), 1) + + if (j < l - 1) { + // points previous to poisitions + v = this.copyV3(j) + this.previous.push(v[0], v[1], v[2]) + this.previous.push(v[0], v[1], v[2]) + + // indices + var n = j * 2 + this.indices_array.push(n, n + 1, n + 2) + this.indices_array.push(n + 2, n + 1, n + 3) + } + if (j > 0) { + // points after poisitions + v = this.copyV3(j) + this.next.push(v[0], v[1], v[2]) + this.next.push(v[0], v[1], v[2]) + } + } + + // last next point + if (this.compareV3(l - 1, 0)) { + v = this.copyV3(1) + } else { + v = this.copyV3(l - 1) + } + this.next.push(v[0], v[1], v[2]) + this.next.push(v[0], v[1], v[2]) + + // redefining the attribute seems to prevent range errors + // if the user sets a differing number of vertices + if (!this._attributes || this._attributes.position.count !== this.positions.length) { + this._attributes = { + position: new THREE.BufferAttribute(new Float32Array(this.positions), 3), + previous: new THREE.BufferAttribute(new Float32Array(this.previous), 3), + next: new THREE.BufferAttribute(new Float32Array(this.next), 3), + side: new THREE.BufferAttribute(new Float32Array(this.side), 1), + width: new THREE.BufferAttribute(new Float32Array(this.width), 1), + uv: new THREE.BufferAttribute(new Float32Array(this.uvs), 2), + index: new THREE.BufferAttribute(new Uint16Array(this.indices_array), 1), + counters: new THREE.BufferAttribute(new Float32Array(this.counters), 1), + } + } else { + this._attributes.position.copyArray(new Float32Array(this.positions)) + this._attributes.position.needsUpdate = true + this._attributes.previous.copyArray(new Float32Array(this.previous)) + this._attributes.previous.needsUpdate = true + this._attributes.next.copyArray(new Float32Array(this.next)) + this._attributes.next.needsUpdate = true + this._attributes.side.copyArray(new Float32Array(this.side)) + this._attributes.side.needsUpdate = true + this._attributes.width.copyArray(new Float32Array(this.width)) + this._attributes.width.needsUpdate = true + this._attributes.uv.copyArray(new Float32Array(this.uvs)) + this._attributes.uv.needsUpdate = true + this._attributes.index.copyArray(new Uint16Array(this.indices_array)) + this._attributes.index.needsUpdate = true + } + + this.setAttribute('position', this._attributes.position) + this.setAttribute('previous', this._attributes.previous) + this.setAttribute('next', this._attributes.next) + this.setAttribute('side', this._attributes.side) + this.setAttribute('width', this._attributes.width) + this.setAttribute('uv', this._attributes.uv) + this.setAttribute('counters', this._attributes.counters) + + this.setIndex(this._attributes.index) + + this.computeBoundingSphere() + this.computeBoundingBox() + } + + function memcpy(src, srcOffset, dst, dstOffset, length) { + var i + + src = src.subarray || src.slice ? src : src.buffer + dst = dst.subarray || dst.slice ? dst : dst.buffer + + src = srcOffset + ? src.subarray + ? src.subarray(srcOffset, length && srcOffset + length) + : src.slice(srcOffset, length && srcOffset + length) + : src + + if (dst.set) { + dst.set(src, dstOffset) + } else { + for (i = 0; i < src.length; i++) { + dst[i + dstOffset] = src[i] + } + } + + return dst + } + + /** + * Fast method to advance the line by one position. The oldest position is removed. + * @param position + */ + MeshLine.prototype.advance = function(position) { + var positions = this._attributes.position.array + var previous = this._attributes.previous.array + var next = this._attributes.next.array + var l = positions.length + + // PREVIOUS + memcpy(positions, 0, previous, 0, l) + + // POSITIONS + memcpy(positions, 6, positions, 0, l - 6) + + positions[l - 6] = position.x + positions[l - 5] = position.y + positions[l - 4] = position.z + positions[l - 3] = position.x + positions[l - 2] = position.y + positions[l - 1] = position.z + + // NEXT + memcpy(positions, 6, next, 0, l - 6) + + next[l - 6] = position.x + next[l - 5] = position.y + next[l - 4] = position.z + next[l - 3] = position.x + next[l - 2] = position.y + next[l - 1] = position.z + + this._attributes.position.needsUpdate = true + this._attributes.previous.needsUpdate = true + this._attributes.next.needsUpdate = true + } + + THREE.ShaderChunk['meshline_vert'] = [ + '', + THREE.ShaderChunk.logdepthbuf_pars_vertex, + THREE.ShaderChunk.fog_pars_vertex, + '', + 'attribute vec3 previous;', + 'attribute vec3 next;', + 'attribute float side;', + 'attribute float width;', + 'attribute float counters;', + '', + 'uniform vec2 resolution;', + 'uniform float lineWidth;', + 'uniform vec3 color;', + 'uniform float opacity;', + 'uniform float sizeAttenuation;', + '', + 'varying vec2 vUV;', + 'varying vec4 vColor;', + 'varying float vCounters;', + '', + 'vec2 fix( vec4 i, float aspect ) {', + '', + ' vec2 res = i.xy / i.w;', + ' res.x *= aspect;', + ' vCounters = counters;', + ' return res;', + '', + '}', + '', + 'void main() {', + '', + ' float aspect = resolution.x / resolution.y;', + '', + ' vColor = vec4( color, opacity );', + ' vUV = uv;', + '', + ' mat4 m = projectionMatrix * modelViewMatrix;', + ' vec4 finalPosition = m * vec4( position, 1.0 );', + ' vec4 prevPos = m * vec4( previous, 1.0 );', + ' vec4 nextPos = m * vec4( next, 1.0 );', + '', + ' vec2 currentP = fix( finalPosition, aspect );', + ' vec2 prevP = fix( prevPos, aspect );', + ' vec2 nextP = fix( nextPos, aspect );', + '', + ' float w = lineWidth * width;', + '', + ' vec2 dir;', + ' if( nextP == currentP ) dir = normalize( currentP - prevP );', + ' else if( prevP == currentP ) dir = normalize( nextP - currentP );', + ' else {', + ' vec2 dir1 = normalize( currentP - prevP );', + ' vec2 dir2 = normalize( nextP - currentP );', + ' dir = normalize( dir1 + dir2 );', + '', + ' vec2 perp = vec2( -dir1.y, dir1.x );', + ' vec2 miter = vec2( -dir.y, dir.x );', + ' //w = clamp( w / dot( miter, perp ), 0., 4. * lineWidth * width );', + '', + ' }', + '', + ' //vec2 normal = ( cross( vec3( dir, 0. ), vec3( 0., 0., 1. ) ) ).xy;', + ' vec4 normal = vec4( -dir.y, dir.x, 0., 1. );', + ' normal.xy *= .5 * w;', + ' normal *= projectionMatrix;', + ' if( sizeAttenuation == 0. ) {', + ' normal.xy *= finalPosition.w;', + ' normal.xy /= ( vec4( resolution, 0., 1. ) * projectionMatrix ).xy;', + ' }', + '', + ' finalPosition.xy += normal.xy * side;', + '', + ' gl_Position = finalPosition;', + '', + THREE.ShaderChunk.logdepthbuf_vertex, + THREE.ShaderChunk.fog_vertex && ' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );', + THREE.ShaderChunk.fog_vertex, + '}', + ].join('\n') + + THREE.ShaderChunk['meshline_frag'] = [ + '', + THREE.ShaderChunk.fog_pars_fragment, + THREE.ShaderChunk.logdepthbuf_pars_fragment, + '', + 'uniform sampler2D map;', + 'uniform sampler2D alphaMap;', + 'uniform float useMap;', + 'uniform float useAlphaMap;', + 'uniform float useDash;', + 'uniform float dashArray;', + 'uniform float dashOffset;', + 'uniform float dashRatio;', + 'uniform float visibility;', + 'uniform float alphaTest;', + 'uniform vec2 repeat;', + '', + 'varying vec2 vUV;', + 'varying vec4 vColor;', + 'varying float vCounters;', + '', + 'void main() {', + '', + THREE.ShaderChunk.logdepthbuf_fragment, + '', + ' vec4 c = vColor;', + ' if( useMap == 1. ) c *= texture2D( map, vUV * repeat );', + ' if( useAlphaMap == 1. ) c.a *= texture2D( alphaMap, vUV * repeat ).a;', + ' if( c.a < alphaTest ) discard;', + ' if( useDash == 1. ){', + ' c.a *= ceil(mod(vCounters + dashOffset, dashArray) - (dashArray * dashRatio));', + ' }', + ' gl_FragColor = c;', + ' gl_FragColor.a *= step(vCounters, visibility);', + '', + THREE.ShaderChunk.fog_fragment, + '}', + ].join('\n') + + function MeshLineMaterial(parameters) { + THREE.ShaderMaterial.call(this, { + uniforms: Object.assign({}, THREE.UniformsLib.fog, { + lineWidth: { value: 1 }, + map: { value: null }, + useMap: { value: 0 }, + alphaMap: { value: null }, + useAlphaMap: { value: 0 }, + color: { value: new THREE.Color(0xffffff) }, + opacity: { value: 1 }, + resolution: { value: new THREE.Vector2(1, 1) }, + sizeAttenuation: { value: 1 }, + dashArray: { value: 0 }, + dashOffset: { value: 0 }, + dashRatio: { value: 0.5 }, + useDash: { value: 0 }, + visibility: { value: 1 }, + alphaTest: { value: 0 }, + repeat: { value: new THREE.Vector2(1, 1) }, + }), + + vertexShader: THREE.ShaderChunk.meshline_vert, + + fragmentShader: THREE.ShaderChunk.meshline_frag, + }) + + this.type = 'MeshLineMaterial' + + Object.defineProperties(this, { + lineWidth: { + enumerable: true, + get: function() { + return this.uniforms.lineWidth.value + }, + set: function(value) { + this.uniforms.lineWidth.value = value + }, + }, + map: { + enumerable: true, + get: function() { + return this.uniforms.map.value + }, + set: function(value) { + this.uniforms.map.value = value + }, + }, + useMap: { + enumerable: true, + get: function() { + return this.uniforms.useMap.value + }, + set: function(value) { + this.uniforms.useMap.value = value + }, + }, + alphaMap: { + enumerable: true, + get: function() { + return this.uniforms.alphaMap.value + }, + set: function(value) { + this.uniforms.alphaMap.value = value + }, + }, + useAlphaMap: { + enumerable: true, + get: function() { + return this.uniforms.useAlphaMap.value + }, + set: function(value) { + this.uniforms.useAlphaMap.value = value + }, + }, + color: { + enumerable: true, + get: function() { + return this.uniforms.color.value + }, + set: function(value) { + this.uniforms.color.value = value + }, + }, + opacity: { + enumerable: true, + get: function() { + return this.uniforms.opacity.value + }, + set: function(value) { + this.uniforms.opacity.value = value + }, + }, + resolution: { + enumerable: true, + get: function() { + return this.uniforms.resolution.value + }, + set: function(value) { + this.uniforms.resolution.value.copy(value) + }, + }, + sizeAttenuation: { + enumerable: true, + get: function() { + return this.uniforms.sizeAttenuation.value + }, + set: function(value) { + this.uniforms.sizeAttenuation.value = value + }, + }, + dashArray: { + enumerable: true, + get: function() { + return this.uniforms.dashArray.value + }, + set: function(value) { + this.uniforms.dashArray.value = value + this.useDash = value !== 0 ? 1 : 0 + }, + }, + dashOffset: { + enumerable: true, + get: function() { + return this.uniforms.dashOffset.value + }, + set: function(value) { + this.uniforms.dashOffset.value = value + }, + }, + dashRatio: { + enumerable: true, + get: function() { + return this.uniforms.dashRatio.value + }, + set: function(value) { + this.uniforms.dashRatio.value = value + }, + }, + useDash: { + enumerable: true, + get: function() { + return this.uniforms.useDash.value + }, + set: function(value) { + this.uniforms.useDash.value = value + }, + }, + visibility: { + enumerable: true, + get: function() { + return this.uniforms.visibility.value + }, + set: function(value) { + this.uniforms.visibility.value = value + }, + }, + alphaTest: { + enumerable: true, + get: function() { + return this.uniforms.alphaTest.value + }, + set: function(value) { + this.uniforms.alphaTest.value = value + }, + }, + repeat: { + enumerable: true, + get: function() { + return this.uniforms.repeat.value + }, + set: function(value) { + this.uniforms.repeat.value.copy(value) + }, + }, + }) + + this.setValues(parameters) + } + + MeshLineMaterial.prototype = Object.create(THREE.ShaderMaterial.prototype) + MeshLineMaterial.prototype.constructor = MeshLineMaterial + MeshLineMaterial.prototype.isMeshLineMaterial = true + + MeshLineMaterial.prototype.copy = function(source) { + THREE.ShaderMaterial.prototype.copy.call(this, source) + + this.lineWidth = source.lineWidth + this.map = source.map + this.useMap = source.useMap + this.alphaMap = source.alphaMap + this.useAlphaMap = source.useAlphaMap + this.color.copy(source.color) + this.opacity = source.opacity + this.resolution.copy(source.resolution) + this.sizeAttenuation = source.sizeAttenuation + this.dashArray.copy(source.dashArray) + this.dashOffset.copy(source.dashOffset) + this.dashRatio.copy(source.dashRatio) + this.useDash = source.useDash + this.visibility = source.visibility + this.alphaTest = source.alphaTest + this.repeat.copy(source.repeat) + + return this + } + + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = { + MeshLine: MeshLine, + MeshLineMaterial: MeshLineMaterial, + MeshLineRaycast: MeshLineRaycast, + } + } + exports.MeshLine = MeshLine + exports.MeshLineMaterial = MeshLineMaterial + exports.MeshLineRaycast = MeshLineRaycast + } else { + root.MeshLine = MeshLine + root.MeshLineMaterial = MeshLineMaterial + root.MeshLineRaycast = MeshLineRaycast + } +}.call(this)) diff --git a/docs/examples/27/kibiji/qgis2threejs.css b/docs/examples/27/kibiji/qgis2threejs.css new file mode 100644 index 00000000..4f10f9eb --- /dev/null +++ b/docs/examples/27/kibiji/qgis2threejs.css @@ -0,0 +1,483 @@ +/* +(C) 2014 Minoru Akagi +SPDX-License-Identifier: MIT +https://github.com/minorua/Qgis2threejs +*/ + +body { + font-family: arial, sans-serif; + margin: 0; + overflow: hidden; +} + +#view { + position: absolute; + width: 100%; + height: 100%; +} + +#view.sky { + background: -webkit-gradient(linear, left top, left bottom, from(#98c8f6), color-stop(0.4, #cbebff), to(#f0f9ff)); + background: linear-gradient(to bottom, #98c8f6 0%,#cbebff 40%,#f0f9ff 100%); +} + +.hidden { + display: none !important; +} + +.visible { + display: block !important; +} + +.clickable { + cursor: pointer; +} + +.no-events { + pointer-events: none; +} + +.tooltip::before { + display: block; + position: absolute; + visibility: hidden; + transform: translate(10px, 30px); + + padding: 5px 10px; + content: attr(data-tooltip); + + color: black; + background: white; + font-size: small; + white-space: nowrap; +} + +.tooltip:hover::before { + visibility: visible; +} + +.tooltip-btn { + display: inline-block; + width: 14px; + height: 14px; + border-radius: 8px; + + font-size: 12px; + padding-top: 1px; + text-align: center; + color: white; + background-color: #bbb; + cursor: pointer; +} + +#progress { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 5px; +} + +#progressbar { + width: 0; + height: 5px; + background-color: #2196F3; + opacity: 1; +} + +#progressbar.fadeout { + opacity: 0; + height: 0; + transition: all .4s; +} + +#toolbtns { + position: absolute; + margin: 1px; + box-shadow: 1px 2px 6px rgba(0,0,0,0.2); + float: left; +} + +#toolbtns > div { + background-color: white; + width: 24px; + height: 24px; + padding: 6px; + cursor: pointer; +} + +#toolbtns > div:hover { + background-color: #eee; +} + +#toolbtns > div::before { + opacity: 0.6; +} + +#layerpanel { + position: absolute; + margin: 1px 2px; + background-color: white; + box-shadow: 1px 2px 6px rgba(0,0,0,0.2); + z-index: 1000; + display: none; +} + +.layer { + padding: 6px; +} + +.layer > div { + display: flex; + align-items: center; + margin-bottom: 3px; + font-size: small; +} + +.layer > div:nth-child(n + 2) { + margin-left: 20px; + font-size: xx-small +} + +.layer input[type="range"] { + width: 130px; + background-color:lightgray; +} + +.layer select { + width: 130px; +} + +#header { + position: absolute; + margin: 5px 10px; +} + +#footer { + position: absolute; + left: 5px; + bottom: 5px; +} + +/* popup */ +#popup { + position: absolute; + margin: 1px 2px; + max-width: 480px; + min-width: 300px; + z-index: 9999; + background-color: white; + box-shadow: 1px 2px 6px rgba(0,0,0,0.2); + display: none; +} + +#popupbar { + padding-left: 4px; + height: 19px; + border-bottom: 1px solid lightgray; + border-radius: 3px 3px 0 0; +} + +#closebtn { + color: #ccc; + padding: 2px; + line-height: 16px; + font-size: 16px; + font-weight: bold; + width: 16px; + height: 16px; + text-align: center; + float: right; + cursor: pointer; +} + +#closebtn:hover { + background-color: #eee; +} + +#popupbody { + padding: 0px 5px 5px; + max-height: 500px; + overflow: auto; +} + +#popupcontent, #queryresult { + display: none; +} + +#popupbody table { + margin: 4px 0px; + width: 100%; +} + +#popupbody table caption { + background-color: gray; + color: white; + font-size: small; + padding: 1px 1px 1px 6px; + text-align: left; + vertical-align: bottom; +} + +#popupbody table td { + padding-left: 5px; +} + +#qr_layername_table tr, #qr_coords_table tr { + background-color: #eee; +} + +#qr_attrs_table tr:nth-child(odd) { + background-color: #eee; +} + +#qr_attrs_table tr td:first-child { + width: 40%; +} + +.action-zoom { + cursor: pointer; + float: right; + padding: 0 1px 0; + width: 15px; + height: 15px; + filter: invert(100%); +} + +.action-zoom:hover { + background-color: #eee; + border-radius: 3px; + filter: none; +} + +.action-btn { + display: inline-block; + border: 1px solid lightgray; + cursor: pointer; + font-size: small; + padding: 2px 4px; + margin-left: 2px; +} + +.action-btn:hover { + background-color: #eee; +} + +/* pageinfo */ +#pageinfo { + font-size: small; + display: none; +} + +#pageinfo > h1 { + background-color: gray; + color: white; + font-size: small; + font-weight: normal; + margin-top: 5px; + margin-bottom: 3px; + padding: 1px 1px 1px 6px; +} + +#urlbox { + width: 98%; +} + +#usage, #about { + margin-left: 5px; +} + +#usage tr:nth-child(odd) { + background-color: #eee; +} + +#usage td.star { + font-weight: bold; +} + +#about ul { + margin: 5px; + margin-left: 20px; + padding: 0px; +} + +#about img { + float: left; + margin-right: 5px; + width: 24px; + height: 24px; +} + +.license { + font-size: xx-small; +} + +.download-link { + display: block; + border: 1px solid darkgray; + background: lightgray; + color: black; + font-size: large; + margin: 10px 50px 10px; + padding: 8px; + text-align: center; + text-decoration: none; +} + +/* measure distance */ +table.measure tr:nth-child(odd) { + background-color: #eee; +} + +table.measure tr > td:nth-child(2) { + text-align: right; +} + +/* print dialog */ +.print div { + padding: 5px; +} + +.print label { + margin-left: 5px; +} + +.print input[type="text"] { + width: 40px; + border: 1px solid lightgray; + background: #F6F6F6; + margin-left: 8px; + margin-right: 8px; +} + +.print input[type="checkbox"] { + margin-left: 15px; +} + +.print input[type="submit"] { + display: none; +} + +.print .buttonbox { + text-align: center; + padding-top: 10px; + padding-bottom: 10px; +} + +.print .buttonbox span { + border: 1px solid darkgray; + background: lightgray; + margin: 0px 5px 0px; + padding: 5px 10px 5px; + cursor: pointer; +} + +/* widgets */ +#northarrow { + position: absolute; + left: 12px; + bottom: 16px; + width: 80px; + height: 80px; + z-index: 1000; + pointer-events: none; + display: none; +} + +#navigation { + position: absolute; + right: 0px; + bottom: 0px; + width: 128px; + height: 128px; + z-index: 1000; + display: none; +} + +/* animation */ +#narrativebox { + position: absolute; + z-index: 1001; + left: 2px; + top: 2px; + max-width: 40%; + max-height: 80%; + min-width: 200px; + + border: 1px solid gray; + border-radius: 2px; + background-color: rgba(255, 255, 255, .95); + box-shadow: 5px 5px 5px rgba(0, 0, 0, .2); + padding: 8px; + + overflow: auto; +} + +#narrativebox.ef1 { + top: 90%; + height: 0; + opacity: 0; +} + +#narrativebox.ef1.visible { + transition: all ease-out .2s; + + top: 2px; + height: auto; + opacity: 1; +} + +#narbody { + width: 100%; + min-height: 75px; +} + +#narbody > .narcontent { + display: none; +} + +#nextbtn { + float: right; + padding: 4px 8px; + + border: 1px solid gray; + border-radius: 2px; + + font-size: small; + cursor: pointer; +} + +#nextbtn:hover { + background-color: #eee; +} + +.nextbtn { + width: 20px; + height: 20px; + opacity: 0.6; +} + +/* images */ +#layerbtn::before { + content: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgdmlld0JveD0iMCAwIDEwMCAxMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8ZyBjbGFzcz0ibGF5ZXIiPgogIDx0aXRsZT5MYXllciAxPC90aXRsZT4KICA8cGF0aCBkPSJtNTAsNDVsLTQwLDIwbDQwLDIwbDQwLC0yMGwtNDAsLTIweiIgZmlsbD0iI2ZmZmZmZiIgaWQ9InN2Z18xMCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjgiLz4KICA8cGF0aCBkPSJtNTAsMzBsLTQwLDIwbDQwLDIwbDQwLC0yMGwtNDAsLTIweiIgZmlsbD0iI2ZmZmZmZiIgaWQ9InN2Z185IiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iOCIgdHJhbnNmb3JtPSJtYXRyaXgoMSAwIDAgMSAwIDApIi8+CiAgPHBhdGggZD0ibTUwLDE1bC00MCwyMGw0MCwyMGw0MCwtMjBsLTQwLC0yMHoiIGZpbGw9IiNmZmZmZmYiIGlkPSJzdmdfNCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjgiLz4KIDwvZz4KPC9zdmc+"); +} + +#infobtn::before { + content: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGFzcz0ibGF5ZXIiIHN0cm9rZT0iIzAwMCI+PGNpcmNsZSBjeD0iNTAuMiIgY3k9IjUwIiByPSIzNiIgc3Ryb2tlLXdpZHRoPSIxMCIgZmlsbD0ibm9uZSIvPjxjaXJjbGUgY3g9IjUwIiBjeT0iMzAiIHI9IjUiLz48cGF0aCBkPSJNNDIgNDRoOHYyNW0tOCAyaDE2IiBzdHJva2Utd2lkdGg9IjgiIGZpbGw9Im5vbmUiLz48L2c+PC9zdmc+"); +} + +.zoombtn::before { + content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZyBjbGFzcz0ibGF5ZXIiIHN0cm9rZT0iIzAwMCIgZmlsbD0ibm9uZSI+PGNpcmNsZSBjeD0iNDIiIGN5PSI0MiIgcj0iMzMiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iOCIvPjxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNCIgZD0ibTY4IDY4IDE5IDE5Ii8+PHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2Utd2lkdGg9IjYiIGQ9Ik0yNyA0MWgzME00MiAyN3YzMCIvPjwvZz48L3N2Zz4="); +} + +.playbtn::before { + content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMiIgZD0iTTgwIDUwIDIyIDgwVjIwbDU4IDMweiIgY2xhc3M9ImxheWVyIi8+PC9zdmc+"); +} + +.pausebtn::before { + content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZyBjbGFzcz0ibGF5ZXIiPjxwYXRoIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxOCIgZD0iTTMwIDI1djUwTTcwIDI1djUwIi8+PC9nPjwvc3ZnPg=="); +} + +.nextbtn::before { + content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBkPSJNMzYuNyAxOC4yIDY4LjUgNTAgMzYuNyA4MS44IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMTQiIGZpbGw9Im5vbmUiIGNsYXNzPSJsYXllciIvPjwvc3ZnPg=="); +} diff --git a/docs/examples/27/kibiji/qgis2threejs.js b/docs/examples/27/kibiji/qgis2threejs.js new file mode 100644 index 00000000..64d5f71f --- /dev/null +++ b/docs/examples/27/kibiji/qgis2threejs.js @@ -0,0 +1,4594 @@ +// (C) 2014 Minoru Akagi +// SPDX-License-Identifier: MIT +// https://github.com/minorua/Qgis2threejs + +"use strict"; + +var Q3D = { + VERSION: "2.7.1", + application: {}, + gui: {} +}; + +Q3D.Config = { + + // renderer + renderer: { + hiDpi: true // HD-DPI support + }, + + texture: { + anisotropy: -4 // zero means max available value. negative value means max / -v. + }, + + // scene + autoAdjustCameraPos: true, // automatic camera height adjustment + bgColor: null, // null is sky + + // camera + orthoCamera: false, + viewpoint: { // z-up + default: { // assumed that origin is (0, 0, 0) and base extent width in 3D world coordinates is 1 + pos: new THREE.Vector3(0, -1, 1), + lookAt: new THREE.Vector3() + } + }, + + // light + lights: { + directional: [ + { + type: "ambient", + color: 0x999999, + intensity: 0.8 + }, + { + type: "directional", + color: 0xffffff, + intensity: 0.7, + azimuth: 220, // azimuth of light, in degrees. default light azimuth of gdaldem hillshade is 315. + altitude: 45 // altitude angle in degrees. + } + ], + point: [ + { + type: "ambient", + color: 0x999999, + intensity: 0.9 + }, + { + type: "point", + color: 0xffffff, + intensity: 0.6, + height: 10 + } + ] + }, + + // layer + allVisible: false, // set every layer visible property to true on load if set to true + + line: { + dash: { + dashSize: 1, + gapSize: 0.5 + } + }, + + label: { + visible: true, + canvasHeight: 64, + clickable: true + }, + + // widgets + navigation: { + enabled: true + }, + + northArrow: { + color: 0x8b4513, + cameraDistance: 30, + enabled: false + }, + + // animation + animation: { + enabled: false, + startOnLoad: false, + easingCurve: "Cubic", + repeat: false + }, + + // others + qmarker: { + radius: 0.004, + color: 0xffff00, + opacity: 0.8, + k: 0.2 // size factor for ortho camera + }, + + measure: { + marker: { + radius: 0.004, + color: 0xffff00, + opacity: 0.5 + /* k: 0.2 */ + }, + line: { + color: 0xffff00 + } + }, + + coord: { + visible: true, + latlon: false + }, + + potree: {}, + + debugMode: false +}; + +// consts +Q3D.LayerType = { + DEM: "dem", + Point: "point", + Line: "line", + Polygon: "polygon", + PointCloud: "pc" +}; + +Q3D.MaterialType = { + MeshLambert: 0, + MeshPhong: 1, + MeshToon: 2, + Line: 3, + MeshLine: 4, + Sprite: 5, + Point: 6, + MeshStandard: 7, + Unknown: -1 +}; + +Q3D.KeyframeType = { + CameraMotion: 64, + Opacity: 65, + Texture: 66, + GrowingLine: 67 +}; + +Q3D.uv = { + i: new THREE.Vector3(1, 0, 0), + j: new THREE.Vector3(0, 1, 0), + k: new THREE.Vector3(0, 0, 1) +}; + +Q3D.deg2rad = Math.PI / 180; + +Q3D.ua = window.navigator.userAgent.toLowerCase(); +Q3D.isIE = (Q3D.ua.indexOf("msie") != -1 || Q3D.ua.indexOf("trident") != -1); +Q3D.isTouchDevice = ("ontouchstart" in window); + +Q3D.E = function (id) { + return document.getElementById(id); +}; + +/* +Q3D.Group -> THREE.Group -> THREE.Object3D +*/ +Q3D.Group = function () { + THREE.Group.call(this); +}; + +Q3D.Group.prototype = Object.create(THREE.Group.prototype); +Q3D.Group.prototype.constructor = Q3D.Group; + +Q3D.Group.prototype.add = function (object) { + THREE.Group.prototype.add.call(this, object); + object.updateMatrixWorld(); +}; + +Q3D.Group.prototype.clear = function () { + for (var i = this.children.length - 1; i >= 0; i--) { + this.remove(this.children[i]); + } +}; + +/* +Q3D.application +*/ +(function () { + var app = Q3D.application, + gui = Q3D.gui, + conf = Q3D.Config, + E = Q3D.E; + + var vec3 = new THREE.Vector3(); + + var listeners = {}; + app.dispatchEvent = function (event) { + var ls = listeners[event.type] || []; + for (var i = 0; i < ls.length; i++) { + ls[i](event); + } + }; + + app.addEventListener = function (type, listener, prepend) { + listeners[type] = listeners[type] || []; + if (prepend) { + listeners[type].unshift(listener); + } + else { + listeners[type].push(listener); + } + }; + + app.removeEventListener = function (type, listener) { + var array = listeners[type]; + if (array !== undefined) { + var idx = array.indexOf(listener); + if (idx !== -1) array.splice(idx, 1); + } + }; + + app.init = function (container) { + + app.container = container; + + app.selectedObject = null; + app.highlightObject = null; + + app.modelBuilders = []; + app._wireframeMode = false; + + // URL parameters + var params = app.parseUrlParameters(); + app.urlParams = params; + + if ("popup" in params) { + // open popup window + var c = window.location.href.split("?"); + window.open(c[0] + "?" + c[1].replace(/&?popup/, ""), "popup", "width=" + params.width + ",height=" + params.height); + gui.popup.show("Another window has been opened."); + return; + } + + if (params.hiDpi == "no") conf.renderer.hiDpi = false; + if (params.anisotropy) conf.texture.anisotropy = parseFloat(params.anisotropy); + + if (params.cx !== undefined) conf.viewpoint.pos = new THREE.Vector3(parseFloat(params.cx), parseFloat(params.cy), parseFloat(params.cz)); + if (params.tx !== undefined) conf.viewpoint.lookAt = new THREE.Vector3(parseFloat(params.tx), parseFloat(params.ty), parseFloat(params.tz)); + + if (params.width && params.height) { + container.style.width = params.width + "px"; + container.style.height = params.height + "px"; + } + + app.width = container.clientWidth; + app.height = container.clientHeight; + + var bgcolor = conf.bgColor; + if (bgcolor === null) container.classList.add("sky"); + + // WebGLRenderer + app.renderer = new THREE.WebGLRenderer({alpha: true, antialias: true}); + + if (conf.renderer.hiDpi) { + app.renderer.setPixelRatio(window.devicePixelRatio); + } + + app.renderer.setSize(app.width, app.height); + app.renderer.setClearColor(bgcolor || 0, (bgcolor === null) ? 0 : 1); + app.container.appendChild(app.renderer.domElement); + + if (conf.texture.anisotropy <= 0) { + var maxAnis = app.renderer.capabilities.getMaxAnisotropy() || 1; + + if (conf.texture.anisotropy == 0) { + conf.texture.anisotropy = maxAnis; + } + else { + conf.texture.anisotropy = (maxAnis > -conf.texture.anisotropy) ? -maxAnis / conf.texture.anisotropy : 1; + } + } + + // outline effect + if (THREE.OutlineEffect !== undefined) app.effect = new THREE.OutlineEffect(app.renderer); + + // scene + app.scene = new Q3D.Scene(); + + app.scene.addEventListener("renderRequest", function (event) { + app.render(); + }); + + app.scene.addEventListener("cameraUpdateRequest", function (event) { + app.camera.position.copy(event.pos); + app.camera.lookAt(event.focal); + if (app.controls.target !== undefined) app.controls.target.copy(event.focal); + if (app.controls.saveState !== undefined) app.controls.saveState(); + + if (event.far !== undefined) { + app.camera.near = (app.camera.isOrthographicCamera) ? 0 : event.near; + app.camera.far = event.far; + app.camera.updateProjectionMatrix(); + } + }); + + app.scene.addEventListener("lightChanged", function (event) { + if (event.light == "point") { + app.scene.add(app.camera); + app.camera.add(app.scene.lightGroup); + } + else { // directional + app.scene.remove(app.camera); + app.scene.add(app.scene.lightGroup); + } + }); + + app.scene.addEventListener("mapRotationChanged", function (event) { + if (app.scene2) { + app.scene2.lightGroup.clear(); + app.scene2.buildLights(Q3D.Config.lights.directional, event.rotation); + } + }); + + // camera + app.buildCamera(conf.orthoCamera); + + // controls + if (THREE.OrbitControls) { + app.controls = new THREE.OrbitControls(app.camera, app.renderer.domElement); + + app.controls.addEventListener("change", function (event) { + app.render(); + }); + + app.controls.update(); + } + + // navigation + if (conf.navigation.enabled && typeof ViewHelper !== "undefined") { + app.buildViewHelper(E("navigation")); + } + + // north arrow + if (conf.northArrow.enabled) { + app.buildNorthArrow(E("northarrow")); + } + + // labels + app.labelVisible = conf.label.visible; + + // create a marker for queried point + var opt = conf.qmarker; + app.queryMarker = new THREE.Mesh(new THREE.SphereBufferGeometry(opt.radius, 32, 32), + new THREE.MeshLambertMaterial({color: opt.color, opacity: opt.opacity, transparent: (opt.opacity < 1)})); + app.queryMarker.name = "marker"; + + app.queryMarker.onBeforeRender = function (renderer, scene, camera, geometry, material, group) { + this.scale.setScalar(this.position.distanceTo(camera.position) * ((camera.isPerspectiveCamera) ? 1 : conf.qmarker.k)); + this.updateMatrixWorld(); + }; + + app.highlightMaterial = new THREE.MeshLambertMaterial({emissive: 0x999900, transparent: true, opacity: 0.5}); + + if (!Q3D.isIE) app.highlightMaterial.side = THREE.DoubleSide; // Shader compilation error occurs with double sided material on IE11 + + // loading manager + app.initLoadingManager(); + + // event listeners + app.addEventListener("sceneLoaded", function () { + if (conf.viewpoint.pos === undefined && conf.autoAdjustCameraPos) { + app.adjustCameraPosition(); + } + app.render(); + + if (conf.animation.startOnLoad) { + app.animation.keyframes.start(); + } + }, true); + + window.addEventListener("keydown", app.eventListener.keydown); + window.addEventListener("resize", app.eventListener.resize); + + app.renderer.domElement.addEventListener("mousedown", app.eventListener.mousedown); + app.renderer.domElement.addEventListener("mouseup", app.eventListener.mouseup); + + gui.init(); + }; + + app.parseUrlParameters = function () { + var p, vars = {}; + var params = window.location.search.substring(1).split('&').concat(window.location.hash.substring(1).split('&')); + params.forEach(function (param) { + p = param.split('='); + vars[p[0]] = p[1]; + }); + return vars; + }; + + app.initLoadingManager = function () { + if (app.loadingManager) { + app.loadingManager.onLoad = app.loadingManager.onProgress = app.loadingManager.onError = undefined; + } + + app.loadingManager = new THREE.LoadingManager(function () { // onLoad + app.loadingManager.isLoading = false; + + E("progressbar").classList.add("fadeout"); + + app.dispatchEvent({type: "sceneLoaded"}); + }, + function (url, loaded, total) { // onProgress + E("progressbar").style.width = (loaded / total * 100) + "%"; + }, + function () { // onError + app.loadingManager.isLoading = false; + + app.dispatchEvent({type: "sceneLoadError"}); + }); + + app.loadingManager.onStart = function () { + app.loadingManager.isLoading = true; + }; + + app.loadingManager.isLoading = false; + }; + + app.loadFile = function (url, type, callback) { + + var loader = new THREE.FileLoader(app.loadingManager); + loader.setResponseType(type); + + var onError = function (e) { + if (location.protocol == "file:") { + gui.popup.show("This browser doesn't allow loading local files via Ajax. See plugin wiki page for details.", "Error", true); + } + }; + + try { + loader.load(url, callback, undefined, onError); + } + catch (e) { // for IE + onError(e); + } + }; + + app.loadJSONObject = function (jsonObject) { + app.scene.loadJSONObject(jsonObject); + if (jsonObject.animation !== undefined) app.animation.keyframes.load(jsonObject.animation.groups); + }; + + app.loadJSONFile = function (url, callback) { + app.loadFile(url, "json", function (obj) { + app.loadJSONObject(obj); + if (callback) callback(obj); + }); + }; + + app.loadSceneFile = function (url, sceneFileLoadedCallback, sceneLoadedCallback) { + + var onload = function () { + if (sceneFileLoadedCallback) sceneFileLoadedCallback(app.scene); + }; + + if (sceneLoadedCallback) { + app.addEventListener("sceneLoaded", function () { + sceneLoadedCallback(app.scene); + }); + } + + var ext = url.split(".").pop(); + if (ext == "json") app.loadJSONFile(url, onload); + else if (ext == "js") { + var e = document.createElement("script"); + e.src = url; + e.onload = onload; + document.body.appendChild(e); + } + }; + + app.loadTextureFile = function (url, callback) { + return new THREE.TextureLoader(app.loadingManager).load(url, callback); + }; + + app.loadModelFile = function (url, callback) { + var loader, + ext = url.split(".").pop(); + if (ext == "dae") { + loader = new THREE.ColladaLoader(app.loadingManager); + } + else if (ext == "gltf" || ext == "glb") { + loader = new THREE.GLTFLoader(app.loadingManager); + } + else { + console.log("Model file type not supported: " + url); + return; + } + + app.loadingManager.itemStart("M" + url); + + loader.load(url, function (model) { + if (callback) callback(model); + app.loadingManager.itemEnd("M" + url); + }, + undefined, + function (e) { + console.log("Failed to load model: " + url); + app.loadingManager.itemError("M" + url); + }); + }; + + app.loadModelData = function (data, ext, resourcePath, callback) { + + if (ext == "dae") { + var model = new THREE.ColladaLoader(app.loadingManager).parse(data, resourcePath); + if (callback) callback(model); + } + else if (ext == "gltf" || ext == "glb") { + new THREE.GLTFLoader(app.loadingManager).parse(data, resourcePath, function (model) { + if (callback) callback(model); + }, function (e) { + console.log("Failed to load a glTF model: " + e); + }); + } + else { + console.log("Model file type not supported: " + ext); + return; + } + }; + + app.mouseDownPoint = new THREE.Vector2(); + app.mouseUpPoint = new THREE.Vector2(); + + app.eventListener = { + + keydown: function (e) { + if (e.ctrlKey) return; + + if (e.shiftKey) { + switch (e.keyCode) { + case 82: // Shift + R + app.controls.reset(); + return; + case 83: // Shift + S + gui.showPrintDialog(); + return; + } + return; + } + + switch (e.keyCode) { + case 8: // BackSpace + if (app.measure.isActive) app.measure.removeLastPoint(); + return; + case 13: // Enter + app.animation.keyframes.resume(); + return; + case 27: // ESC + if (gui.popup.isVisible()) { + app.cleanView(); + } + else if (app.controls.autoRotate) { + app.setRotateAnimationMode(false); + } + return; + case 73: // I + gui.showInfo(); + return; + case 76: // L + app.setLabelVisible(!app.labelVisible); + return; + case 82: // R + app.setRotateAnimationMode(!app.controls.autoRotate); + return; + case 87: // W + app.setWireframeMode(!app._wireframeMode); + return; + } + }, + + mousedown: function (e) { + app.mouseDownPoint.set(e.clientX, e.clientY); + }, + + mouseup: function (e) { + app.mouseUpPoint.set(e.clientX, e.clientY); + if (app.mouseDownPoint.equals(app.mouseUpPoint)) app.canvasClicked(e); + }, + + resize: function () { + app.setCanvasSize(app.container.clientWidth, app.container.clientHeight); + app.render(); + } + + }; + + app.setCanvasSize = function (width, height) { + var changed = (app.width != width || app.height != height); + + app.width = width; + app.height = height; + app.camera.aspect = width / height; + app.camera.updateProjectionMatrix(); + app.renderer.setSize(width, height); + + if (changed) app.dispatchEvent({type: "canvasSizeChanged"}); + }; + + app.buildCamera = function (is_ortho) { + if (is_ortho) { + app.camera = new THREE.OrthographicCamera(-app.width / 10, app.width / 10, app.height / 10, -app.height / 10); + } + else { + app.camera = new THREE.PerspectiveCamera(45, app.width / app.height); + } + + // magic to change y-up world to z-up + app.camera.up.set(0, 0, 1); + + var be = app.scene.userData.baseExtent; + if (be) { + app.camera.near = (is_ortho) ? 0 : 0.001 * be.width; + app.camera.far = 100 * be.width; + app.camera.updateProjectionMatrix(); + } + }; + + // move camera target to center of scene + app.adjustCameraPosition = function (force) { + if (!force) { + app.render(); + + // stay at current position if rendered objects exist + var r = app.renderer.info.render; + if (r.triangles + r.points + r.lines) return; + } + var bbox = app.scene.boundingBox(); + if (bbox.isEmpty()) return; + + bbox.getCenter(vec3); + app.cameraAction.zoom(vec3.x, vec3.y, (bbox.max.z + vec3.z) / 2, app.scene.userData.baseExtent.width); + }; + + // declination: clockwise from +y, in degrees + app.buildNorthArrow = function (container, declination) { + container.style.display = "block"; + + app.renderer2 = new THREE.WebGLRenderer({alpha: true, antialias: true}); + app.renderer2.setClearColor(0, 0); + app.renderer2.setSize(container.clientWidth, container.clientHeight); + + app.container2 = container; + app.container2.appendChild(app.renderer2.domElement); + + app.camera2 = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 1, 1000); + app.camera2.position.set(0, 0, conf.northArrow.cameraDistance); + app.camera2.up = app.camera.up; + + app.scene2 = new Q3D.Scene(); + app.scene2.buildLights(conf.lights.directional, 0); + + // an arrow object + var geometry = new THREE.Geometry(); + geometry.vertices.push( + new THREE.Vector3(-5, -10, 0), + new THREE.Vector3(0, 10, 0), + new THREE.Vector3(0, -7, 3), + new THREE.Vector3(5, -10, 0) + ); + geometry.faces.push( + new THREE.Face3(0, 1, 2), + new THREE.Face3(2, 1, 3) + ); + geometry.computeFaceNormals(); + + var material = new THREE.MeshLambertMaterial({color: conf.northArrow.color, side: THREE.DoubleSide}); + var mesh = new THREE.Mesh(geometry, material); + if (declination) mesh.rotation.z = -declination * Q3D.deg2rad; + app.scene2.add(mesh); + }; + + app.buildViewHelper = function (container) { + + if (app.renderer3 === undefined) { + container.style.display = "block"; + + app.renderer3 = new THREE.WebGLRenderer({alpha: true, antialias: true}); + app.renderer3.setClearColor(0, 0); + app.renderer3.setSize(container.clientWidth, container.clientHeight); + + app.container3 = container; + app.container3.appendChild(app.renderer3.domElement); + } + + if (app.viewHelper !== undefined) { + app.viewHelper.removeEventListener("requestAnimation", app.startViewHelperAnimation); + } + + app.viewHelper = new ViewHelper(app.camera, {dom: container}); + app.viewHelper.controls = app.controls; + + app.viewHelper.addEventListener("requestAnimation", app.startViewHelperAnimation); + }; + + var clock = new THREE.Clock(); + app.startViewHelperAnimation = function () { + clock.start(); + requestAnimationFrame(app.animate); + }; + + app.currentViewUrl = function () { + var c = app.scene.toMapCoordinates(app.camera.position), + t = app.scene.toMapCoordinates(app.controls.target), + hash = "#cx=" + c.x.toFixed(3) + "&cy=" + c.y.toFixed(3) + "&cz=" + c.z.toFixed(3); + if (t.x || t.y || t.z) hash += "&tx=" + t.x.toFixed(3) + "&ty=" + t.y.toFixed(3) + "&tz=" + t.z.toFixed(3); + return window.location.href.split("#")[0] + hash; + }; + + // enable the controls + app.start = function () { + if (app.controls) app.controls.enabled = true; + }; + + app.pause = function () { + app.animation.isActive = false; + if (app.controls) app.controls.enabled = false; + }; + + app.resume = function () { + if (app.controls) app.controls.enabled = true; + }; + + // animation loop + app.animate = function () { + + if (app.animation.isActive) { + requestAnimationFrame(app.animate); + + if (app.animation.keyframes.isActive) TWEEN.update(); + else if (app.controls.enabled) app.controls.update(); + } + else if (app.viewHelper && app.viewHelper.animating) { + requestAnimationFrame(app.animate); + + app.viewHelper.update(clock.getDelta()); + } + + app.render(); + }; + + app.animation = { + + isActive: false, + + start: function () { + this.isActive = true; + app.animate(); + }, + + stop: function () { + this.isActive = false; + }, + + keyframes: { // keyframe animation + + isActive: false, + + isPaused: false, + + curveFactor: 0, + + easingFunction: function (easing) { + if (easing == 1) return TWEEN.Easing.Linear.None; + if (easing > 1) { + var f = TWEEN.Easing[Q3D.Config.animation.easingCurve]; + if (easing == 2) return f["InOut"]; + else if (easing == 3) return f["In"]; + else return f["Out"]; // easing == 4 + } + }, + + keyframeGroups: [], + + clear: function () { + this.keyframeGroups = []; + }, + + load: function (group) { + if (!Array.isArray(group)) group = [group]; + + this.keyframeGroups = this.keyframeGroups.concat(group); + }, + + start: function () { + + var _this = this, + e = E("narrativebox"), + btn = E("nextbtn"), + currentNarElem; + + this.keyframeGroups.forEach(function (group) { + + var t; + for (var p in Q3D.Tweens) { + if (Q3D.Tweens[p].type == group.type) { + t = Q3D.Tweens[p]; + break; + } + } + if (t === undefined) { + console.warn("unknown animation type: " + group.type); + return; + } + + var layer = (group.layerId !== undefined) ? app.scene.mapLayers[group.layerId] : undefined; + + group.completed = false; + group.currentIndex = 0; + group.prop_list = []; + + t.init(group, layer); + + var keyframes = group.keyframes; + + var showNBox = function (idx) { + // narrative box + var n = keyframes[idx].narration; + if (n && e) { + if (currentNarElem) { + currentNarElem.classList.remove("visible"); + } + + currentNarElem = E(n.id); + if (currentNarElem) { + currentNarElem.classList.add("visible"); + } + else { // preview + E("narbody").innerHTML = n.text; + } + + if (btn) { + if (idx < keyframes.length - 1) { + btn.className = "nextbtn"; + btn.innerHTML = ""; + } + else { + btn.className = ""; + btn.innerHTML = "Close"; + } + } + + setTimeout(function () { + _this.pause(); + e.classList.add("visible"); + }, 0); + } + }; + + var onStart = function () { + if (group.onStart) group.onStart(); + + app.dispatchEvent({type: "tweenStarted", index: group.currentIndex}); + + // pause if narrative box is shown + if (e && e.classList.contains("visible")) { + e.classList.remove("visible"); + } + }; + + var onComplete = function (obj) { + if (!keyframes[group.currentIndex].easing) { + group.onUpdate(obj, 1); + } + + if (group.onComplete) group.onComplete(obj); + + var index = ++group.currentIndex; + if (index == keyframes.length - 1) { + group.completed = true; + + var completed = true; + for (var i = 0; i < _this.keyframeGroups.length; i++) { + if (!_this.keyframeGroups[i].completed) completed = false; + } + + if (completed) { + if (conf.animation.repeat) { + setTimeout(function () { + _this.start(); + }, 0); + } + else { + _this.stop(); + } + } + } + + // show narrative box if the current keyframe has a narrative content + showNBox(index); + }; + + var t0, t1, t2; + for (var i = 0; i < keyframes.length - 1; i++) { + + t2 = new TWEEN.Tween(group.prop_list[i]).delay(keyframes[i].delay).onStart(onStart) + .to(group.prop_list[i + 1], keyframes[i].duration).onComplete(onComplete); + + if (keyframes[i].easing) { + t2.easing(_this.easingFunction(keyframes[i].easing)).onUpdate(group.onUpdate); + } + + if (i == 0) { + t0 = t2; + } + else { + t1.chain(t2); + } + t1 = t2; + } + + showNBox(0); + + t0.start(); + }); + + app.animation.isActive = this.isActive = true; + app.dispatchEvent({type: "animationStarted"}); + app.animate(); + }, + + stop: function () { + + TWEEN.removeAll(); + + app.animation.isActive = this.isActive = this.isPaused = false; + this._pausedTweens = null; + + app.dispatchEvent({type: "animationStopped"}); + }, + + pause: function () { + + if (this.isPaused) return; + + this._pausedTweens = TWEEN.getAll(); + + if (this._pausedTweens.length) { + for (var i = 0; i < this._pausedTweens.length; i++) { + this._pausedTweens[i].pause(); + } + this.isPaused = true; + } + app.animation.isActive = this.isActive = false; + }, + + resume: function () { + + var box = E("narrativebox"); + if (box && box.classList.contains("visible")) { + box.classList.remove("visible"); + } + + if (!this.isPaused) return; + + for (var i = 0; i < this._pausedTweens.length; i++) { + this._pausedTweens[i].resume(); + } + this._pausedTweens = null; + + app.animation.isActive = this.isActive = true; + this.isPaused = false; + + app.animate(); + } + }, + + orbit: { // orbit animation + + isActive: false, + + start: function () { + + app.controls.autoRotate = true; + app.animation.isActive = this.isActive = true; + + app.animate(); + }, + + stop: function () { + + app.controls.autoRotate = false; + app.animation.isActive = this.isActive = false; + } + } + }; + + app.render = function (updateControls) { + if (updateControls) { + app.controls.update(); + } + + if (app.camera.parent) { + app.camera.updateMatrixWorld(); + } + + // render + if (app.effect) { + app.effect.render(app.scene, app.camera); + } + else { + app.renderer.render(app.scene, app.camera); + } + + // North arrow + if (app.renderer2) { + app.scene2.quaternion.copy(app.camera.quaternion).inverse(); + app.scene2.updateMatrixWorld(); + + app.renderer2.render(app.scene2, app.camera2); + } + + // navigation widget + if (app.viewHelper) { + app.viewHelper.render(app.renderer3); + } + }; + + (function () { + var dly, rpt, times, id = null; + var func = function () { + app.render(); + if (rpt <= ++times) { + clearInterval(id); + id = null; + } + }; + app.setIntervalRender = function (delay, repeat) { + if (id === null || delay != dly) { + if (id !== null) { + clearInterval(id); + } + id = setInterval(func, delay); + dly = delay; + } + rpt = repeat; + times = 0; + }; + })(); + + app.setLabelVisible = function (visible) { + app.labelVisible = visible; + app.scene.labelGroup.visible = visible; + app.scene.labelConnectorGroup.visible = visible; + app.render(); + }; + + app.setRotateAnimationMode = function (enabled) { + if (enabled) { + app.animation.orbit.start(); + } + else { + app.animation.orbit.stop(); + } + }; + + app.setWireframeMode = function (wireframe) { + if (wireframe == app._wireframeMode) return; + + for (var id in app.scene.mapLayers) { + app.scene.mapLayers[id].setWireframeMode(wireframe); + } + + app._wireframeMode = wireframe; + app.render(); + }; + + app.intersectObjects = function (offsetX, offsetY) { + var vec2 = new THREE.Vector2((offsetX / app.width) * 2 - 1, + -(offsetY / app.height) * 2 + 1); + var ray = new THREE.Raycaster(); + ray.linePrecision = 0.2; + ray.setFromCamera(vec2, app.camera); + return ray.intersectObjects(app.scene.visibleObjects(app.labelVisible)); + }; + + app._offset = function (elm) { + var top = 0, left = 0; + do { + top += elm.offsetTop || 0; left += elm.offsetLeft || 0; elm = elm.offsetParent; + } while (elm); + return {top: top, left: left}; + }; + + app.queryTargetPosition = new THREE.Vector3(); + + app.cameraAction = { + + move: function (x, y, z) { + if (x === undefined) app.camera.position.copy(app.queryTargetPosition); + else app.camera.position.set(x, y, z); + app.render(true); + app.cleanView(); + }, + + vecZoom: new THREE.Vector3(0, -1, 1).normalize(), + + zoom: function (x, y, z, dist) { + if (x === undefined) vec3.copy(app.queryTargetPosition); + else vec3.set(x, y, z); + + if (dist === undefined) dist = app.scene.userData.baseExtent.width * 0.1; + + app.camera.position.copy(app.cameraAction.vecZoom).multiplyScalar(dist).add(vec3); + app.camera.lookAt(vec3); + if (app.controls.target !== undefined) app.controls.target.copy(vec3); + app.render(true); + app.cleanView(); + }, + + zoomToLayer: function (layer) { + if (!layer) return; + + var bbox = layer.boundingBox(); + + bbox.getSize(vec3); + var dist = Math.max(vec3.x, vec3.y * 3 / 4) * 1.2; + + bbox.getCenter(vec3); + app.cameraAction.zoom(vec3.x, vec3.y, vec3.z, dist); + }, + + orbit: function (x, y, z) { + if (app.controls.target === undefined) return; + + if (x === undefined) app.controls.target.copy(app.queryTargetPosition); + else app.controls.target.set(x, y, z); + app.setRotateAnimationMode(true); + app.cleanView(); + } + + }; + + app.cleanView = function () { + gui.clean(); + + app.scene.remove(app.queryMarker); + app.highlightFeature(null); + app.measure.clear(); + app.render(); + + app.selectedLayer = null; + + if (app._canvasImageUrl) { + URL.revokeObjectURL(app._canvasImageUrl); + app._canvasImageUrl = null; + } + }; + + app.highlightFeature = function (object) { + if (app.highlightObject) { + // remove highlight object from the scene + app.scene.remove(app.highlightObject); + app.selectedObject = null; + app.highlightObject = null; + } + + if (object === null) return; + + var layer = app.scene.mapLayers[object.userData.layerId]; + if (!layer || layer.type == Q3D.LayerType.DEM || layer.type == Q3D.LayerType.PointCloud) return; + if (layer.properties.objType == "Billboard") return; + + // create a highlight object (if layer type is Point, slightly bigger than the object) + var s = (layer.type == Q3D.LayerType.Point) ? 1.01 : 1; + + var clone = object.clone(); + clone.traverse(function (obj) { + obj.material = app.highlightMaterial; + }); + if (s != 1) clone.scale.multiplyScalar(s); + + // add the highlight object to the scene + app.scene.add(clone); + + app.selectedObject = object; + app.highlightObject = clone; + }; + + app.canvasClicked = function (e) { + + // button 2: right click + if (e.button == 2 && app.measure.isActive) { + app.measure.removeLastPoint(); + return; + } + + var canvasOffset = app._offset(app.renderer.domElement); + var objs = app.intersectObjects(e.clientX - canvasOffset.left, e.clientY - canvasOffset.top); + + var obj, o, layer, layerId; + for (var i = 0, l = objs.length; i < l; i++) { + obj = objs[i]; + + if (app.measure.isActive) { + app.measure.addPoint(obj.point); + return; + } + + // get layerId of clicked object + o = obj.object; + while (o) { + layerId = o.userData.layerId; + if (layerId !== undefined) break; + o = o.parent; + } + + if (layerId === undefined) break; + + layer = app.scene.mapLayers[layerId]; + if (!layer.clickable) break; + + app.selectedLayer = layer; + app.queryTargetPosition.copy(obj.point); + + // query marker + app.queryMarker.position.copy(obj.point); + app.scene.add(app.queryMarker); + + if (o.userData.isLabel) { + o = o.userData.objs[o.userData.partIdx]; // label -> object + } + + app.highlightFeature(o); + app.render(); + gui.showQueryResult(obj.point, layer, o, conf.coord.visible); + + return; + } + if (app.measure.isActive) return; + + app.cleanView(); + + if (app.controls.autoRotate) { + app.setRotateAnimationMode(false); + } + }; + + app.saveCanvasImage = function (width, height, fill_background, saveImageFunc) { + if (fill_background === undefined) fill_background = true; + + // set canvas size + var old_size; + if (width && height) { + old_size = [app.width, app.height]; + app.setCanvasSize(width, height); + } + + // functions + var saveBlob = function (blob) { + var filename = "image.png"; + + // ie + if (window.navigator.msSaveBlob !== undefined) { + window.navigator.msSaveBlob(blob, filename); + gui.popup.hide(); + } + else { + // create object url + if (app._canvasImageUrl) URL.revokeObjectURL(app._canvasImageUrl); + app._canvasImageUrl = URL.createObjectURL(blob); + + // display a link to save the image + var e = document.createElement("a"); + e.className = "download-link"; + e.href = app._canvasImageUrl; + e.download = filename; + e.innerHTML = "Save"; + gui.popup.show("Click to save the image to a file." + e.outerHTML, "Image is ready"); + } + }; + + var saveCanvasImage = saveImageFunc || function (canvas) { + if (canvas.toBlob !== undefined) { + canvas.toBlob(saveBlob); + } + else { // !HTMLCanvasElement.prototype.toBlob + // https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement.toBlob + var binStr = atob(canvas.toDataURL("image/png").split(',')[1]), + len = binStr.length, + arr = new Uint8Array(len); + + for (var i = 0; i < len; i++) { + arr[i] = binStr.charCodeAt(i); + } + + saveBlob(new Blob([arr], {type: "image/png"})); + } + }; + + var restoreCanvasSize = function () { + // restore canvas size + if (old_size) app.setCanvasSize(old_size[0], old_size[1]); + app.render(); + }; + + // background option + if (!fill_background) app.renderer.setClearColor(0, 0); + + // render + app.renderer.preserveDrawingBuffer = true; + + if (app.effect) { + app.effect.render(app.scene, app.camera); + } + else { + app.renderer.render(app.scene, app.camera); + } + + // restore clear color + var bgcolor = conf.bgColor; + app.renderer.setClearColor(bgcolor || 0, (bgcolor === null) ? 0 : 1); + + if (fill_background && bgcolor === null) { + var canvas = document.createElement("canvas"); + canvas.width = width; + canvas.height = height; + + var ctx = canvas.getContext("2d"); + if (fill_background && bgcolor === null) { + // render "sky-like" background + var grad = ctx.createLinearGradient(0, 0, 0, height); + grad.addColorStop(0, "#98c8f6"); + grad.addColorStop(0.4, "#cbebff"); + grad.addColorStop(1, "#f0f9ff"); + ctx.fillStyle = grad; + ctx.fillRect(0, 0, width, height); + } + + var image = new Image(); + image.onload = function () { + // draw webgl canvas image + ctx.drawImage(image, 0, 0, width, height); + + // save canvas image + saveCanvasImage(canvas); + restoreCanvasSize(); + }; + image.src = app.renderer.domElement.toDataURL("image/png"); + } + else { + // save webgl canvas image + saveCanvasImage(app.renderer.domElement); + restoreCanvasSize(); + } + }; + + (function () { + + var path = []; + + app.measure = { + + isActive: false, + + precision: 3, + + start: function () { + app.scene.remove(app.queryMarker); + + if (!this.geom) { + var opt = conf.measure.marker; + this.geom = new THREE.SphereBufferGeometry(opt.radius, 32, 32); + this.mtl = new THREE.MeshLambertMaterial({color: opt.color, opacity: opt.opacity, transparent: (opt.opacity < 1)}); + opt = conf.measure.line; + this.lineMtl = new THREE.LineBasicMaterial({color: opt.color}); + this.markerGroup = new Q3D.Group(); + this.markerGroup.name = "measure marker"; + this.lineGroup = new Q3D.Group(); + this.lineGroup.name = "measure line"; + } + + this.isActive = true; + + app.scene.add(this.markerGroup); + app.scene.add(this.lineGroup); + + this.addPoint(app.queryTargetPosition); + }, + + addPoint: function (pt) { + // add a marker + var marker = new THREE.Mesh(this.geom, this.mtl); + marker.position.copy(pt); + marker.onBeforeRender = app.queryMarker.onBeforeRender; + + this.markerGroup.updateMatrixWorld(); + this.markerGroup.add(marker); + + path.push(marker.position); + + if (path.length > 1) { + // add a line + var v = path[path.length - 2].toArray().concat(path[path.length - 1].toArray()), + geom = new THREE.BufferGeometry().setAttribute("position", new THREE.Float32BufferAttribute(v, 3)), + line = new THREE.Line(geom, this.lineMtl); + this.lineGroup.add(line); + } + + app.render(); + this.showResult(); + }, + + removeLastPoint: function () { + path.pop(); + this.markerGroup.children.pop(); + this.lineGroup.children.pop(); + + app.render(); + + if (path.length) this.showResult(); + else app.cleanView(); + }, + + clear: function () { + if (!this.isActive) return; + + this.markerGroup.clear(); + this.lineGroup.clear(); + + app.scene.remove(this.markerGroup); + app.scene.remove(this.lineGroup); + + path = []; + this.isActive = false; + }, + + formatLength: function (length) { + return (length) ? length.toFixed(this.precision) : 0; + }, + + showResult: function () { + var vec2 = new THREE.Vector2(), + zScale = app.scene.userData.zScale; + var total = 0, totalxy = 0, dz = 0; + if (path.length > 1) { + var dxy; + for (var i = path.length - 1; i > 0; i--) { + dxy = vec2.copy(path[i]).distanceTo(path[i - 1]); + dz = (path[i].z - path[i - 1].z) / zScale; + + total += Math.sqrt(dxy * dxy + dz * dz); + totalxy += dxy; + } + dz = (path[path.length - 1].z - path[0].z) / zScale; + } + + var html = ''; + html += ""; + html += ""; + html += "'; + html += "
    Total distance:" + this.formatLength(total) + " m
    Horizontal distance:" + this.formatLength(totalxy) + " m
    Vertical difference:" + this.formatLength(dz) + ' m?
    "; + + gui.popup.show(html, "Measure distance"); + } + }; + })(); +})(); + +/* +Q3D.gui +*/ +(function () { + var app = Q3D.application, + gui = Q3D.gui, + conf = Q3D.Config, + E = Q3D.E, + VIS = "visible"; + + function CE(tagName, parent, innerHTML) { + var elem = document.createElement(tagName); + if (parent) parent.appendChild(elem); + if (innerHTML) elem.innerHTML = innerHTML; + return elem; + } + + function ON_CLICK(id, listener) { + var e = document.getElementById(id); + if (e) e.addEventListener("click", listener); + } + + gui.modules = []; + + gui.init = function () { + // tool buttons + ON_CLICK("layerbtn", function () { + if (!gui.layerPanel.initialized) gui.layerPanel.init(); + + if (gui.layerPanel.isVisible()) { + gui.layerPanel.hide(); + } + else { + if (gui.popup.isVisible()) { + gui.popup.hide(); + } + gui.layerPanel.show(); + } + }); + + ON_CLICK("infobtn", function () { + gui.layerPanel.hide(); + + if (gui.popup.isVisible() && gui.popup.content == "pageinfo") gui.popup.hide(); + else gui.showInfo(); + }); + + var btn = E("animbtn"); + if (conf.animation.enabled && btn) { + var anim = app.animation.keyframes; + + btn.classList.remove("hidden"); + + var playButton = function () { + btn.className = "playbtn"; + }; + + var pauseButton = function () { + btn.className = "pausebtn"; + }; + + playButton(); + + btn.onclick = function () { + if (anim.isActive) { + anim.pause(); + playButton(); + } + else if (anim.isPaused) { + anim.resume(); + pauseButton(); + } + else anim.start(); + }; + + app.addEventListener('animationStarted', pauseButton); + app.addEventListener('animationStopped', playButton); + } + + // popup + ON_CLICK("closebtn", app.cleanView); + ON_CLICK("zoomtolayer", function () { + app.cameraAction.zoomToLayer(app.selectedLayer); + }); + ON_CLICK("zoomtopoint", function () { + app.cameraAction.zoom(); + }); + ON_CLICK("orbitbtn", function () { + app.cameraAction.orbit(); + }); + ON_CLICK("measurebtn", function () { + app.measure.start(); + }); + + // narrative box + ON_CLICK("nextbtn", function () { + app.animation.keyframes.resume(); + }); + + // attribution + if (typeof proj4 === "undefined") { + var e = E("lib_proj4js"); + if (e) e.classList.add("hidden"); + } + + // initialize modules + for (var i = 0; i < gui.modules.length; i++) { + gui.modules[i].init(); + } + }; + + gui.clean = function () { + gui.popup.hide(); + if (gui.layerPanel.initialized) gui.layerPanel.hide(); + }; + + gui.popup = { + + modal: false, + + content: null, + + timerId: null, + + isVisible: function () { + return E("popup").classList.contains(VIS); + }, + + // show box + // obj: html, element or content id ("queryresult" or "pageinfo") + // modal: boolean + // duration: int [milliseconds] + show: function (obj, title, modal, duration) { + + if (modal) app.pause(); + else if (this.modal) app.resume(); + + this.content = obj; + this.modal = Boolean(modal); + + var e = E("layerpanel"); + if (e) e.classList.remove(VIS); + + var content = E("popupcontent"); + [content, E("queryresult"), E("pageinfo")].forEach(function (e) { + if (e) e.classList.remove(VIS); + }); + + if (obj == "queryresult" || obj == "pageinfo") { + E(obj).classList.add(VIS); + } + else { + if (obj instanceof HTMLElement) { + content.innerHTML = ""; + content.appendChild(obj); + } + else { + content.innerHTML = obj; + } + content.classList.add(VIS); + } + E("popupbar").innerHTML = title || ""; + E("popup").classList.add(VIS); + + if (this.timerId !== null) { + clearTimeout(this.timerId); + this.timerId = null; + } + + if (duration) { + this.timerId = setTimeout(function () { + gui.popup.hide(); + }, duration); + } + }, + + hide: function () { + E("popup").classList.remove(VIS); + if (this.timerId !== null) clearTimeout(this.timerId); + this.timerId = null; + this.content = null; + if (this.modal) app.resume(); + } + + }; + + gui.showInfo = function () { + var e = E("urlbox"); + if (e) e.value = app.currentViewUrl(); + gui.popup.show("pageinfo"); + }; + + gui.showQueryResult = function (point, layer, obj, show_coords) { + // layer name + var e = E("qr_layername"); + if (layer && e) e.innerHTML = layer.properties.name; + + // clicked coordinates + e = E("qr_coords_table"); + if (e) { + if (show_coords) { + e.classList.remove("hidden"); + + var pt = app.scene.toMapCoordinates(point); + + e = E("qr_coords"); + + if (conf.coord.latlon) { + var lonLat = proj4(app.scene.userData.proj).inverse([pt.x, pt.y]); + e.innerHTML = Q3D.Utils.convertToDMS(lonLat[1], lonLat[0]) + ", Elev. " + pt.z.toFixed(2); + } + else { + e.innerHTML = [pt.x.toFixed(2), pt.y.toFixed(2), pt.z.toFixed(2)].join(", "); + } + + if (conf.debugMode) { + var p = app.scene.userData, + be = p.baseExtent; + e.innerHTML += "
    WLD: " + [point.x.toFixed(8), point.y.toFixed(8), point.z.toFixed(8)].join(", "); + e.innerHTML += "

    ORG: " + [p.origin.x.toFixed(8), p.origin.y.toFixed(8), p.origin.z.toFixed(8)].join(", "); + e.innerHTML += "
    BE CNTR: " + [be.cx.toFixed(8), be.cy.toFixed(8)].join(", "); + e.innerHTML += "
    BE SIZE: " + [be.width.toFixed(8), be.height.toFixed(8)].join(", "); + e.innerHTML += "
    ROT: " + be.rotation + "
    Z SC: " + p.zScale; + } + } + else { + e.classList.add("hidden"); + } + } + + e = E("qr_attrs_table"); + if (e) { + for (var i = e.children.length - 1; i >= 0; i--) { + if (e.children[i].tagName.toUpperCase() == "TR") e.removeChild(e.children[i]); + } + + if (layer && layer.properties.propertyNames !== undefined) { + var row; + for (var i = 0, l = layer.properties.propertyNames.length; i < l; i++) { + row = document.createElement("tr"); + row.innerHTML = "" + layer.properties.propertyNames[i] + "" + + "" + obj.userData.properties[i] + ""; + e.appendChild(row); + } + e.classList.remove("hidden"); + } + else { + e.classList.add("hidden"); + } + } + gui.popup.show("queryresult"); + }; + + gui.showPrintDialog = function () { + + var f = CE("form"); + f.className = "print"; + + var d1 = CE("div", f, "Image Size"); + d1.style.textDecoration = "underline"; + + var d2 = CE("div", f), + l1 = CE("label", d2, "Width:"), + width = CE("input", d2); + d2.style.cssFloat = "left"; + l1.htmlFor = width.id = width.name = "printwidth"; + width.type = "text"; + width.value = app.width; + CE("span", d2, "px,"); + + var d3 = CE("div", f), + l2 = CE("label", d3, "Height:"), + height = CE("input", d3); + l2.htmlFor = height.id = height.name = "printheight"; + height.type = "text"; + height.value = app.height; + CE("span", d3, "px"); + + var d4 = CE("div", f), + ka = CE("input", d4); + ka.type = "checkbox"; + ka.checked = true; + CE("span", d4, "Keep Aspect Ratio"); + + var d5 = CE("div", f, "Option"); + d5.style.textDecoration = "underline"; + + var d6 = CE("div", f), + bg = CE("input", d6); + bg.type = "checkbox"; + bg.checked = true; + CE("span", d6, "Fill Background"); + + var d7 = CE("div", f), + ok = CE("span", d7, "OK"), + cancel = CE("span", d7, "Cancel"); + d7.className = "buttonbox"; + + CE("input", f).type = "submit"; + + // event handlers + // width and height boxes + var aspect = app.width / app.height; + + width.oninput = function () { + if (ka.checked) height.value = Math.round(width.value / aspect); + }; + + height.oninput = function () { + if (ka.checked) width.value = Math.round(height.value * aspect); + }; + + ok.onclick = function () { + gui.popup.show("Rendering..."); + window.setTimeout(function () { + app.saveCanvasImage(width.value, height.value, bg.checked); + }, 10); + }; + + cancel.onclick = app.cleanView; + + // enter key pressed + f.onsubmit = function () { + ok.onclick(); + return false; + }; + + gui.popup.show(f, "Save Image", true); // modal + }; + + gui.layerPanel = { + + init: function () { + var panel = E("layerpanel"); + + var p, item, e, slider, o, select, i; + Object.keys(app.scene.mapLayers).forEach(function (layerId) { + + var layer = app.scene.mapLayers[layerId]; + p = layer.properties; + item = CE("div", panel); + item.className = "layer"; + + // visible + e = CE("div", item, "" + p.name); + e.querySelector("input[type=checkbox]").addEventListener("change", function () { + layer.visible = this.checked; + }); + + // opacity slider + e = CE("div", item, "Opacity: "); + slider = e.querySelector("input[type=range]"); + + var label = e.querySelector("output"); + + o = parseInt(layer.opacity * 100); + slider.value = o; + slider.addEventListener("input", function () { + label.innerHTML = this.value + " %"; + }); + slider.addEventListener("change", function () { + label.innerHTML = this.value + " %"; + layer.opacity = this.value / 100; + }); + label.innerHTML = o + " %"; + + // material dropdown + if (p.mtlNames && p.mtlNames.length > 1) { + select = CE("select", CE("div", item, "Material: ")); + for (i = 0; i < p.mtlNames.length; i++) { + CE("option", select, p.mtlNames[i]).setAttribute("value", i); + } + select.value = p.mtlIdx; + select.addEventListener("change", function () { + layer.setCurrentMaterial(this.value); + }); + } + }); + gui.layerPanel.initialized = true; + }, + + isVisible: function () { + return E("layerpanel").classList.contains(VIS); + }, + + show: function () { + E("layerpanel").classList.add(VIS); + }, + + hide: function () { + E("layerpanel").classList.remove(VIS); + } + + }; + +})(); + +/* +Q3D.Material +*/ +Q3D.Material = function () { + this.loaded = false; +}; + +Q3D.Material.prototype = { + + constructor: Q3D.Material, + + // material: a THREE.Material-based object + set: function (material) { + this.mtl = material; + this.origProp = {}; + return this; + }, + + // callback is called when material has been completely loaded + loadJSONObject: function (jsonObject, callback) { + this.origProp = jsonObject; + this.groupId = jsonObject.mtlIndex; + + var m = jsonObject, opt = {}, defer = false; + + if (m.ds && !Q3D.isIE) opt.side = THREE.DoubleSide; + + if (m.flat) opt.flatShading = true; + + // texture + if (m.image !== undefined) { + var _this = this; + if (m.image.url !== undefined) { + opt.map = Q3D.application.loadTextureFile(m.image.url, function () { + _this._loadCompleted(callback); + }); + defer = true; + } + else if (m.image.object !== undefined) { // WebKit Bridge + opt.map = new THREE.Texture(m.image.object.toImageData()); + opt.map.needsUpdate = true; + + delete m.image.object; + } + else { // base64 + var img = new Image(); + img.onload = function () { + opt.map.needsUpdate = true; + _this._loadCompleted(callback); + }; + img.src = m.image.base64; + opt.map = new THREE.Texture(img); + defer = true; + + delete m.image.base64; + } + opt.map.anisotropy = Q3D.Config.texture.anisotropy; + } + + if (m.c !== undefined) opt.color = m.c; + + if (m.o !== undefined && m.o < 1) { + opt.opacity = m.o; + opt.transparent = true; + } + + if (m.t) opt.transparent = true; + + if (m.w) opt.wireframe = true; + + if (m.bm) { + this.mtl = new THREE.MeshBasicMaterial(opt); + } + else if (m.type == Q3D.MaterialType.MeshLambert) { + this.mtl = new THREE.MeshLambertMaterial(opt); + } + else if (m.type == Q3D.MaterialType.MeshPhong) { + this.mtl = new THREE.MeshPhongMaterial(opt); + } + else if (m.type == Q3D.MaterialType.MeshToon) { + this.mtl = new THREE.MeshToonMaterial(opt); + } + else if (m.type == Q3D.MaterialType.Point) { + opt.size = m.s; + this.mtl = new THREE.PointsMaterial(opt); + } + else if (m.type == Q3D.MaterialType.Line) { + + if (m.dashed) { + opt.dashSize = Q3D.Config.line.dash.dashSize; + opt.gapSize = Q3D.Config.line.dash.gapSize; + this.mtl = new THREE.LineDashedMaterial(opt); + } + else { + this.mtl = new THREE.LineBasicMaterial(opt); + } + } + else if (m.type == Q3D.MaterialType.MeshLine) { + + opt.lineWidth = m.thickness; + if (m.dashed) { + opt.dashArray = 0.03; + opt.dashRatio = 0.45; + opt.dashOffset = 0.015; + opt.transparent = true; + } + // opt.sizeAttenuation = 1; + + var mtl = this.mtl = new MeshLineMaterial(opt); + var updateAspect = this._listener = function () { + mtl.resolution = new THREE.Vector2(Q3D.application.width, Q3D.application.height); + }; + + updateAspect(); + Q3D.application.addEventListener("canvasSizeChanged", updateAspect); + } + else if (m.type == Q3D.MaterialType.Sprite) { + opt.color = 0xffffff; + this.mtl = new THREE.SpriteMaterial(opt); + } + else { + if (m.roughness !== undefined) opt.roughness = m.roughness; + if (m.metalness !== undefined) opt.metalness = m.metalness; + + this.mtl = new THREE.MeshStandardMaterial(opt); + } + + if (!defer) this._loadCompleted(callback); + }, + + _loadCompleted: function (anotherCallback) { + this.loaded = true; + + if (this._callbacks !== undefined) { + for (var i = 0; i < this._callbacks.length; i++) { + this._callbacks[i](); + } + this._callbacks = []; + } + + if (anotherCallback) anotherCallback(); + }, + + callbackOnLoad: function (callback) { + if (this.loaded) return callback(); + + if (this._callbacks === undefined) this._callbacks = []; + this._callbacks.push(callback); + }, + + dispose: function () { + if (!this.mtl) return; + + if (this.mtl.map) this.mtl.map.dispose(); // dispose of texture + this.mtl.dispose(); + this.mtl = null; + + if (this._listener) { + Q3D.application.removeEventListener("canvasSizeChanged", this._listener); + this._listener = undefined; + } + } +}; + +/* +Q3D.Scene -> THREE.Scene -> THREE.Object3D + +scene properties (userData): + - baseExtent(cx, cy, width, height, rotation): map base extent in map coordinates. center is (cx, cy). + - origin: origin of 3D world in map coordinates + - zScale: vertical scale factor + - proj: (optional) proj string. used to display clicked position in long/lat. +*/ +Q3D.Scene = function () { + THREE.Scene.call(this); + this.autoUpdate = false; + + this.mapLayers = {}; // map layers contained in this scene. key is layerId. + + this.lightGroup = new Q3D.Group(); + this.lightGroup.name = "light"; + this.add(this.lightGroup); + + this.labelGroup = new Q3D.Group(); + this.labelGroup.name = "label"; + this.add(this.labelGroup); + + this.labelConnectorGroup = new Q3D.Group(); + this.labelConnectorGroup.name = "label connector"; + this.add(this.labelConnectorGroup); +}; + +Q3D.Scene.prototype = Object.create(THREE.Scene.prototype); +Q3D.Scene.prototype.constructor = Q3D.Scene; + +Q3D.Scene.prototype.add = function (object) { + THREE.Scene.prototype.add.call(this, object); + object.updateMatrixWorld(); +}; + +Q3D.Scene.prototype.loadJSONObject = function (jsonObject) { + if (jsonObject.type == "scene") { + var p = jsonObject.properties; + if (p !== undefined) { + // fog + if (p.fog) { + this.fog = new THREE.FogExp2(p.fog.color, p.fog.density); + } + + // light + var rotation0 = (this.userData.baseExtent) ? this.userData.baseExtent.rotation : 0; + if (p.light != this.userData.light || p.baseExtent.rotation != rotation0) { + this.lightGroup.clear(); + this.buildLights(Q3D.Config.lights[p.light] || Q3D.Config.lights.directional, p.baseExtent.rotation); + this.dispatchEvent({type: "lightChanged", light: p.light}); + } + + var be = p.baseExtent; + p.pivot = new THREE.Vector3(be.cx, be.cy, p.origin.z).sub(p.origin); // 2D center of extent in 3D world coordinates + + // set initial camera position and parameters + if (this.userData.origin === undefined) { + + var s = be.width, + v = Q3D.Config.viewpoint, + pos, focal; + + if (v.pos === undefined) { + v = v.default; + if (be.rotation) { + v = { + pos: v.pos.clone().applyAxisAngle(Q3D.uv.k, be.rotation * Q3D.deg2rad), + lookAt: v.lookAt.clone().applyAxisAngle(Q3D.uv.k, be.rotation * Q3D.deg2rad) + }; + } + pos = v.pos.clone().multiplyScalar(s).add(p.pivot); + focal = v.lookAt.clone().multiplyScalar(s).add(p.pivot); + } + else { + pos = new THREE.Vector3().copy(v.pos).sub(p.origin); + focal = new THREE.Vector3().copy(v.lookAt).sub(p.origin); + } + + pos.z *= p.zScale; + focal.z *= p.zScale; + + var near = 0.001 * s, + far = 100 * s; + + this.requestCameraUpdate(pos, focal, near, far); + } + + if (p.baseExtent.rotation != rotation0) { + this.dispatchEvent({type: "mapRotationChanged", rotation: p.baseExtent.rotation}); + } + + this.userData = p; + } + + // load layers + if (jsonObject.layers !== undefined) { + jsonObject.layers.forEach(function (layer) { + this.loadJSONObject(layer); + }, this); + } + } + else if (jsonObject.type == "layer") { + var layer = this.mapLayers[jsonObject.id]; + if (layer === undefined) { + // create a layer + var type = jsonObject.properties.type; + if (type == "dem") layer = new Q3D.DEMLayer(); + else if (type == "point") layer = new Q3D.PointLayer(); + else if (type == "line") layer = new Q3D.LineLayer(); + else if (type == "polygon") layer = new Q3D.PolygonLayer(); + else if (type == "pc") layer = new Q3D.PointCloudLayer(); + else { + console.error("unknown layer type:" + type); + return; + } + layer.id = jsonObject.id; + layer.objectGroup.userData.layerId = jsonObject.id; + layer.addEventListener("renderRequest", this.requestRender.bind(this)); + + this.mapLayers[jsonObject.id] = layer; + this.add(layer.objectGroup); + } + + layer.loadJSONObject(jsonObject, this); + + this.requestRender(); + } + else if (jsonObject.type == "block") { + var layer = this.mapLayers[jsonObject.layer]; + if (layer === undefined) { + // console.error("layer not exists:" + jsonObject.layer); + return; + } + layer.loadJSONObject(jsonObject, this); + + this.requestRender(); + } +}; + +Q3D.Scene.prototype.buildLights = function (lights, rotation) { + var p, light; + for (var i = 0; i < lights.length; i++) { + p = lights[i]; + if (p.type == "ambient") { + light = new THREE.AmbientLight(p.color, p.intensity); + } + else if (p.type == "directional") { + light = new THREE.DirectionalLight(p.color, p.intensity); + light.position.copy(Q3D.uv.j) + .applyAxisAngle(Q3D.uv.i, p.altitude * Q3D.deg2rad) + .applyAxisAngle(Q3D.uv.k, (rotation - p.azimuth) * Q3D.deg2rad); + } + else if (p.type == "point") { + light = new THREE.PointLight(p.color, p.intensity); + light.position.set(0, 0, p.height); + } + else { + continue; + } + this.lightGroup.add(light); + } +}; + +Q3D.Scene.prototype.requestRender = function () { + this.dispatchEvent({type: "renderRequest"}); +}; + +Q3D.Scene.prototype.requestCameraUpdate = function (pos, focal, near, far) { + this.dispatchEvent({type: "cameraUpdateRequest", pos: pos, focal: focal, near: near, far: far}); +}; + +Q3D.Scene.prototype.visibleObjects = function (labelVisible) { + var layer, objs = []; + for (var id in this.mapLayers) { + layer = this.mapLayers[id]; + if (layer.visible) { + objs = objs.concat(layer.visibleObjects()); + if (labelVisible && layer.labels) objs = objs.concat(layer.labels); + } + } + return objs; +}; + +// 3D world coordinates to map coordinates +Q3D.Scene.prototype.toMapCoordinates = function (pt) { + var p = this.userData; + return { + x: p.origin.x + pt.x, + y: p.origin.y + pt.y, + z: p.origin.z + pt.z / p.zScale + }; +}; + +// map coordinates to 3D world coordinates +Q3D.Scene.prototype.toWorldCoordinates = function (pt, isLonLat) { + var p = this.userData; + if (isLonLat && typeof proj4 !== "undefined") { + // WGS84 long,lat to map coordinates + var t = proj4(p.proj).forward([pt.x, pt.y]); + pt = {x: t[0], y: t[1], z: pt.z}; + } + + return { + x: pt.x - p.origin.x, + y: pt.y - p.origin.y, + z: (pt.z - p.origin.z) * p.zScale + }; +}; + +// return bounding box in 3d world coordinates +Q3D.Scene.prototype.boundingBox = function () { + var box = new THREE.Box3(); + for (var id in this.mapLayers) { + if (this.mapLayers[id].visible) { + box.union(this.mapLayers[id].boundingBox()); + } + } + return box; +}; + +/* +Q3D.Materials +*/ +Q3D.Materials = function () { + this.array = []; +}; + +Q3D.Materials.prototype = Object.create(THREE.EventDispatcher.prototype); +Q3D.Materials.prototype.constructor = Q3D.Materials; + +// material: instance of Q3D.Material object or THREE.Material-based object +Q3D.Materials.prototype.add = function (material) { + if (material instanceof Q3D.Material) { + this.array.push(material); + } + else { + this.array.push(new Q3D.Material().set(material)); + } +}; + +Q3D.Materials.prototype.get = function (index) { + return this.array[index]; +}; + +Q3D.Materials.prototype.mtl = function (index) { + return this.array[index].mtl; +}; + +Q3D.Materials.prototype.loadJSONObject = function (jsonObject) { + var _this = this, iterated = false; + var callback = function () { + if (iterated) _this.dispatchEvent({type: "renderRequest"}); + }; + + for (var i = 0, l = jsonObject.length; i < l; i++) { + var mtl = new Q3D.Material(); + mtl.loadJSONObject(jsonObject[i], callback); + this.add(mtl); + } + iterated = true; +}; + +Q3D.Materials.prototype.dispose = function () { + for (var i = 0, l = this.array.length; i < l; i++) { + this.array[i].dispose(); + } + this.array = []; +}; + +Q3D.Materials.prototype.addFromObject3D = function (object) { + var mtls = []; + + object.traverse(function (obj) { + if (obj.material === undefined) return; + ((obj.material instanceof Array) ? obj.material : [obj.material]).forEach(function (mtl) { + if (mtls.indexOf(mtl) == -1) { + mtls.push(mtl); + } + }); + }); + + for (var i = 0, l = mtls.length; i < l; i++) { + this.array.push(new Q3D.Material().set(mtls[i])); + } +}; + +// opacity +Q3D.Materials.prototype.opacity = function () { + if (this.array.length == 0) return 1; + + var sum = 0; + for (var i = 0, l = this.array.length; i < l; i++) { + sum += this.array[i].mtl.opacity; + } + return sum / this.array.length; +}; + +Q3D.Materials.prototype.setOpacity = function (opacity) { + var m; + for (var i = 0, l = this.array.length; i < l; i++) { + m = this.array[i]; + m.mtl.transparent = Boolean(m.origProp.t) || (opacity < 1); + m.mtl.opacity = opacity; + } +}; + +// wireframe: boolean +Q3D.Materials.prototype.setWireframeMode = function (wireframe) { + var m; + for (var i = 0, l = this.array.length; i < l; i++) { + m = this.array[i]; + if (m.origProp.w || m.mtl instanceof THREE.LineBasicMaterial) continue; + m.mtl.wireframe = wireframe; + } +}; + +Q3D.Materials.prototype.removeItem = function (material, dispose) { + for (var i = this.array.length - 1; i >= 0; i--) { + if (this.array[i].mtl === material) { + this.array.splice(i, 1); + break; + } + } + if (dispose) material.dispose(); +}; + +Q3D.Materials.prototype.removeGroupItems = function (groupId) { + for (var i = this.array.length - 1; i >= 0; i--) { + if (this.array[i].groupId === groupId) { + this.array.splice(i, 1); + } + } +}; + +/* +Q3D.DEMBlock +*/ +Q3D.DEMBlock = function () { + this.materials = []; + this.currentMtlIndex = 0; +}; + +Q3D.DEMBlock.prototype = { + + constructor: Q3D.DEMBlock, + + // obj: object decoded from JSON + loadJSONObject: function (obj, layer, callback) { + + this.data = obj; + + // load material + var m, mtl; + for (var i = 0, l = (obj.materials || []).length; i < l; i++) { + m = obj.materials[i]; + + mtl = new Q3D.Material(); + mtl.loadJSONObject(m, function () { + layer.requestRender(); + }); + this.materials[m.mtlIndex] = mtl; + + if (m.useNow) { + this.currentMtlIndex = m.mtlIndex; + if (this.obj) { + layer.materials.removeItem(this.obj.material, true); + + this.obj.material = mtl.mtl; + layer.requestRender(); + } + layer.materials.add(mtl); + } + } + + if (obj.grid === undefined) return; + + // create a plane geometry + var geom, grid = obj.grid; + if (layer.geometryCache) { + var params = layer.geometryCache.parameters || {}; + if (params.width === obj.width && params.height === obj.height && + params.widthSegments === grid.width - 1 && params.heightSegments === grid.height - 1) { + geom = layer.geometryCache.clone(); + geom.parameters = layer.geometryCache.parameters; + } + } + geom = geom || new THREE.PlaneBufferGeometry(obj.width, obj.height, grid.width - 1, grid.height - 1); + layer.geometryCache = geom; + + // create a mesh + var mesh = new THREE.Mesh(geom, (this.materials[this.currentMtlIndex] || {}).mtl); + mesh.position.fromArray(obj.translate); + mesh.scale.z = obj.zScale; + layer.addObject(mesh); + + // set z values + var buildGeometry = function (grid_values) { + var vertices = geom.attributes.position.array; + for (var i = 0, j = 0, l = vertices.length; i < l; i++, j += 3) { + vertices[j + 2] = grid_values[i]; + } + geom.attributes.position.needsUpdate = true; + geom.computeVertexNormals(); + + if (callback) callback(mesh); + }; + + if (grid.url !== undefined) { + Q3D.application.loadFile(grid.url, "arraybuffer", function (buf) { + grid.array = new Float32Array(buf); + buildGeometry(grid.array); + }); + } + else { // local mode or WebKit Bridge + if (grid.binary !== undefined) grid.array = new Float32Array(grid.binary.buffer, 0, grid.width * grid.height); + buildGeometry(grid.array); + } + + this.obj = mesh; + return mesh; + }, + + buildSides: function (layer, parent, material, z0) { + var planeWidth = this.data.width, + planeHeight = this.data.height, + grid = this.data.grid, + grid_values = grid.array, + w = grid.width, + h = grid.height, + k = w * (h - 1); + + var band_width = -2 * z0; + + // front and back + var geom_fr = new THREE.PlaneBufferGeometry(planeWidth, band_width, w - 1, 1), + geom_ba = geom_fr.clone(); + + var vertices_fr = geom_fr.attributes.position.array, + vertices_ba = geom_ba.attributes.position.array; + + var i, mesh; + for (i = 0; i < w; i++) { + vertices_fr[i * 3 + 1] = grid_values[k + i]; + vertices_ba[i * 3 + 1] = grid_values[w - 1 - i]; + } + mesh = new THREE.Mesh(geom_fr, material); + mesh.rotation.x = Math.PI / 2; + mesh.position.y = -planeHeight / 2; + mesh.name = "side"; + parent.add(mesh); + + mesh = new THREE.Mesh(geom_ba, material); + mesh.rotation.x = Math.PI / 2; + mesh.rotation.y = Math.PI; + mesh.position.y = planeHeight / 2; + mesh.name = "side"; + parent.add(mesh); + + // left and right + var geom_le = new THREE.PlaneBufferGeometry(band_width, planeHeight, 1, h - 1), + geom_ri = geom_le.clone(); + + var vertices_le = geom_le.attributes.position.array, + vertices_ri = geom_ri.attributes.position.array; + + for (i = 0; i < h; i++) { + vertices_le[(i * 2 + 1) * 3] = grid_values[w * i]; + vertices_ri[i * 2 * 3] = -grid_values[w * (i + 1) - 1]; + } + mesh = new THREE.Mesh(geom_le, material); + mesh.rotation.y = -Math.PI / 2; + mesh.position.x = -planeWidth / 2; + mesh.name = "side"; + parent.add(mesh); + + mesh = new THREE.Mesh(geom_ri, material); + mesh.rotation.y = Math.PI / 2; + mesh.position.x = planeWidth / 2; + mesh.name = "side"; + parent.add(mesh); + + // bottom + var geom = new THREE.PlaneBufferGeometry(planeWidth, planeHeight, 1, 1); + mesh = new THREE.Mesh(geom, material); + mesh.rotation.x = Math.PI; + mesh.position.z = z0; + mesh.name = "bottom"; + parent.add(mesh); + + parent.updateMatrixWorld(); + }, + + addEdges: function (layer, parent, material, z0) { + + var i, x, y, + grid = this.data.grid, + grid_values = grid.array, + w = grid.width, + h = grid.height, + k = w * (h - 1), + planeWidth = this.data.width, + planeHeight = this.data.height, + hpw = planeWidth / 2, + hph = planeHeight / 2, + psw = planeWidth / (w - 1), + psh = planeHeight / (h - 1); + + var vl = []; + + // terrain edges + var vl_fr = [], + vl_bk = [], + vl_le = [], + vl_ri = []; + + for (i = 0; i < w; i++) { + x = -hpw + psw * i; + vl_fr.push(x, -hph, grid_values[k + i]); + vl_bk.push(x, hph, grid_values[i]); + } + + for (i = 0; i < h; i++) { + y = hph - psh * i; + vl_le.push(-hpw, y, grid_values[w * i]); + vl_ri.push(hpw, y, grid_values[w * (i + 1) - 1]); + } + + vl.push(vl_fr, vl_bk, vl_le, vl_ri); + + if (z0 !== undefined) { + // horizontal rectangle at bottom + vl.push([-hpw, -hph, z0, + hpw, -hph, z0, + hpw, hph, z0, + -hpw, hph, z0, + -hpw, -hph, z0]); + + // vertical lines at corners + [[-hpw, -hph, grid_values[grid_values.length - w]], + [ hpw, -hph, grid_values[grid_values.length - 1]], + [ hpw, hph, grid_values[w - 1]], + [-hpw, hph, grid_values[0]]].forEach(function (v) { + + vl.push([v[0], v[1], v[2], v[0], v[1], z0]); + + }); + } + + vl.forEach(function (v) { + + var geom = new THREE.BufferGeometry().setAttribute("position", new THREE.Float32BufferAttribute(v, 3)); + var obj = new THREE.Line(geom, material); + obj.name = "frame"; + parent.add(obj); + + }); + + parent.updateMatrixWorld(); + }, + + // add quad wireframe + addWireframe: function (layer, parent, material) { + + var grid = this.data.grid, + grid_values = grid.array, + w = grid.width, + h = grid.height, + planeWidth = this.data.width, + planeHeight = this.data.height, + hpw = planeWidth / 2, + hph = planeHeight / 2, + psw = planeWidth / (w - 1), + psh = planeHeight / (h - 1); + + var v, geom, x, y, vx, vy, group = new THREE.Group(); + + for (x = w - 1; x >= 0; x--) { + v = []; + vx = -hpw + psw * x; + + for (y = h - 1; y >= 0; y--) { + v.push(vx, hph - psh * y, grid_values[x + w * y]); + } + + geom = new THREE.BufferGeometry().setAttribute("position", new THREE.Float32BufferAttribute(v, 3)); + + group.add(new THREE.Line(geom, material)); + } + + for (y = h - 1; y >= 0; y--) { + v = []; + vy = hph - psh * y; + + for (x = w - 1; x >= 0; x--) { + v.push(-hpw + psw * x, vy, grid_values[x + w * y]); + } + + geom = new THREE.BufferGeometry().setAttribute("position", new THREE.Float32BufferAttribute(v, 3)); + + group.add(new THREE.Line(geom, material)); + } + + parent.add(group); + parent.updateMatrixWorld(); + }, + + getValue: function (x, y) { + var grid = this.data.grid; + if (0 <= x && x < grid.width && 0 <= y && y < grid.height) return grid.array[x + grid.width * y]; + return null; + }, + + contains: function (x, y) { + var translate = this.data.translate, + xmin = translate[0] - this.data.width / 2, + xmax = translate[0] + this.data.width / 2, + ymin = translate[1] - this.data.height / 2, + ymax = translate[1] + this.data.height / 2; + if (xmin <= x && x <= xmax && ymin <= y && y <= ymax) return true; + return false; + } + +}; + + +/* +Q3D.ClippedDEMBlock +*/ +Q3D.ClippedDEMBlock = function () { + this.materials = []; + this.currentMtlIndex = 0; +}; + +Q3D.ClippedDEMBlock.prototype = { + + constructor: Q3D.ClippedDEMBlock, + + loadJSONObject: function (obj, layer, callback) { + this.data = obj; + var _this = this; + + // load material + var m, mtl; + for (var i = 0, l = (obj.materials || []).length; i < l; i++) { + m = obj.materials[i]; + + mtl = new Q3D.Material(); + mtl.loadJSONObject(m, function () { + layer.requestRender(); + }); + this.materials[m.mtlIndex] = mtl; + + if (m.useNow) { + if (this.obj) { + layer.materials.removeItem(this.obj.material, true); + + this.obj.material = mtl.mtl; + + layer.materials.add(mtl); + layer.requestRender(); + } + this.currentMtlIndex = m.mtlIndex; + } + } + + if (obj.geom === undefined) return; + + var geom = new THREE.BufferGeometry(), + mesh = new THREE.Mesh(geom, (this.materials[this.currentMtlIndex] || {}).mtl); + mesh.position.fromArray(obj.translate); + mesh.scale.z = obj.zScale; + layer.addObject(mesh); + + var buildGeometry = function (obj) { + + var v = obj.triangles.v, + origin = layer.sceneData.origin, + be = layer.sceneData.baseExtent, + base_width = be.width, + base_height = be.height, + x0 = be.cx - origin.x - base_width * 0.5, + y0 = be.cy - origin.y - base_height * 0.5; + + var normals = [], uvs = []; + for (var i = 0, l = v.length; i < l; i += 3) { + normals.push(0, 0, 1); + uvs.push((v[i] - x0) / base_width, (v[i + 1] - y0) / base_height); + } + + geom.setIndex(obj.triangles.f); + geom.setAttribute("position", new THREE.Float32BufferAttribute(v, 3)); + geom.setAttribute("normal", new THREE.Float32BufferAttribute(normals, 3)); + geom.setAttribute("uv", new THREE.Float32BufferAttribute(uvs, 2)); + geom.computeVertexNormals(); + + geom.attributes.position.needsUpdate = true; + geom.attributes.normal.needsUpdate = true; + geom.attributes.uv.needsUpdate = true; + + _this.data.polygons = obj.polygons; + if (callback) callback(mesh); + }; + + if (obj.geom.url !== undefined) { + Q3D.application.loadFile(obj.geom.url, "json", function (obj) { + buildGeometry(obj); + }); + } + else { // local mode or WebKit Bridge + buildGeometry(obj.geom); + } + + this.obj = mesh; + return mesh; + }, + + buildSides: function (layer, parent, material, z0) { + var polygons = this.data.polygons, + bzFunc = function (x, y) { return z0; }; + + // make back-side material for bottom + var mat_back = material.clone(); + mat_back.side = THREE.BackSide; + layer.materials.add(mat_back); + + var geom, mesh, shape; + for (var i = 0, l = polygons.length; i < l; i++) { + var bnds = polygons[i]; + + // sides + for (var j = 0, m = bnds.length; j < m; j++) { + geom = Q3D.Utils.createWallGeometry(bnds[j], bzFunc, true); + mesh = new THREE.Mesh(geom, material); + mesh.name = "side"; + parent.add(mesh); + } + + // bottom + shape = new THREE.Shape(Q3D.Utils.flatArrayToVec2Array(bnds[0], 3)); + for (j = 1, m = bnds.length; j < m; j++) { + shape.holes.push(new THREE.Path(Q3D.Utils.flatArrayToVec2Array(bnds[j], 3))); + } + geom = new THREE.ShapeBufferGeometry(shape); + mesh = new THREE.Mesh(geom, mat_back); + mesh.position.z = z0; + mesh.name = "bottom"; + parent.add(mesh); + } + parent.updateMatrixWorld(); + }, + + // not implemented + getValue: function (x, y) { + return null; + }, + + // not implemented + contains: function (x, y) { + return false; + } + +}; + +/* +Q3D.MapLayer +*/ +Q3D.MapLayer = function () { + this.properties = {}; + + this.materials = new Q3D.Materials(); + this.materials.addEventListener("renderRequest", this.requestRender.bind(this)); + + this.objectGroup = new Q3D.Group(); + this.objectGroup.name = "layer"; + this.objects = []; +}; + +Q3D.MapLayer.prototype = Object.create(THREE.EventDispatcher.prototype); +Q3D.MapLayer.prototype.constructor = Q3D.MapLayer; + +Q3D.MapLayer.prototype.addObject = function (object) { + + object.userData.layerId = this.id; + this.objectGroup.add(object); + + var o = this.objects; + object.traverse(function (obj) { + o.push(obj); + }); + return this.objectGroup.children.length - 1; +}; + +Q3D.MapLayer.prototype.addObjects = function (objects) { + for (var i = 0; i < objects.length; i++) { + this.addObject(objects[i]); + } +}; + +Q3D.MapLayer.prototype.clearObjects = function () { + // dispose of geometries + this.objectGroup.traverse(function (obj) { + if (obj.geometry) obj.geometry.dispose(); + }); + + // dispose of materials + this.materials.dispose(); + + // remove all child objects from object group + for (var i = this.objectGroup.children.length - 1; i >= 0; i--) { + this.objectGroup.remove(this.objectGroup.children[i]); + } + this.objects = []; +}; + +Q3D.MapLayer.prototype.visibleObjects = function () { + return (this.visible) ? this.objects : []; +}; + +Q3D.MapLayer.prototype.loadJSONObject = function (jsonObject, scene) { + if (jsonObject.type == "layer") { + // properties + if (jsonObject.properties !== undefined) { + this.properties = jsonObject.properties; + this.visible = (jsonObject.properties.visible || Q3D.Config.allVisible) ? true : false; + } + + if (jsonObject.data !== undefined) { + this.clearObjects(); + + // materials + if (jsonObject.data.materials !== undefined) { + this.materials.loadJSONObject(jsonObject.data.materials); + } + } + + this.sceneData = scene.userData; + } +}; + +Object.defineProperty(Q3D.MapLayer.prototype, "clickable", { + get: function () { + return this.properties.clickable; + } +}); + +Object.defineProperty(Q3D.MapLayer.prototype, "opacity", { + get: function () { + return this.materials.opacity(); + }, + set: function (value) { + this.materials.setOpacity(value); + + if (this.labelGroup) { + this.labelGroup.traverse(function (obj) { + if (obj.material) obj.material.opacity = value; + }); + } + + if (this.labelConnectorGroup && this.labelConnectorGroup.children.length) { + this.labelConnectorGroup.children[0].material.opacity = value; + } + + this.requestRender(); + } +}); + +Object.defineProperty(Q3D.MapLayer.prototype, "visible", { + get: function () { + return this.objectGroup.visible; + }, + set: function (value) { + this.objectGroup.visible = value; + this.requestRender(); + } +}); + +Q3D.MapLayer.prototype.boundingBox = function () { + return new THREE.Box3().setFromObject(this.objectGroup); +}; + +Q3D.MapLayer.prototype.setWireframeMode = function (wireframe) { + this.materials.setWireframeMode(wireframe); +}; + +Q3D.MapLayer.prototype.requestRender = function () { + this.dispatchEvent({type: "renderRequest"}); +}; + + +/* +Q3D.DEMLayer --> Q3D.MapLayer +*/ +Q3D.DEMLayer = function () { + Q3D.MapLayer.call(this); + this.type = Q3D.LayerType.DEM; + this.blocks = []; +}; + +Q3D.DEMLayer.prototype = Object.create(Q3D.MapLayer.prototype); +Q3D.DEMLayer.prototype.constructor = Q3D.DEMLayer; + +Q3D.DEMLayer.prototype.loadJSONObject = function (jsonObject, scene) { + var old_blockIsClipped = this.properties.clipped; + + Q3D.MapLayer.prototype.loadJSONObject.call(this, jsonObject, scene); + if (jsonObject.type == "layer") { + if (old_blockIsClipped !== jsonObject.properties.clipped) { + // DEM type changed + this.blocks = []; + } + + var p = scene.userData, + rotation = p.baseExtent.rotation; + + if (jsonObject.properties.clipped) { + this.objectGroup.position.set(0, 0, 0); + this.objectGroup.rotation.z = 0; + + if (rotation) { + // rotate around center of base extent + this.objectGroup.position.copy(p.pivot).negate(); + this.objectGroup.position.applyAxisAngle(Q3D.uv.k, rotation * Q3D.deg2rad); + this.objectGroup.position.add(p.pivot); + this.objectGroup.rotateOnAxis(Q3D.uv.k, rotation * Q3D.deg2rad); + } + } + else { + this.objectGroup.position.copy(p.pivot); + this.objectGroup.position.z *= p.zScale; + this.objectGroup.rotation.z = rotation * Q3D.deg2rad; + } + this.objectGroup.updateMatrixWorld(); + + if (jsonObject.data !== undefined) { + jsonObject.data.forEach(function (obj) { + this.buildBlock(obj, scene, this); + }, this); + } + } + else if (jsonObject.type == "block") { + this.buildBlock(jsonObject, scene, this); + } +}; + +Q3D.DEMLayer.prototype.buildBlock = function (jsonObject, scene, layer) { + var _this = this, + block = this.blocks[jsonObject.block]; + + if (block === undefined) { + block = (layer.properties.clipped) ? (new Q3D.ClippedDEMBlock()) : (new Q3D.DEMBlock()); + this.blocks[jsonObject.block] = block; + } + + block.loadJSONObject(jsonObject, this, function (mesh) { + + var material; + if (jsonObject.wireframe) { + material = new Q3D.Material(); + material.loadJSONObject(jsonObject.wireframe.mtl); + _this.materials.add(material); + + block.addWireframe(_this, mesh, material.mtl); + + var mtl = block.material.mtl; + mtl.polygonOffset = true; + mtl.polygonOffsetFactor = 1; + mtl.polygonOffsetUnits = 1; + } + + if (jsonObject.sides) { + // sides and bottom + material = new Q3D.Material(); + material.loadJSONObject(jsonObject.sides.mtl); + _this.materials.add(material); + + block.buildSides(_this, mesh, material.mtl, jsonObject.sides.bottom); + _this.sideVisible = true; + } + + if (jsonObject.edges) { + material = new Q3D.Material(); + material.loadJSONObject(jsonObject.edges.mtl); + _this.materials.add(material); + + block.addEdges(_this, mesh, material.mtl, (jsonObject.sides) ? jsonObject.sides.bottom : undefined); + } + + _this.requestRender(); + }); +}; + +// calculate elevation at the coordinates (x, y) on triangle face +Q3D.DEMLayer.prototype.getZ = function (x, y) { + for (var i = 0, l = this.blocks.length; i < l; i++) { + var block = this.blocks[i], + data = block.data; + if (!block.contains(x, y)) continue; + + var ix = data.width / (data.grid.width - 1), + iy = data.height / (data.grid.height - 1); + + var xmin = data.translate[0] - data.width / 2, + ymax = data.translate[1] + data.height / 2; + + var mx0 = Math.floor((x - xmin) / ix), + my0 = Math.floor((ymax - y) / iy); + + var z = [block.getValue(mx0, my0), + block.getValue(mx0 + 1, my0), + block.getValue(mx0, my0 + 1), + block.getValue(mx0 + 1, my0 + 1)]; + + var px0 = xmin + ix * mx0, + py0 = ymax - iy * my0; + + var sdx = (x - px0) / ix, + sdy = (py0 - y) / iy; + + if (sdx <= 1 - sdy) return z[0] + (z[1] - z[0]) * sdx + (z[2] - z[0]) * sdy; + else return z[3] + (z[2] - z[3]) * (1 - sdx) + (z[1] - z[3]) * (1 - sdy); + } + return null; +}; + +Q3D.DEMLayer.prototype.segmentizeLineString = function (lineString, zFunc) { + // does not support multiple blocks + if (zFunc === undefined) zFunc = function () { return 0; }; + var width = this.sceneData.width, + height = this.sceneData.height; + var xmin = -width / 2, + ymax = height / 2; + var grid = this.blocks[0].data.grid, + ix = width / (grid.width - 1), + iy = height / (grid.height - 1); + var sort_func = function (a, b) { return a - b; }; + + var pts = []; + for (var i = 1, l = lineString.length; i < l; i++) { + var pt1 = lineString[i - 1], pt2 = lineString[i]; + var x1 = pt1[0], x2 = pt2[0], y1 = pt1[1], y2 = pt2[1], z1 = pt1[2], z2 = pt2[2]; + var nx1 = (x1 - xmin) / ix, + nx2 = (x2 - xmin) / ix; + var ny1 = (ymax - y1) / iy, + ny2 = (ymax - y2) / iy; + var ns1 = Math.abs(ny1 + nx1), + ns2 = Math.abs(ny2 + nx2); + + var p = [0], nvp = [[nx1, nx2], [ny1, ny2], [ns1, ns2]]; + for (var j = 0; j < 3; j++) { + var v1 = nvp[j][0], v2 = nvp[j][1]; + if (v1 == v2) continue; + var k = Math.ceil(Math.min(v1, v2)); + var n = Math.floor(Math.max(v1, v2)); + for (; k <= n; k++) { + p.push((k - v1) / (v2 - v1)); + } + } + + p.sort(sort_func); + + var x, y, z, lp = null; + for (var j = 0, m = p.length; j < m; j++) { + if (lp === p[j]) continue; + if (p[j] == 1) break; + + x = x1 + (x2 - x1) * p[j]; + y = y1 + (y2 - y1) * p[j]; + + if (z1 === undefined || z2 === undefined) z = zFunc(x, y); + else z = z1 + (z2 - z1) * p[j]; + + pts.push(new THREE.Vector3(x, y, z)); + + // Q3D.Utils.putStick(x, y, zFunc); + + lp = p[j]; + } + } + // last point (= the first point) + var pt = lineString[lineString.length - 1]; + pts.push(new THREE.Vector3(pt[0], pt[1], (pt[2] === undefined) ? zFunc(pt[0], pt[1]) : pt[2])); + + /* + for (var i = 0, l = lineString.length - 1; i < l; i++) { + Q3D.Utils.putStick(lineString[i][0], lineString[i][1], zFunc, 0.8); + } + */ + return pts; +}; + +Q3D.DEMLayer.prototype.setCurrentMaterial = function (mtlIndex) { + + this.materials.removeGroupItems(this.currentMtlIndex); + + this.currentMtlIndex = mtlIndex; + + var b, m; + for (var i = 0, l = this.blocks.length; i < l; i++) { + b = this.blocks[i]; + m = b.materials[mtlIndex]; + if (m !== undefined) { + b.obj.material = m.mtl; + this.materials.add(m); + } + } + this.requestRender(); +}; + +Q3D.DEMLayer.prototype.setSideVisible = function (visible) { + this.sideVisible = visible; + this.objectGroup.traverse(function (obj) { + if (obj.name == "side" || obj.name == "bottom") obj.visible = visible; + }); +}; + +// texture animation +Q3D.DEMLayer.prototype.prepareTexAnimation = function (from, to) { + + function imageData2Canvas(img) { + var cnvs = document.createElement("canvas"); + cnvs.width = img.width; + cnvs.height = img.height; + + var ctx = cnvs.getContext("2d"); + ctx.putImageData(img, 0, 0); + return cnvs; + } + + this.anim = []; + + var m, canvas, ctx, opt, mtl; + var img_from, img_to; + for (var i = 0; i < this.blocks.length; i++) { + + m = this.blocks[i].obj.material; + + img_from = this.blocks[i].materials[from].mtl.map.image; + img_to = this.blocks[i].materials[to].mtl.map.image; + + canvas = document.createElement("canvas"); + canvas.width = (img_from.width > img_to.width) ? img_from.width : img_to.width; + canvas.height = (img_from.width > img_to.width) ? img_from.height : img_to.height; + + ctx = canvas.getContext("2d"); + + opt = {}; + opt.map = new THREE.CanvasTexture(canvas); + opt.map.anisotropy = Q3D.Config.texture.anisotropy; + opt.transparent = true; + + mtl = undefined; + if (m) { + if (m.isMeshToonMaterial) { + mtl = new THREE.MeshToonMaterial(opt); + } + else if (m.isMeshPhongMaterial) { + mtl = new THREE.MeshPhongMaterial(opt); + } + } + if (mtl === undefined) { + mtl = new THREE.MeshLambertMaterial(opt); + } + + if (img_from instanceof ImageData) { // WebKit Bridge + img_from = imageData2Canvas(img_from); + img_to = imageData2Canvas(img_to); + } + + this.blocks[i].obj.material = mtl; + + this.materials.add(mtl); + + this.anim.push({ + img_from: img_from, + img_to: img_to, + ctx: ctx, + tex: mtl.map + }); + } +}; + +Q3D.DEMLayer.prototype.setTextureAt = function (progress, effect) { + + if (this.anim === undefined) return; + + var a, w, h, w0, h0, w1, h1, ew, ew1; + for (var i = 0; i < this.anim.length; i++) { + a = this.anim[i]; + w = a.ctx.canvas.width; + h = a.ctx.canvas.height; + w0 = a.img_from.width; + h0 = a.img_from.height; + w1 = a.img_to.width; + h1 = a.img_to.height; + + if (effect == 0) { // fade in + a.ctx.globalAlpha = 1; + a.ctx.drawImage(a.img_from, 0, 0, w0, h0, + 0, 0, w, h); + a.ctx.globalAlpha = progress; + a.ctx.drawImage(a.img_to, 0, 0, w1, h1, + 0, 0, w, h); + } + else if (effect == 2) { // slide to left (not used) + if (progress === null) { + a.ctx.drawImage(a.img_from, 0, 0, w0, h0, + 0, 0, w, h); + } + else { + ew1 = w1 * progress; + ew = w * progress; + a.ctx.drawImage(a.img_to, w1 - ew1, 0, ew1, h1, + w - ew, 0, ew, h); + } + } + a.tex.needsUpdate = true; + } +}; + +/* +Q3D.VectorLayer --> Q3D.MapLayer +*/ +Q3D.VectorLayer = function () { + Q3D.MapLayer.call(this); + + this.features = []; + this.labels = []; +}; + +Q3D.VectorLayer.prototype = Object.create(Q3D.MapLayer.prototype); +Q3D.VectorLayer.prototype.constructor = Q3D.VectorLayer; + +// Q3D.VectorLayer.prototype.build = function (features, startIndex) {}; + +Q3D.VectorLayer.prototype.addFeature = function (featureIdx, f, objs) { + Q3D.MapLayer.prototype.addObjects.call(this, objs); + + for (var i = 0; i < objs.length; i++) { + objs[i].userData.featureIdx = featureIdx; + } + f.objs = objs; + + this.features[featureIdx] = f; + return f; +}; + +Q3D.VectorLayer.prototype.clearLabels = function () { + this.labels = []; + if (this.labelGroup) this.labelGroup.clear(); + if (this.labelConnectorGroup) this.labelConnectorGroup.clear(); +}; + +Q3D.VectorLayer.prototype.buildLabels = function (features, getPointsFunc) { + if (this.properties.label === undefined || getPointsFunc === undefined) return; + + var _this = this, + p = this.properties, + label = p.label, + bs = this.sceneData.baseExtent.width * 0.016, + sc = bs * Math.pow(1.2, label.size); + + var hasOtl = (label.olcolor !== undefined), + hasConn = (label.cncolor !== undefined); + + if (hasConn) { + var line_mtl = new THREE.LineBasicMaterial({ + color: label.cncolor, + opacity: this.materials.opacity(), + transparent: true + }); + } + + var hasUnderline = Boolean(hasConn && label.underline); + if (hasUnderline) { + var ul_geom = new THREE.BufferGeometry(); + ul_geom.setAttribute("position", new THREE.Float32BufferAttribute([0, 0, 0, 1, 0, 0], 3)); + + var onBeforeRender = function (renderer, scene, camera, geometry, material, group) { + this.quaternion.copy(camera.quaternion); + this.updateMatrixWorld(); + }; + } + + var canvas = document.createElement("canvas"), + ctx = canvas.getContext("2d"); + + var font, tw, th, cw, ch; + th = ch = Q3D.Config.label.canvasHeight; + font = th + "px " + (label.font || "sans-serif"); + + canvas.height = ch; + + var f, text, partIdx, vec, sprite, mtl, geom, conn, x, y, j, sc, opacity; + var underline; + + for (var i = 0, l = features.length; i < l; i++) { + f = features[i]; + text = f.lbl; + if (!text) continue; + + opacity = this.materials.mtl(f.mtl).opacity; + + partIdx = 0; + getPointsFunc(f).forEach(function (pt) { + + // label position + vec = new THREE.Vector3(pt[0], pt[1], (label.relative) ? pt[2] + f.lh : f.lh); + + // render label text + ctx.font = font; + tw = ctx.measureText(text).width + 2; + cw = THREE.Math.ceilPowerOfTwo(tw); + x = cw / 2; + y = ch / 2; + + canvas.width = cw; + ctx.clearRect(0, 0, cw, ch); + + if (label.bgcolor !== undefined) { + ctx.fillStyle = label.bgcolor; + ctx.roundRect((cw - tw) / 2, (ch - th) / 2, tw, th, 4).fill(); // definition is in this file + } + + ctx.font = font; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + + if (hasOtl) { + // outline effect + ctx.fillStyle = label.olcolor; + for (j = 0; j < 9; j++) { + if (j != 4) ctx.fillText(text, x + Math.floor(j / 3) - 1, y + j % 3 - 1); + } + } + + ctx.fillStyle = label.color; + ctx.fillText(text, x, y); + + mtl = new THREE.SpriteMaterial({ + map: new THREE.TextureLoader().load(canvas.toDataURL(), function () { _this.requestRender(); }), + opacity: opacity, + transparent: true + }); + + sprite = new THREE.Sprite(mtl); + if (hasUnderline) { + sprite.center.set((1 - tw / cw) * 0.5, 0); + } + else { + sprite.center.set(0.5, 0); + } + sprite.position.copy(vec); + sprite.scale.set(sc * cw / ch, sc, 1); + + sprite.userData.layerId = this.id; + sprite.userData.properties = f.prop; + sprite.userData.objs = f.objs; + sprite.userData.partIdx = partIdx; + sprite.userData.isLabel = true; + + this.labelGroup.add(sprite); + + if (Q3D.Config.label.clickable) this.labels.push(sprite); + + if (hasConn) { + // a connector + geom = new THREE.BufferGeometry(); + geom.setAttribute("position", new THREE.Float32BufferAttribute(vec.toArray().concat(pt), 3)); + + conn = new THREE.Line(geom, line_mtl); + conn.userData = sprite.userData; + + this.labelConnectorGroup.add(conn); + + if (hasUnderline) { + underline = new THREE.Line(ul_geom, line_mtl); + underline.position.copy(vec); + underline.scale.x = sc * tw / th; + underline.updateMatrixWorld(); + underline.onBeforeRender = onBeforeRender; + conn.add(underline); + } + } + partIdx++; + }, this); + } +}; + +Q3D.VectorLayer.prototype.loadJSONObject = function (jsonObject, scene) { + Q3D.MapLayer.prototype.loadJSONObject.call(this, jsonObject, scene); + if (jsonObject.type == "layer") { + if (jsonObject.data !== undefined) { + this.features = []; + this.clearLabels(); + + // build labels + if (this.properties.label !== undefined) { + // create a label group and a label connector group + if (this.labelGroup === undefined) { + this.labelGroup = new Q3D.Group(); + this.labelGroup.userData.layerId = this.id; + this.labelGroup.visible = this.visible; + scene.labelGroup.add(this.labelGroup); + } + + if (this.labelConnectorGroup === undefined) { + this.labelConnectorGroup = new Q3D.Group(); + this.labelConnectorGroup.userData.layerId = this.id; + this.labelConnectorGroup.visible = this.visible; + scene.labelConnectorGroup.add(this.labelConnectorGroup); + } + } + + (jsonObject.data.blocks || []).forEach(function (block) { + if (block.url !== undefined) Q3D.application.loadJSONFile(block.url); + else { + this.build(block.features, block.startIndex); + if (this.properties.label !== undefined) this.buildLabels(block.features); + } + }, this); + } + } + else if (jsonObject.type == "block") { + this.build(jsonObject.features, jsonObject.startIndex); + if (this.properties.label !== undefined) this.buildLabels(jsonObject.features); + } +}; + +Object.defineProperty(Q3D.VectorLayer.prototype, "visible", { + get: function () { + return Object.getOwnPropertyDescriptor(Q3D.MapLayer.prototype, "visible").get.call(this); + }, + set: function (value) { + if (this.labelGroup) this.labelGroup.visible = value; + if (this.labelConnectorGroup) this.labelConnectorGroup.visible = value; + Object.getOwnPropertyDescriptor(Q3D.MapLayer.prototype, "visible").set.call(this, value); + } +}); + + +/* +Q3D.PointLayer --> Q3D.VectorLayer +*/ +Q3D.PointLayer = function () { + Q3D.VectorLayer.call(this); + this.type = Q3D.LayerType.Point; +}; + +Q3D.PointLayer.prototype = Object.create(Q3D.VectorLayer.prototype); +Q3D.PointLayer.prototype.constructor = Q3D.PointLayer; + +Q3D.PointLayer.prototype.loadJSONObject = function (jsonObject, scene) { + if (jsonObject.type == "layer" && jsonObject.properties.objType == "3D Model" && jsonObject.data !== undefined) { + if (this.models === undefined) { + var _this = this; + + this.models = new Q3D.Models(); + this.models.addEventListener("modelLoaded", function (event) { + _this.materials.addFromObject3D(event.model.scene); + _this.requestRender(); + }); + } + else { + this.models.clear(); + } + this.models.loadJSONObject(jsonObject.data.models); + } + + Q3D.VectorLayer.prototype.loadJSONObject.call(this, jsonObject, scene); +}; + +Q3D.PointLayer.prototype.build = function (features, startIndex) { + var objType = this.properties.objType; + if (objType == "Point") { + return this.buildPoints(features, startIndex); + } + else if (objType == "Billboard") { + return this.buildBillboards(features, startIndex); + } + else if (objType == "3D Model") { + return this.buildModels(features, startIndex); + } + + var unitGeom, transform; + if (this.cachedGeometryType === objType) { + unitGeom = this.geometryCache; + transform = this.transformCache; + } + else { + var gt = this.geomAndTransformFunc(objType); + unitGeom = gt[0]; + transform = gt[1]; + } + + var f, mtl, pts, i, l, mesh, meshes; + for (var fidx = 0; fidx < features.length; fidx++) { + f = features[fidx]; + pts = f.geom.pts; + mtl = this.materials.mtl(f.mtl); + + meshes = []; + for (i = 0, l = pts.length; i < l; i++) { + mesh = new THREE.Mesh(unitGeom, mtl); + transform(mesh, f.geom, pts[i]); + + mesh.userData.properties = f.prop; + + meshes.push(mesh); + } + this.addFeature(fidx + startIndex, f, meshes); + } + + this.cachedGeometryType = objType; + this.geometryCache = unitGeom; + this.transformCache = transform; +}; + +Q3D.PointLayer.prototype.geomAndTransformFunc = function (objType) { + + var deg2rad = Q3D.deg2rad, + rx = 90 * deg2rad; + + if (objType == "Sphere") { + return [ + new THREE.SphereBufferGeometry(1, 32, 32), + function (mesh, geom, pt) { + mesh.scale.setScalar(geom.r); + mesh.position.fromArray(pt); + } + ]; + } + else if (objType == "Box") { + return [ + new THREE.BoxBufferGeometry(1, 1, 1), + function (mesh, geom, pt) { + mesh.scale.set(geom.w, geom.h, geom.d); + mesh.rotation.x = rx; + mesh.position.set(pt[0], pt[1], pt[2] + geom.h / 2); + } + ]; + } + else if (objType == "Disk") { + var sz = this.sceneData.zScale; + return [ + new THREE.CircleBufferGeometry(1, 32), + function (mesh, geom, pt) { + mesh.scale.set(geom.r, geom.r * sz, 1); + mesh.rotateOnWorldAxis(Q3D.uv.i, -geom.d * deg2rad); + mesh.rotateOnWorldAxis(Q3D.uv.k, -geom.dd * deg2rad); + mesh.position.fromArray(pt); + } + ]; + } + else if (objType == "Plane") { + var sz = this.sceneData.zScale; + return [ + new THREE.PlaneBufferGeometry(1, 1, 1, 1), + function (mesh, geom, pt) { + mesh.scale.set(geom.w, geom.l * sz, 1); + mesh.rotateOnWorldAxis(Q3D.uv.i, -geom.d * deg2rad); + mesh.rotateOnWorldAxis(Q3D.uv.k, -geom.dd * deg2rad); + mesh.position.fromArray(pt); + } + ]; + } + + // Cylinder or Cone + var radiusTop = (objType == "Cylinder") ? 1 : 0; + return [ + new THREE.CylinderBufferGeometry(radiusTop, 1, 1, 32), + function (mesh, geom, pt) { + mesh.scale.set(geom.r, geom.h, geom.r); + mesh.rotation.x = rx; + mesh.position.set(pt[0], pt[1], pt[2] + geom.h / 2); + } + ]; +}; + +Q3D.PointLayer.prototype.buildPoints = function (features, startIndex) { + var f, geom, mtl, obj; + for (var fidx = 0; fidx < features.length; fidx++) { + f = features[fidx]; + + geom = new THREE.BufferGeometry().setAttribute("position", new THREE.Float32BufferAttribute(f.geom.pts, 3)); + mtl = this.materials.mtl(f.mtl); + + obj = new THREE.Points(geom, mtl); + obj.userData.properties = f.prop; + + this.addFeature(fidx + startIndex, f, [obj]); + } +}; + +Q3D.PointLayer.prototype.buildBillboards = function (features, startIndex) { + + features.forEach(function (f, fidx) { + + var material = this.materials.get(f.mtl); + + var sprite, sprites = []; + for (var i = 0; i < f.geom.pts.length; i++) { + sprite = new THREE.Sprite(material.mtl); + sprite.position.fromArray(f.geom.pts[i]); + sprite.userData.properties = f.prop; + + sprites.push(sprite); + } + + material.callbackOnLoad(function () { + var img = material.mtl.map.image; + for (var i = 0; i < sprites.length; i++) { + sprites[i].scale.set(f.geom.size, + f.geom.size * img.height / img.width, + 1); + sprites[i].updateMatrixWorld(); + } + }); + + this.addFeature(fidx + startIndex, f, sprites); + }, this); +}; + +Q3D.PointLayer.prototype.buildModels = function (features, startIndex) { + var q = new THREE.Quaternion(), + e = new THREE.Euler(), + deg2rad = Q3D.deg2rad; + + features.forEach(function (f, fidx) { + + var model = this.models.get(f.model); + if (!model) { + console.log("3D Model: There is a missing model."); + return; + } + + var parents = []; + var pt, pts = f.geom.pts; + for (var i = 0; i < pts.length; i++) { + pt = pts[i]; + + var parent = new Q3D.Group(); + parent.position.fromArray(pt); + parent.scale.set(1, 1, this.sceneData.zScale); + + parent.userData.properties = f.prop; + + parents.push(parent); + } + + model.callbackOnLoad(function (m) { + var parent, obj; + for (var i = 0; i < parents.length; i++) { + parent = parents[i]; + + obj = m.scene.clone(); + obj.scale.setScalar(f.geom.scale); + + if (obj.rotation.x) { + // reset coordinate system to z-up and specified rotation + obj.rotation.set(0, 0, 0); + obj.quaternion.multiply(q.setFromEuler(e.set(f.geom.rotateX * deg2rad, + f.geom.rotateY * deg2rad, + f.geom.rotateZ * deg2rad, + f.geom.rotateO || "XYZ"))); + } + else { + // y-up to z-up and specified rotation + obj.quaternion.multiply(q.setFromEuler(e.set(f.geom.rotateX * deg2rad, + f.geom.rotateY * deg2rad, + f.geom.rotateZ * deg2rad, + f.geom.rotateO || "XYZ"))); + obj.quaternion.multiply(q.setFromEuler(e.set(Math.PI / 2, 0, 0))); + } + parent.add(obj); + } + }); + + this.addFeature(fidx + startIndex, f, parents); + }, this); +}; + +Q3D.PointLayer.prototype.buildLabels = function (features) { + Q3D.VectorLayer.prototype.buildLabels.call(this, features, function (f) { return f.geom.pts; }); +}; + + +/* +Q3D.LineLayer --> Q3D.VectorLayer +*/ +Q3D.LineLayer = function () { + Q3D.VectorLayer.call(this); + this.type = Q3D.LayerType.Line; +}; + +Q3D.LineLayer.prototype = Object.create(Q3D.VectorLayer.prototype); +Q3D.LineLayer.prototype.constructor = Q3D.LineLayer; + +Q3D.LineLayer.prototype.clearObjects = function () { + Q3D.VectorLayer.prototype.clearObjects.call(this); + + if (this.origMtls) { + this.origMtls.dispose(); + this.origMtls = undefined; + } +}; + +Q3D.LineLayer.prototype.build = function (features, startIndex) { + + if (this._lastObjType !== this.properties.objType) this._createObject = null; + + var createObject = this._createObject || this.createObjFunc(this.properties.objType); + + var f, i, lines, obj, objs; + for (var fidx = 0; fidx < features.length; fidx++) { + f = features[fidx]; + lines = f.geom.lines; + + objs = []; + for (i = 0; i < lines.length; i++) { + obj = createObject(f, lines[i]); + obj.userData.properties = f.prop; + obj.userData.mtl = f.mtl; + + objs.push(obj); + } + this.addFeature(fidx + startIndex, f, objs); + } + + this._lastObjType = this.properties.objType; + this._createObject = createObject; +}; + +Q3D.LineLayer.prototype.createObjFunc = function (objType) { + var materials = this.materials; + + if (objType == "Line") { + return function (f, vertices) { + var geom = new THREE.BufferGeometry().setAttribute("position", new THREE.Float32BufferAttribute(vertices, 3)); + + var obj = new THREE.Line(geom, materials.mtl(f.mtl)); + if (obj.material instanceof THREE.LineDashedMaterial) obj.computeLineDistances(); + return obj; + }; + } + else if (objType == "Thick Line") { + return function (f, vertices) { + var line = new MeshLine(); + line.setPoints(vertices); + + return new THREE.Mesh(line, materials.mtl(f.mtl)); + }; + } + else if (objType == "Pipe" || objType == "Cone") { + var jointGeom, cylinGeom; + if (objType == "Pipe") { + jointGeom = new THREE.SphereBufferGeometry(1, 32, 32); + cylinGeom = new THREE.CylinderBufferGeometry(1, 1, 1, 32); + } + else { + cylinGeom = new THREE.CylinderBufferGeometry(0, 1, 1, 32); + } + + var group, mesh, axis = Q3D.uv.j; + var pt0 = new THREE.Vector3(), pt1 = new THREE.Vector3(), sub = new THREE.Vector3(); + + return function (f, points) { + group = new Q3D.Group(); + + pt0.fromArray(points[0]); + for (var i = 1, l = points.length; i < l; i++) { + pt1.fromArray(points[i]); + + mesh = new THREE.Mesh(cylinGeom, materials.mtl(f.mtl)); + mesh.scale.set(f.geom.r, pt0.distanceTo(pt1), f.geom.r); + mesh.position.set((pt0.x + pt1.x) / 2, (pt0.y + pt1.y) / 2, (pt0.z + pt1.z) / 2); + mesh.quaternion.setFromUnitVectors(axis, sub.subVectors(pt1, pt0).normalize()); + group.add(mesh); + + if (jointGeom && i < l - 1) { + mesh = new THREE.Mesh(jointGeom, materials.mtl(f.mtl)); + mesh.scale.setScalar(f.geom.r); + mesh.position.copy(pt1); + group.add(mesh); + } + + pt0.copy(pt1); + } + return group; + }; + } + else if (objType == "Box") { + // In this method, box corners are exposed near joint when both azimuth and slope of + // the segments of both sides are different. Also, some unnecessary faces are created. + var faces = [], vi; + vi = [[0, 5, 4], [4, 5, 1], // left turn - top, side, bottom + [3, 0, 7], [7, 0, 4], + [6, 3, 2], [2, 3, 7], + [4, 1, 0], [0, 1, 5], // right turn - top, side, bottom + [1, 2, 5], [5, 2, 6], + [2, 7, 6], [6, 7, 3]]; + + for (var j = 0; j < 12; j++) { + faces.push(new THREE.Face3(vi[j][0], vi[j][1], vi[j][2])); + } + + return function (f, points) { + var geometry = new THREE.Geometry(); + + var geom, dist, rx, rz, wh4, vb4, vf4; + var pt0 = new THREE.Vector3(), pt1 = new THREE.Vector3(), sub = new THREE.Vector3(), + pt = new THREE.Vector3(), ptM = new THREE.Vector3(), scale1 = new THREE.Vector3(1, 1, 1), + matrix = new THREE.Matrix4(), quat = new THREE.Quaternion(); + + pt0.fromArray(points[0]); + for (var i = 1, l = points.length; i < l; i++) { + pt1.fromArray(points[i]); + dist = pt0.distanceTo(pt1); + sub.subVectors(pt1, pt0); + rx = Math.atan2(sub.z, Math.sqrt(sub.x * sub.x + sub.y * sub.y)); + rz = Math.atan2(sub.y, sub.x) - Math.PI / 2; + ptM.set((pt0.x + pt1.x) / 2, (pt0.y + pt1.y) / 2, (pt0.z + pt1.z) / 2); // midpoint + quat.setFromEuler(new THREE.Euler(rx, 0, rz, "ZXY")); + matrix.compose(ptM, quat, scale1); + + // place a box to the segment + geom = new THREE.BoxGeometry(f.geom.w, dist, f.geom.h); + geom.applyMatrix(matrix); + geometry.merge(geom); + + // joint + // 4 vertices of backward side of current segment + wh4 = [[-f.geom.w / 2, f.geom.h / 2], + [f.geom.w / 2, f.geom.h / 2], + [f.geom.w / 2, -f.geom.h / 2], + [-f.geom.w / 2, -f.geom.h / 2]]; + vb4 = []; + for (j = 0; j < 4; j++) { + pt.set(wh4[j][0], -dist / 2, wh4[j][1]); + pt.applyMatrix4(matrix); + vb4.push(pt.clone()); + } + + if (vf4) { + geom = new THREE.Geometry(); + geom.vertices = vf4.concat(vb4); + geom.faces = faces; + geometry.merge(geom); + } + + // 4 vertices of forward side + vf4 = []; + for (j = 0; j < 4; j++) { + pt.set(wh4[j][0], dist / 2, wh4[j][1]); + pt.applyMatrix4(matrix); + vf4.push(new THREE.Vector3(pt.x, pt.y, pt.z)); + } + + pt0.copy(pt1); + } + + geometry.faceVertexUvs = [[]]; + geometry.mergeVertices(); + geometry.computeFaceNormals(); + return new THREE.Mesh(geometry, materials.mtl(f.mtl)); + }; + } + else if (objType == "Wall") { + return function (f, vertices) { + var bzFunc = function (x, y) { return f.geom.bh; }; + return new THREE.Mesh(Q3D.Utils.createWallGeometry(vertices, bzFunc), + materials.mtl(f.mtl)); + }; + } +}; + +Q3D.LineLayer.prototype.buildLabels = function (features) { + // Line layer doesn't support label + // Q3D.VectorLayer.prototype.buildLabels.call(this, features); +}; + +// prepare for growing line animation +Q3D.LineLayer.prototype.prepareAnimation = function (sequential) { + + if (this.origMtls !== undefined) return; + + function computeLineDistances(obj) { + if (!obj.material.isLineDashedMaterial) return; + + obj.computeLineDistances(); + + var dists = obj.geometry.attributes.lineDistance.array; + obj.lineLength = dists[dists.length - 1]; + + for (var i = 0; i < dists.length; i++) { + dists[i] /= obj.lineLength; + } + } + + this.origMtls = new Q3D.Materials(); + this.origMtls.array = this.materials.array; + + this.materials.array = []; + + if (sequential) { + var f, m, mtl, j; + for (var i = 0; i < this.features.length; i++) { + f = this.features[i]; + m = f.objs[0].material; + + if (m.isMeshLineMaterial) { + mtl = new MeshLineMaterial(); + mtl.color = m.color; + mtl.opacity = m.opacity; + mtl.lineWidth = m.lineWidth; + mtl.dashArray = 2; + mtl.transparent = true; + } + else { + if (m.isLineDashedMaterial) { + mtl = m.clone(); + } + else { + mtl = new THREE.LineDashedMaterial({color: m.color, opacity: m.opacity}); + } + mtl.gapSize = 1; + } + + for (j = 0; j < f.objs.length; j++) { + f.objs[j].material = mtl; + computeLineDistances(f.objs[j]); + } + this.materials.add(mtl); + } + } + else { + var mtl, mtls = this.origMtls.array; + + for (var i = 0; i < mtls.length; i++) { + mtl = mtls[i].mtl; + + if (mtl.isLineDashedMaterial) { + mtl.gapSize = 1; + } + else if (mtl.isMeshLineMaterial) { + mtl.dashArray = 2; + mtl.transparent = true; + } + else if (mtl.isLineBasicMaterial) { + mtl = new THREE.LineDashedMaterial({color: mtl.color, opacity: mtl.opacity}); + } + + this.materials.add(mtl); + } + + var _this = this; + this.objectGroup.traverse(function (obj) { + + if (obj.userData.mtl !== undefined) { + obj.material = _this.materials.mtl(obj.userData.mtl); + computeLineDistances(obj); + } + + }); + } +}; + +// length: number [0 - 1] +Q3D.LineLayer.prototype.setLineLength = function (length, featureIdx) { + + if (this.origMtls === undefined) return; + + var mtl; + if (featureIdx === undefined) { + var mtls = this.materials.array; + for (var i = 0; i < mtls.length; i++) { + mtl = mtls[i].mtl; + if (mtl.isLineDashedMaterial) { + mtl.dashSize = length; + } + else if (mtl.isMeshLineMaterial) { + mtl.uniforms.dashOffset.value = -length; + } + } + } + else { + mtl = this.features[featureIdx].objs[0].material; + if (mtl.isLineDashedMaterial) { + mtl.dashSize = length; + } + else if (mtl.isMeshLineMaterial) { + mtl.uniforms.dashOffset.value = -length; + } + } +}; + + +/* +Q3D.PolygonLayer --> Q3D.VectorLayer +*/ +Q3D.PolygonLayer = function () { + Q3D.VectorLayer.call(this); + this.type = Q3D.LayerType.Polygon; + + // for overlay + this.borderVisible = true; + this.sideVisible = true; +}; + +Q3D.PolygonLayer.prototype = Object.create(Q3D.VectorLayer.prototype); +Q3D.PolygonLayer.prototype.constructor = Q3D.PolygonLayer; + +Q3D.PolygonLayer.prototype.loadJSONObject = function (jsonObject, scene) { + Q3D.VectorLayer.prototype.loadJSONObject.call(this, jsonObject, scene); +}; + +Q3D.PolygonLayer.prototype.build = function (features, startIndex) { + + if (this.properties.objType !== this._lastObjType) this._createObject = null; + + var createObject = this._createObject || this.createObjFunc(this.properties.objType); + + var f, obj; + for (var fidx = 0; fidx < features.length; fidx++) { + f = features[fidx]; + obj = createObject(f); + obj.userData.properties = f.prop; + + this.addFeature(fidx + startIndex, f, [obj]); + } + + this._lastObjType = this.properties.objType; + this._createObject = createObject; +}; + +Q3D.PolygonLayer.prototype.createObjFunc = function (objType) { + + var materials = this.materials; + + if (objType == "Polygon") { + return function (f) { + var geom = new THREE.BufferGeometry(); + geom.setAttribute("position", new THREE.Float32BufferAttribute(f.geom.triangles.v, 3)); + geom.setIndex(f.geom.triangles.f); + geom = new THREE.Geometry().fromBufferGeometry(geom); // Flat shading doesn't work with combination of + // BufferGeometry and Lambert/Toon material. + return new THREE.Mesh(geom, materials.mtl(f.mtl)); + }; + } + else if (objType == "Extruded") { + var createSubObject = function (f, polygon, z) { + var i, l, j, m; + + var shape = new THREE.Shape(Q3D.Utils.arrayToVec2Array(polygon[0])); + for (i = 1, l = polygon.length; i < l; i++) { + shape.holes.push(new THREE.Path(Q3D.Utils.arrayToVec2Array(polygon[i]))); + } + + // extruded geometry + var geom = new THREE.ExtrudeBufferGeometry(shape, {bevelEnabled: false, depth: f.geom.h}); + var mesh = new THREE.Mesh(geom, materials.mtl(f.mtl.face)); + mesh.position.z = z; + + if (f.mtl.edge !== undefined) { + // edge + var edge, bnd, v, + h = f.geom.h, + mtl = materials.mtl(f.mtl.edge); + + for (i = 0, l = polygon.length; i < l; i++) { + bnd = polygon[i]; + + v = []; + for (j = 0, m = bnd.length; j < m; j++) { + v.push(bnd[j][0], bnd[j][1], 0); + } + + geom = new THREE.BufferGeometry().setAttribute("position", new THREE.Float32BufferAttribute(v, 3)); + + edge = new THREE.Line(geom, mtl); + mesh.add(edge); + + edge = new THREE.Line(geom, mtl); + edge.position.z = h; + mesh.add(edge); + + // vertical lines + for (j = 0, m = bnd.length - 1; j < m; j++) { + v = [bnd[j][0], bnd[j][1], 0, + bnd[j][0], bnd[j][1], h]; + + geom = new THREE.BufferGeometry().setAttribute("position", new THREE.Float32BufferAttribute(v, 3)); + + edge = new THREE.Line(geom, mtl); + mesh.add(edge); + } + } + } + return mesh; + }; + + var polygons, centroids; + + return function (f) { + polygons = f.geom.polygons; + centroids = f.geom.centroids; + + if (polygons.length == 1) return createSubObject(f, polygons[0], centroids[0][2]); + + var group = new THREE.Group(); + for (var i = 0, l = polygons.length; i < l; i++) { + group.add(createSubObject(f, polygons[i], centroids[i][2])); + } + return group; + }; + } + else if (objType == "Overlay") { + + var _this = this; + + return function (f) { + + var geom = new THREE.BufferGeometry(); + geom.setIndex(f.geom.triangles.f); + geom.setAttribute("position", new THREE.Float32BufferAttribute(f.geom.triangles.v, 3)); + geom.computeVertexNormals(); + + var mesh = new THREE.Mesh(geom, materials.mtl(f.mtl.face)); + + var rotation = _this.sceneData.baseExtent.rotation; + if (rotation) { + // rotate around center of base extent + mesh.position.copy(_this.sceneData.pivot).negate(); + mesh.position.applyAxisAngle(Q3D.uv.k, rotation * Q3D.deg2rad); + mesh.position.add(_this.sceneData.pivot); + mesh.rotateOnAxis(Q3D.uv.k, rotation * Q3D.deg2rad); + } + + // borders + if (f.geom.brdr !== undefined) { + var bnds, i, l, j, m; + for (i = 0, l = f.geom.brdr.length; i < l; i++) { + bnds = f.geom.brdr[i]; + for (j = 0, m = bnds.length; j < m; j++) { + geom = new THREE.BufferGeometry().setAttribute("position", new THREE.Float32BufferAttribute(bnds[j], 3)); + + mesh.add(new THREE.Line(geom, materials.mtl(f.mtl.brdr))); + } + } + } + return mesh; + }; + } +}; + +Q3D.PolygonLayer.prototype.buildLabels = function (features) { + Q3D.VectorLayer.prototype.buildLabels.call(this, features, function (f) { return f.geom.centroids; }); +}; + +Q3D.PolygonLayer.prototype.setBorderVisible = function (visible) { + if (this.properties.objType != "Overlay") return; + + this.objectGroup.children.forEach(function (parent) { + for (var i = 0, l = parent.children.length; i < l; i++) { + var obj = parent.children[i]; + if (obj instanceof THREE.Line) obj.visible = visible; + } + }); + this.borderVisible = visible; +}; + +Q3D.PolygonLayer.prototype.setSideVisible = function (visible) { + if (this.properties.objType != "Overlay") return; + + this.objectGroup.children.forEach(function (parent) { + for (var i = 0, l = parent.children.length; i < l; i++) { + var obj = parent.children[i]; + if (obj instanceof THREE.Mesh) obj.visible = visible; + } + }); + this.sideVisible = visible; +}; + + +/* +Q3D.Model +*/ +Q3D.Model = function () { + this.loaded = false; +}; + +Q3D.Model.prototype = { + + constructor: Q3D.Model, + + // callback is called when model has been completely loaded + load: function (url, callback) { + var _this = this; + Q3D.application.loadModelFile(url, function (model) { + _this.model = model; + _this._loadCompleted(callback); + }); + }, + + loadData: function (data, ext, resourcePath, callback) { + var _this = this; + Q3D.application.loadModelData(data, ext, resourcePath, function (model) { + _this.model = model; + _this._loadCompleted(callback); + }); + }, + + loadJSONObject: function (jsonObject, callback) { + if (jsonObject.url !== undefined) { + this.load(jsonObject.url, callback); + } + else { + var b = atob(jsonObject.base64), + len = b.length, + bytes = new Uint8Array(len); + + for (var i = 0; i < len; i++) { + bytes[i] = b.charCodeAt(i); + } + + this.loadData(bytes.buffer, jsonObject.ext, jsonObject.resourcePath, callback); + } + }, + + _loadCompleted: function (anotherCallback) { + this.loaded = true; + + if (this._callbacks !== undefined) { + for (var i = 0; i < this._callbacks.length; i++) { + this._callbacks[i](this.model); + } + this._callbacks = []; + } + + if (anotherCallback) anotherCallback(this.model); + }, + + callbackOnLoad: function (callback) { + if (this.loaded) return callback(this.model); + + if (this._callbacks === undefined) this._callbacks = []; + this._callbacks.push(callback); + } + +}; + + +/* +Q3D.Models +*/ +Q3D.Models = function () { + this.models = []; + this.cache = {}; +}; + +Q3D.Models.prototype = Object.create(THREE.EventDispatcher.prototype); +Q3D.Models.prototype.constructor = Q3D.Models; + +Q3D.Models.prototype.loadJSONObject = function (jsonObject) { + var _this = this; + var callback = function (model) { + _this.dispatchEvent({type: "modelLoaded", model: model}); + }; + + var model, url; + for (var i = 0, l = jsonObject.length; i < l; i++) { + + url = jsonObject[i].url; + if (url !== undefined && this.cache[url] !== undefined) { + model = this.cache[url]; + } + else { + model = new Q3D.Model(); + model.loadJSONObject(jsonObject[i], callback); + + if (url !== undefined) this.cache[url] = model; + } + this.models.push(model); + } +}; + +Q3D.Models.prototype.get = function (index) { + return this.models[index]; +}; + +Q3D.Models.prototype.clear = function () { + this.models = []; +}; + + +// Q3D.Utils - Utilities +Q3D.Utils = {}; + +// Put a stick to given position (for debug) +Q3D.Utils.putStick = function (x, y, zFunc, h) { + if (Q3D.Utils._stick_mat === undefined) Q3D.Utils._stick_mat = new THREE.LineBasicMaterial({color: 0xff0000}); + if (h === undefined) h = 0.2; + if (zFunc === undefined) { + zFunc = function (x, y) { return Q3D.application.scene.mapLayers[0].getZ(x, y); }; + } + var z = zFunc(x, y); + var geom = new THREE.Geometry(); + geom.vertices.push(new THREE.Vector3(x, y, z + h), new THREE.Vector3(x, y, z)); + var stick = new THREE.Line(geom, Q3D.Utils._stick_mat); + Q3D.application.scene.add(stick); +}; + +// convert latitude and longitude in degrees to the following format +// Ndd°mm′ss.ss″, Eddd°mm′ss.ss″ +Q3D.Utils.convertToDMS = function (lat, lon) { + function toDMS(degrees) { + var deg = Math.floor(degrees), + m = (degrees - deg) * 60, + min = Math.floor(m), + sec = (m - min) * 60; + return deg + "°" + ("0" + min).slice(-2) + "′" + ((sec < 10) ? "0" : "") + sec.toFixed(2) + "″"; + } + + return ((lat < 0) ? "S" : "N") + toDMS(Math.abs(lat)) + ", " + + ((lon < 0) ? "W" : "E") + toDMS(Math.abs(lon)); +}; + +Q3D.Utils.createWallGeometry = function (vert, bzFunc, buffer_geom) { + var geom = new THREE.Geometry(); + for (var i = 0, l = vert.length; i < l; i += 3) { + geom.vertices.push( + new THREE.Vector3(vert[i], vert[i + 1], vert[i + 2]), + new THREE.Vector3(vert[i], vert[i + 1], bzFunc(vert[i], vert[i + 1])) + ); + } + + for (var i = 1, i2 = 1, l = vert.length / 3; i < l; i++, i2 += 2) { + geom.faces.push( + new THREE.Face3(i2 - 1, i2, i2 + 1), + new THREE.Face3(i2 + 1, i2, i2 + 2) + ); + } + + geom.computeFaceNormals(); + + if (buffer_geom) { + return new THREE.BufferGeometry().fromGeometry(geom); + } + return geom; +}; + +Q3D.Utils.arrayToVec2Array = function (points) { + var pt, pts = []; + for (var i = 0, l = points.length; i < l; i++) { + pt = points[i]; + pts.push(new THREE.Vector2(pt[0], pt[1])); + } + return pts; +}; + +Q3D.Utils.flatArrayToVec2Array = function (vertices, itemSize) { + itemSize = itemSize || 2; + var pts = []; + for (var i = 0, l = vertices.length; i < l; i += itemSize) { + pts.push(new THREE.Vector2(vertices[i], vertices[i + 1])); + } + return pts; +}; + +Q3D.Utils.setGeometryUVs = function (geom, base_width, base_height) { + var face, v, uvs = []; + for (var i = 0, l = geom.vertices.length; i < l; i++) { + v = geom.vertices[i]; + uvs.push(new THREE.Vector2(v.x / base_width + 0.5, v.y / base_height + 0.5)); + } + + geom.faceVertexUvs[0] = []; + for (var i = 0, l = geom.faces.length; i < l; i++) { + face = geom.faces[i]; + geom.faceVertexUvs[0].push([uvs[face.a], uvs[face.b], uvs[face.c]]); + } +}; + + +// Q3D.Tweens +Q3D.Tweens = {}; + +Q3D.Tweens.cameraMotion = { + + type: Q3D.KeyframeType.CameraMotion, + + curveFactor: 0, + + init: function (group) { + + var app = Q3D.application, + zScale = app.scene.userData.zScale, + keyframes = group.keyframes, + prop_list = []; + + var c = this.curveFactor, p, p0, phi, theta, dist, dist_list = []; + var vec3 = new THREE.Vector3(), + o = app.scene.userData.origin; + for (var i = 0; i < keyframes.length; i++) { + p = keyframes[i].camera; + vec3.set(p.x - p.fx, p.y - p.fy, (p.z - p.fz) * zScale); + dist = vec3.length(); + theta = Math.acos(vec3.z / dist); + phi = Math.atan2(vec3.y, vec3.x); + p.phi = phi; + prop_list.push({p: i, fx: p.fx - o.x, fy: p.fy - o.y, fz: (p.fz - o.z) * zScale, d: dist, theta: theta}); // map to 3D world + + if (i > 0) { + dist_list.push(Math.sqrt((p.x - p0.x) * (p.x - p0.x) + (p.y - p0.y) * (p.y - p0.y))); + } + p0 = p; + } + group.prop_list = prop_list; + + var phi0, phi1, dz; + group.onUpdate = function (obj, elapsed, is_first) { + + p = obj.p - group.currentIndex; + phi0 = keyframes[group.currentIndex].camera.phi; + phi1 = (is_first) ? phi0 : keyframes[group.currentIndex + 1].camera.phi; + + if (Math.abs(phi1 - phi0) > Math.PI) { // take the shortest orbiting path + phi1 += Math.PI * ((phi1 > phi0) ? -2 : 2); + } + + phi = phi0 * (1 - p) + phi1 * p; + + vec3.set(Math.cos(phi) * Math.sin(obj.theta), + Math.sin(phi) * Math.sin(obj.theta), + Math.cos(obj.theta)).setLength(obj.d); + + dz = (c) ? (1 - Math.pow(2 * p - 1, 2)) * dist_list[group.currentIndex] * c : 0; + + app.camera.position.set(obj.fx + vec3.x, obj.fy + vec3.y, obj.fz + vec3.z + dz); + app.camera.lookAt(obj.fx, obj.fy, obj.fz); + app.controls.target.set(obj.fx, obj.fy, obj.fz); + }; + + // initial position + group.onUpdate(group.prop_list[0], 1, true); + } + +}; + +Q3D.Tweens.opacity = { + + type: Q3D.KeyframeType.Opacity, + + init: function (group, layer) { + + var keyframes = group.keyframes; + + for (var i = 0; i < keyframes.length; i++) { + group.prop_list.push({opacity: keyframes[i].opacity}); + } + + group.onUpdate = function (obj, elapsed) { + layer.opacity = obj.opacity; + }; + + // initial opacity + group.onUpdate(group.prop_list[0]); + } + +}; + +Q3D.Tweens.texture = { + + type: Q3D.KeyframeType.Texture, + + init: function (group, layer) { + + var keyframes = group.keyframes; + + var idx_from, from, to, effect; + + group.onStart = function () { + idx_from = group.currentIndex; + effect = keyframes[idx_from].effect; + from = keyframes[idx_from].mtlIndex; + to = keyframes[idx_from + 1].mtlIndex; + + layer.prepareTexAnimation(from, to); + layer.setTextureAt(null, effect); + }; + + group.onUpdate = function (obj, elapsed) { + layer.setTextureAt(obj.p - group.currentIndex, effect); + }; + + for (var i = 0; i < keyframes.length; i++) { + group.prop_list.push({p: i}); + } + } +}; + +Q3D.Tweens.lineGrowing = { + + type: Q3D.KeyframeType.GrowingLine, + + init: function (group, layer) { + if (group._keyframes === undefined) group._keyframes = group.keyframes; + + var effectItem = group._keyframes[0]; + if (effectItem.sequential) { + group.keyframes = []; + + for (var i = 0; i < layer.features.length; i++) { + group.keyframes.push(layer.features[i].anim); + group.prop_list.push({p: i}); + } + group.keyframes.push({}); + group.prop_list.push({p: i}); + + group.onUpdate = function (obj, elapsed) { + layer.setLineLength(obj.p - group.currentIndex, group.currentIndex); + }; + } + else { + group.keyframes = [effectItem, {}]; + group.prop_list = [{p: 0}, {p: 1}]; + + group.onUpdate = function (obj, elapsed) { + layer.setLineLength(obj.p); + }; + } + + layer.prepareAnimation(effectItem.sequential); + layer.setLineLength(0); + } + +}; + + +// https://stackoverflow.com/a/7838871 +CanvasRenderingContext2D.prototype.roundRect = function (x, y, w, h, r) { + if (w < 2 * r) r = w / 2; + if (h < 2 * r) r = h / 2; + this.beginPath(); + this.moveTo(x + r, y); + this.arcTo(x + w, y, x + w, y + h, r); + this.arcTo(x + w, y + h, x, y + h, r); + this.arcTo(x, y + h, x, y, r); + this.arcTo(x, y, x + w, y, r); + this.closePath(); + return this; +}; diff --git a/docs/examples/27/kibiji/qgis2threejs.png b/docs/examples/27/kibiji/qgis2threejs.png new file mode 100644 index 00000000..1d003067 Binary files /dev/null and b/docs/examples/27/kibiji/qgis2threejs.png differ diff --git a/docs/examples/27/kibiji/threejs/license b/docs/examples/27/kibiji/threejs/license new file mode 100644 index 00000000..9ef721c2 --- /dev/null +++ b/docs/examples/27/kibiji/threejs/license @@ -0,0 +1,21 @@ +The MIT License + +Copyright © 2010-2020 three.js authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/docs/examples/27/kibiji/threejs/orbitcontrols.js b/docs/examples/27/kibiji/threejs/orbitcontrols.js new file mode 100644 index 00000000..df69ebda --- /dev/null +++ b/docs/examples/27/kibiji/threejs/orbitcontrols.js @@ -0,0 +1,1154 @@ +/** + * @author qiao / https://github.com/qiao + * @author mrdoob / http://mrdoob.com + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author erich666 / http://erichaines.com + */ + +// This set of controls performs orbiting, dollying (zooming), and panning. +// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). +// +// Orbit - left mouse / touch: one-finger move +// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish +// Pan - right mouse, or left mouse + ctrl/metaKey, or arrow keys / touch: two-finger move + +THREE.OrbitControls = function ( object, domElement ) { + + this.object = object; + + this.domElement = ( domElement !== undefined ) ? domElement : document; + + // Set to false to disable this control + this.enabled = true; + + // "target" sets the location of focus, where the object orbits around + this.target = new THREE.Vector3(); + + // How far you can dolly in and out ( PerspectiveCamera only ) + this.minDistance = 0; + this.maxDistance = Infinity; + + // How far you can zoom in and out ( OrthographicCamera only ) + this.minZoom = 0; + this.maxZoom = Infinity; + + // How far you can orbit vertically, upper and lower limits. + // Range is 0 to Math.PI radians. + this.minPolarAngle = 0; // radians + this.maxPolarAngle = Math.PI; // radians + + // How far you can orbit horizontally, upper and lower limits. + // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ]. + this.minAzimuthAngle = - Infinity; // radians + this.maxAzimuthAngle = Infinity; // radians + + // Set to true to enable damping (inertia) + // If damping is enabled, you must call controls.update() in your animation loop + this.enableDamping = false; + this.dampingFactor = 0.25; + + // This option actually enables dollying in and out; left as "zoom" for backwards compatibility. + // Set to false to disable zooming + this.enableZoom = true; + this.zoomSpeed = 1.0; + + // Set to false to disable rotating + this.enableRotate = true; + this.rotateSpeed = 0.5; // (1.0) + this.keyRotateAngle = Math.PI / 360; // radians. per one key event. added @minorua + + // Set to false to disable panning + this.enablePan = true; + this.panSpeed = 1.0; + this.screenSpacePanning = false; // if true, pan in screen-space + this.keyPanSpeed = 4.0; // (7.0) pixels moved per arrow key push + + // Set to true to automatically rotate around the target + // If auto-rotate is enabled, you must call controls.update() in your animation loop + this.autoRotate = false; + this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 + + // Set to false to disable use of the keys + this.enableKeys = true; + + // The four arrow keys + this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; + + // Mouse buttons + this.mouseButtons = { LEFT: THREE.MOUSE.LEFT, MIDDLE: THREE.MOUSE.MIDDLE, RIGHT: THREE.MOUSE.RIGHT }; + + // for reset + this.target0 = this.target.clone(); + this.position0 = this.object.position.clone(); + this.zoom0 = this.object.zoom; + + // + // public methods + // + + this.getPolarAngle = function () { + + return spherical.phi; + + }; + + this.getAzimuthalAngle = function () { + + return spherical.theta; + + }; + + this.saveState = function () { + + scope.target0.copy( scope.target ); + scope.position0.copy( scope.object.position ); + scope.zoom0 = scope.object.zoom; + + }; + + this.reset = function () { + + scope.target.copy( scope.target0 ); + scope.object.position.copy( scope.position0 ); + scope.object.zoom = scope.zoom0; + + scope.object.updateProjectionMatrix(); + scope.dispatchEvent( changeEvent ); + + scope.update(); + + state = STATE.NONE; + + }; + + // this method is exposed, but perhaps it would be better if we can make it private... + this.update = function () { + + var offset = new THREE.Vector3(); + + // so camera.up is the orbit axis + var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ); + var quatInverse = quat.clone().inverse(); + + var lastPosition = new THREE.Vector3(); + var lastQuaternion = new THREE.Quaternion(); + + return function update() { + + var position = scope.object.position; + + offset.copy( position ).sub( scope.target ); + + // rotate offset to "y-axis-is-up" space + offset.applyQuaternion( quat ); + + // angle from z-axis around y-axis + spherical.setFromVector3( offset ); + + if ( scope.autoRotate && state === STATE.NONE ) { + + rotateLeft( getAutoRotationAngle() ); + + } + + spherical.theta += sphericalDelta.theta; + spherical.phi += sphericalDelta.phi; + + // restrict theta to be between desired limits + spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) ); + + // restrict phi to be between desired limits + spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) ); + + spherical.makeSafe(); + + + spherical.radius *= scale; + + // restrict radius to be between desired limits + spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); + + // move target to panned location + scope.target.add( panOffset ); + + offset.setFromSpherical( spherical ); + + // rotate offset back to "camera-up-vector-is-up" space + offset.applyQuaternion( quatInverse ); + + position.copy( scope.target ).add( offset ); + + scope.object.lookAt( scope.target ); + + if ( scope.enableDamping === true ) { + + sphericalDelta.theta *= ( 1 - scope.dampingFactor ); + sphericalDelta.phi *= ( 1 - scope.dampingFactor ); + + panOffset.multiplyScalar( 1 - scope.dampingFactor ); + + } else { + + sphericalDelta.set( 0, 0, 0 ); + + panOffset.set( 0, 0, 0 ); + + } + + scale = 1; + + // update condition is: + // min(camera displacement, camera rotation in radians)^2 > EPS + // using small-angle approximation cos(x/2) = 1 - x^2 / 8 + + if ( zoomChanged || + lastPosition.distanceToSquared( scope.object.position ) > EPS || + 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { + + scope.dispatchEvent( changeEvent ); + + lastPosition.copy( scope.object.position ); + lastQuaternion.copy( scope.object.quaternion ); + zoomChanged = false; + + return true; + + } + + return false; + + }; + + }(); + + this.dispose = function () { + + scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false ); + scope.domElement.removeEventListener( 'mousedown', onMouseDown, false ); + scope.domElement.removeEventListener( 'wheel', onMouseWheel, false ); + + scope.domElement.removeEventListener( 'touchstart', onTouchStart, false ); + scope.domElement.removeEventListener( 'touchend', onTouchEnd, false ); + scope.domElement.removeEventListener( 'touchmove', onTouchMove, false ); + + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + + window.removeEventListener( 'keydown', onKeyDown, false ); + + //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? + + }; + + // + // internals + // + + var scope = this; + + var changeEvent = { type: 'change' }; + var startEvent = { type: 'start' }; + var endEvent = { type: 'end' }; + + var STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4 }; + + var state = STATE.NONE; + + var EPS = 0.000001; + + // current position in spherical coordinates + var spherical = new THREE.Spherical(); + var sphericalDelta = new THREE.Spherical(); + + var scale = 1; + var panOffset = new THREE.Vector3(); + var zoomChanged = false; + + var rotateStart = new THREE.Vector2(); + var rotateEnd = new THREE.Vector2(); + var rotateDelta = new THREE.Vector2(); + + var panStart = new THREE.Vector2(); + var panEnd = new THREE.Vector2(); + var panDelta = new THREE.Vector2(); + + var dollyStart = new THREE.Vector2(); + var dollyEnd = new THREE.Vector2(); + var dollyDelta = new THREE.Vector2(); + + function getAutoRotationAngle() { + + return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; + + } + + function getZoomScale() { + + return Math.pow( 0.95, scope.zoomSpeed ); + + } + + function rotateLeft( angle ) { + + sphericalDelta.theta -= angle; + + } + + function rotateUp( angle ) { + + sphericalDelta.phi -= angle; + + } + + var panLeft = function () { + + var v = new THREE.Vector3(); + + return function panLeft( distance, objectMatrix ) { + + v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix + v.multiplyScalar( - distance ); + + panOffset.add( v ); + + }; + + }(); + + var panUp = function () { + + var v = new THREE.Vector3(); + + return function panUp( distance, objectMatrix ) { + + if ( scope.screenSpacePanning === true ) { + + v.setFromMatrixColumn( objectMatrix, 1 ); + + } else { + + v.setFromMatrixColumn( objectMatrix, 0 ); + v.crossVectors( scope.object.up, v ); + + } + + v.multiplyScalar( distance ); + + panOffset.add( v ); + + }; + + }(); + + // deltaX and deltaY are in pixels; right and down are positive + var pan = function () { + + var offset = new THREE.Vector3(); + + return function pan( deltaX, deltaY ) { + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + if ( scope.object.isPerspectiveCamera ) { + + // perspective + var position = scope.object.position; + offset.copy( position ).sub( scope.target ); + var targetDistance = offset.length(); + + // half of the fov is center to top of screen + targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 ); + + // we use only clientHeight here so aspect ratio does not distort speed + panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix ); + panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix ); + + } else if ( scope.object.isOrthographicCamera ) { + + // orthographic + panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix ); + panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix ); + + } else { + + // camera neither orthographic nor perspective + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); + scope.enablePan = false; + + } + + }; + + }(); + + function dollyIn( dollyScale ) { + + if ( scope.object.isPerspectiveCamera ) { + + scale /= dollyScale; + + } else if ( scope.object.isOrthographicCamera ) { + + scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) ); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + scope.enableZoom = false; + + } + + } + + function dollyOut( dollyScale ) { + + if ( scope.object.isPerspectiveCamera ) { + + scale *= dollyScale; + + } else if ( scope.object.isOrthographicCamera ) { + + scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) ); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + scope.enableZoom = false; + + } + + } + + // @minorua + var cameraRotate = function () { + + var offset = new THREE.Vector3(), + spherical = new THREE.Spherical(), + quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ), + quatInverse = quat.clone().inverse(); + + return function ( thetaDelta, phiDelta ) { + + offset.copy( scope.target ).sub( object.position ); + offset.applyQuaternion( quat ); + + spherical.setFromVector3( offset ); + + spherical.theta += thetaDelta; + spherical.phi -= phiDelta; + + // restrict theta/phi to be between desired limits + spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) ); + spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) ); + spherical.makeSafe(); + + offset.setFromSpherical( spherical ); + offset.applyQuaternion( quatInverse ); + + scope.target.copy( object.position ).add( offset ); + object.lookAt( scope.target ); + + }; + + }(); + + // + // event callbacks - update the object state + // + + function handleMouseDownRotate( event ) { + + rotateStart.set( event.clientX, event.clientY ); + + } + + function handleMouseDownDolly( event ) { + + dollyStart.set( event.clientX, event.clientY ); + + } + + function handleMouseDownPan( event ) { + + panStart.set( event.clientX, event.clientY ); + + } + + function handleMouseMoveRotate( event ) { + + rotateEnd.set( event.clientX, event.clientY ); + + rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height + + rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); + + rotateStart.copy( rotateEnd ); + + scope.update(); + + } + + function handleMouseMoveDolly( event ) { + + dollyEnd.set( event.clientX, event.clientY ); + + dollyDelta.subVectors( dollyEnd, dollyStart ); + + if ( dollyDelta.y > 0 ) { + + dollyIn( getZoomScale() ); + + } else if ( dollyDelta.y < 0 ) { + + dollyOut( getZoomScale() ); + + } + + dollyStart.copy( dollyEnd ); + + scope.update(); + + } + + function handleMouseMovePan( event ) { + + panEnd.set( event.clientX, event.clientY ); + + panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); + + pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + scope.update(); + + } + + function handleMouseUp( event ) { + + } + + function handleMouseWheel( event ) { + + var delta = 0; + + if ( event.deltaY !== undefined ) { + + delta = event.deltaY; + + } else if ( event.wheelDelta !== undefined ) { // WebKit @minorua + + delta = - event.wheelDelta; + + } + + if ( delta < 0 ) { + + dollyOut( getZoomScale() ); + + } else if ( delta > 0 ) { + + dollyIn( getZoomScale() ); + + } + + scope.update(); + + } + + function handleKeyDown( event ) { + + if ( event.shiftKey && event.ctrlKey ) { // @minorua + + switch ( event.keyCode ) { + case scope.keys.UP: + dollyOut( getZoomScale() ); + break; + + case scope.keys.BOTTOM: + dollyIn( getZoomScale() ); + break; + + default: + return; + } + + scope.update(); + return; + + } + + if ( event.shiftKey ) { + + switch ( event.keyCode ) { + + case scope.keys.UP: + rotateUp( scope.keyRotateAngle ); + break; + + case scope.keys.BOTTOM: + rotateUp( - scope.keyRotateAngle ); + break; + + case scope.keys.LEFT: + rotateLeft( scope.keyRotateAngle ); + break; + + + case scope.keys.RIGHT: + rotateLeft( - scope.keyRotateAngle ); + break; + + default: + return; + + } + + scope.update(); + return; + + } + + if ( event.ctrlKey ) { + + switch ( event.keyCode ) { + + case scope.keys.UP: + cameraRotate( 0, scope.keyRotateAngle ); + break; + + case scope.keys.BOTTOM: + cameraRotate( 0, - scope.keyRotateAngle ); + break; + + case scope.keys.LEFT: + cameraRotate( scope.keyRotateAngle, 0 ); + break; + + case scope.keys.RIGHT: + cameraRotate( - scope.keyRotateAngle, 0 ); + break; + + default: + return; + + } + + scope.update(); + return; + + } + + switch ( event.keyCode ) { + + case scope.keys.UP: + pan( 0, scope.keyPanSpeed ); // horizontally forward + break; + + case scope.keys.BOTTOM: + pan( 0, - scope.keyPanSpeed ); + break; + + case scope.keys.LEFT: + pan( scope.keyPanSpeed, 0 ); // horizontally left + break; + + case scope.keys.RIGHT: + pan( - scope.keyPanSpeed, 0 ); + break; + + default: + return; + + } + + scope.update(); + + } + + function handleTouchStartRotate( event ) { + + rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + } + + function handleTouchStartDollyPan( event ) { + + if ( scope.enableZoom ) { + + var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; + var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; + + var distance = Math.sqrt( dx * dx + dy * dy ); + + dollyStart.set( 0, distance ); + + } + + if ( scope.enablePan ) { + + var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); + var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); + + panStart.set( x, y ); + + } + + } + + function handleTouchMoveRotate( event ) { + + rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height + + rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); + + rotateStart.copy( rotateEnd ); + + scope.update(); + + } + + function handleTouchMoveDollyPan( event ) { + + if ( scope.enableZoom ) { + + var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; + var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; + + var distance = Math.sqrt( dx * dx + dy * dy ); + + dollyEnd.set( 0, distance ); + + dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) ); + + dollyIn( dollyDelta.y ); + + dollyStart.copy( dollyEnd ); + + } + + if ( scope.enablePan ) { + + var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); + var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); + + panEnd.set( x, y ); + + panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); + + pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + } + + scope.update(); + + } + + function handleTouchEnd( event ) { + + } + + // + // event handlers - FSM: listen for events and reset state + // + + function onMouseDown( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + switch ( event.button ) { + + case scope.mouseButtons.LEFT: + + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { // + + if ( scope.enablePan === false ) return; + + scope.screenSpacePanning = event.shiftKey; // added @minorua + + handleMouseDownPan( event ); + + state = STATE.PAN; + + } else { + + if ( scope.enableRotate === false ) return; + + handleMouseDownRotate( event ); + + state = STATE.ROTATE; + + } + + break; + + case scope.mouseButtons.MIDDLE: + + if ( scope.enableZoom === false ) return; + + handleMouseDownDolly( event ); + + state = STATE.DOLLY; + + break; + + case scope.mouseButtons.RIGHT: + + if ( scope.enablePan === false ) return; + + scope.screenSpacePanning = event.shiftKey; // + + handleMouseDownPan( event ); + + state = STATE.PAN; + + break; + + } + + if ( state !== STATE.NONE ) { + + document.addEventListener( 'mousemove', onMouseMove, false ); + document.addEventListener( 'mouseup', onMouseUp, false ); + + scope.dispatchEvent( startEvent ); + + } + + } + + function onMouseMove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + switch ( state ) { + + case STATE.ROTATE: + + if ( scope.enableRotate === false ) return; + + handleMouseMoveRotate( event ); + + break; + + case STATE.DOLLY: + + if ( scope.enableZoom === false ) return; + + handleMouseMoveDolly( event ); + + break; + + case STATE.PAN: + + if ( scope.enablePan === false ) return; + + handleMouseMovePan( event ); + + break; + + } + + } + + function onMouseUp( event ) { + + if ( scope.enabled === false ) return; + + handleMouseUp( event ); + + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + + scope.dispatchEvent( endEvent ); + + state = STATE.NONE; + + } + + function onMouseWheel( event ) { + + if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return; + + event.preventDefault(); + event.stopPropagation(); + + scope.dispatchEvent( startEvent ); + + handleMouseWheel( event ); + + scope.dispatchEvent( endEvent ); + + } + + function onKeyDown( event ) { + + if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return; + + handleKeyDown( event ); + + } + + function onTouchStart( event ) { + + if ( scope.enabled === false ) return; + + // event.preventDefault(); // comment out @minorua + + switch ( event.touches.length ) { + + case 1: // one-fingered touch: rotate + + if ( scope.enableRotate === false ) return; + + handleTouchStartRotate( event ); + + state = STATE.TOUCH_ROTATE; + + break; + + case 2: // two-fingered touch: dolly-pan + + if ( scope.enableZoom === false && scope.enablePan === false ) return; + + handleTouchStartDollyPan( event ); + + state = STATE.TOUCH_DOLLY_PAN; + + break; + + default: + + state = STATE.NONE; + + } + + if ( state !== STATE.NONE ) { + + scope.dispatchEvent( startEvent ); + + } + + } + + function onTouchMove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + event.stopPropagation(); + + switch ( event.touches.length ) { + + case 1: // one-fingered touch: rotate + + if ( scope.enableRotate === false ) return; + if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed? + + handleTouchMoveRotate( event ); + + break; + + case 2: // two-fingered touch: dolly-pan + + if ( scope.enableZoom === false && scope.enablePan === false ) return; + if ( state !== STATE.TOUCH_DOLLY_PAN ) return; // is this needed? + + handleTouchMoveDollyPan( event ); + + break; + + default: + + state = STATE.NONE; + + } + + } + + function onTouchEnd( event ) { + + if ( scope.enabled === false ) return; + + handleTouchEnd( event ); + + scope.dispatchEvent( endEvent ); + + state = STATE.NONE; + + } + + function onContextMenu( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + } + + scope.domElement.addEventListener( 'contextmenu', onContextMenu, false ); + + scope.domElement.addEventListener( 'mousedown', onMouseDown, false ); + scope.domElement.addEventListener( 'wheel', onMouseWheel, false ); + scope.domElement.addEventListener( 'mousewheel', onMouseWheel, false ); // WebKit @minorua + + scope.domElement.addEventListener( 'touchstart', onTouchStart, false ); + scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); + scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); + + window.addEventListener( 'keydown', onKeyDown, false ); + + // force an update at start + + this.update(); + +}; + +THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); +THREE.OrbitControls.prototype.constructor = THREE.OrbitControls; + +Object.defineProperties( THREE.OrbitControls.prototype, { + + center: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .center has been renamed to .target' ); + return this.target; + + } + + }, + + // backward compatibility + + noZoom: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); + return ! this.enableZoom; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); + this.enableZoom = ! value; + + } + + }, + + noRotate: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); + return ! this.enableRotate; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); + this.enableRotate = ! value; + + } + + }, + + noPan: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); + return ! this.enablePan; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); + this.enablePan = ! value; + + } + + }, + + noKeys: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); + return ! this.enableKeys; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); + this.enableKeys = ! value; + + } + + }, + + staticMoving: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); + return ! this.enableDamping; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); + this.enableDamping = ! value; + + } + + }, + + dynamicDampingFactor: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); + return this.dampingFactor; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); + this.dampingFactor = value; + + } + + } + +} ); diff --git a/docs/examples/27/kibiji/threejs/three.min.js b/docs/examples/27/kibiji/threejs/three.min.js new file mode 100644 index 00000000..25b51b84 --- /dev/null +++ b/docs/examples/27/kibiji/threejs/three.min.js @@ -0,0 +1,1019 @@ +// threejs.org/license +(function(k,Aa){"object"===typeof exports&&"undefined"!==typeof module?Aa(exports):"function"===typeof define&&define.amd?define(["exports"],Aa):(k=k||self,Aa(k.THREE={}))})(this,function(k){function Aa(){}function B(a,b){this.x=a||0;this.y=b||0}function wa(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._w=void 0!==d?d:1}function n(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}function Z(){this.elements=[1,0,0,0,1,0,0,0,1];0h)return!1}return!0}function mb(a,b){this.center=void 0!==a?a:new n;this.radius=void 0!==b?b:0}function Rb(a,b){this.origin=void 0!==a?a:new n;this.direction=void 0!==b?b:new n}function Oa(a,b){this.normal=void 0!==a?a:new n(1,0,0);this.constant=void 0!==b?b:0}function ba(a,b,c){this.a=void 0!==a?a:new n;this.b=void 0!== +b?b:new n;this.c=void 0!==c?c:new n}function J(a,b,c){return void 0===b&&void 0===c?this.set(a):this.setRGB(a,b,c)}function Vf(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a}function Wf(a){return.04045>a?.0773993808*a:Math.pow(.9478672986*a+.0521327014,2.4)}function Xf(a){return.0031308>a?12.92*a:1.055*Math.pow(a,.41666)-.055}function xc(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d&&d.isVector3?d:new n;this.vertexNormals=Array.isArray(d)?d:[];this.color= +e&&e.isColor?e:new J;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex=void 0!==f?f:0}function O(){Object.defineProperty(this,"id",{value:Ui++});this.uuid=P.generateUUID();this.name="";this.type="Material";this.fog=!0;this.blending=1;this.side=0;this.vertexTangents=this.flatShading=!1;this.vertexColors=0;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=3;this.depthWrite= +this.depthTest=!0;this.stencilWriteMask=255;this.stencilFunc=519;this.stencilRef=0;this.stencilFuncMask=255;this.stencilZPass=this.stencilZFail=this.stencilFail=7680;this.stencilWrite=!1;this.clippingPlanes=null;this.clipShadows=this.clipIntersection=!1;this.shadowSide=null;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1;this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.dithering=!1;this.alphaTest=0;this.premultipliedAlpha=!1;this.toneMapped=this.visible=!0;this.userData={};this.needsUpdate= +!0}function Ga(a){O.call(this);this.type="MeshBasicMaterial";this.color=new J(16777215);this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.morphTargets=this.skinning=!1;this.setValues(a)}function N(a,b,c){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array."); +this.name="";this.array=a;this.itemSize=b;this.count=void 0!==a?a.length/b:0;this.normalized=!0===c;this.usage=35044;this.updateRange={offset:0,count:-1};this.version=0}function wd(a,b,c){N.call(this,new Int8Array(a),b,c)}function xd(a,b,c){N.call(this,new Uint8Array(a),b,c)}function yd(a,b,c){N.call(this,new Uint8ClampedArray(a),b,c)}function zd(a,b,c){N.call(this,new Int16Array(a),b,c)}function Sb(a,b,c){N.call(this,new Uint16Array(a),b,c)}function Ad(a,b,c){N.call(this,new Int32Array(a),b,c)}function Tb(a, +b,c){N.call(this,new Uint32Array(a),b,c)}function A(a,b,c){N.call(this,new Float32Array(a),b,c)}function Bd(a,b,c){N.call(this,new Float64Array(a),b,c)}function ih(){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}function jh(a){if(0===a.length)return-Infinity; +for(var b=a[0],c=1,d=a.length;cb&&(b=a[c]);return b}function D(){Object.defineProperty(this,"id",{value:Vi+=2});this.uuid=P.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};this.userData={}}function ea(a,b){E.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new D;this.material=void 0!==b?b:new Ga({color:16777215*Math.random()}); +this.drawMode=0;this.updateMorphTargets()}function kh(a,b,c,d,e,f,g,h){if(null===(1===b.side?d.intersectTriangle(g,f,e,!0,h):d.intersectTriangle(e,f,g,2!==b.side,h)))return null;Ee.copy(h);Ee.applyMatrix4(a.matrixWorld);b=c.ray.origin.distanceTo(Ee);return bc.far?null:{distance:b,point:Ee.clone(),object:a}}function Fe(a,b,c,d,e,f,g,h,l,m,r){Ub.fromBufferAttribute(e,l);Vb.fromBufferAttribute(e,m);Wb.fromBufferAttribute(e,r);e=a.morphTargetInfluences;if(b.morphTargets&&f&&e){Yf.set(0,0,0); +Zf.set(0,0,0);$f.set(0,0,0);for(var q=0,u=f.length;qg;g++)a.setRenderTarget(f,g),a.clear(b,c,d);a.setRenderTarget(e)}}function Bb(a,b,c){Ba.call(this,a,b,c)}function Yb(a,b,c,d,e,f,g,h,l,m,r,q){Y.call(this,null,f,g,h,l,m,d,e,r,q);this.image={data:a||null, +width:b||1,height:c||1};this.magFilter=void 0!==l?l:1003;this.minFilter=void 0!==m?m:1003;this.flipY=this.generateMipmaps=!1;this.unpackAlignment=1;this.needsUpdate=!0}function Dd(a,b,c,d,e,f){this.planes=[void 0!==a?a:new Oa,void 0!==b?b:new Oa,void 0!==c?c:new Oa,void 0!==d?d:new Oa,void 0!==e?e:new Oa,void 0!==f?f:new Oa]}function ag(){function a(e,f){!1!==c&&(d(e,f),b.requestAnimationFrame(a))}var b=null,c=!1,d=null;return{start:function(){!0!==c&&null!==d&&(b.requestAnimationFrame(a),c=!0)}, +stop:function(){c=!1},setAnimationLoop:function(a){d=a},setContext:function(a){b=a}}}function Xi(a){function b(b,c){var d=b.array,e=b.usage,h=a.createBuffer();a.bindBuffer(c,h);a.bufferData(c,d,e);b.onUploadCallback();c=5126;d instanceof Float32Array?c=5126:d instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):d instanceof Uint16Array?c=5123:d instanceof Int16Array?c=5122:d instanceof Uint32Array?c=5125:d instanceof Int32Array?c=5124:d instanceof +Int8Array?c=5120:d instanceof Uint8Array&&(c=5121);return{buffer:h,type:c,bytesPerElement:d.BYTES_PER_ELEMENT,version:b.version}}var c=new WeakMap;return{get:function(a){a.isInterleavedBufferAttribute&&(a=a.data);return c.get(a)},remove:function(b){b.isInterleavedBufferAttribute&&(b=b.data);var d=c.get(b);d&&(a.deleteBuffer(d.buffer),c.delete(b))},update:function(d,e){d.isInterleavedBufferAttribute&&(d=d.data);var f=c.get(d);if(void 0===f)c.set(d,b(d,e));else if(f.versionm;m++){if(q=d[m])if(h=q[0],l=q[1]){r&&e.setAttribute("morphTarget"+ +m,r[h]);f&&e.setAttribute("morphNormal"+m,f[h]);c[m]=l;continue}c[m]=0}g.getUniforms().setValue(a,"morphTargetInfluences",c)}}}function hj(a,b,c,d){var e={};return{update:function(a){var f=d.render.frame,h=a.geometry,l=b.get(a,h);e[l.id]!==f&&(h.isGeometry&&l.updateFromObject(a),b.update(l),e[l.id]=f);a.isInstancedMesh&&c.update(a.instanceMatrix,34962);return l},dispose:function(){e={}}}}function nb(a,b,c,d,e,f,g,h,l,m){a=void 0!==a?a:[];Y.call(this,a,void 0!==b?b:301,c,d,e,f,void 0!==g?g:1022,h, +l,m);this.flipY=!1}function Cc(a,b,c,d){Y.call(this,null);this.image={data:a||null,width:b||1,height:c||1,depth:d||1};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1;this.needsUpdate=!0}function Dc(a,b,c,d){Y.call(this,null);this.image={data:a||null,width:b||1,height:c||1,depth:d||1};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1;this.needsUpdate=!0}function Ec(a,b,c){var d=a[0];if(0>=d||0");return a.replace(dg,cg)}function Dh(a,b,c,d){a="";for(b=parseInt(b);bc;c++)b.probe.push(new n);var d=new n,e=new Q,f=new Q;return{setup:function(c,h,l){for(var g=0,r=0,q=0,k=0;9>k;k++)b.probe[k].set(0,0,0);var p=h=0,t=0,v=0,n=0,w=0,x= +0,F=0;l=l.matrixWorldInverse;c.sort(fk);k=0;for(var I=c.length;kla;la++)b.probe[la].addScaledVector(z.sh.coefficients[la],ia);else if(z.isDirectionalLight){var H=a.get(z);H.color.copy(z.color).multiplyScalar(z.intensity);H.direction.setFromMatrixPosition(z.matrixWorld);d.setFromMatrixPosition(z.target.matrixWorld); +H.direction.sub(d);H.direction.transformDirection(l);if(H.shadow=z.castShadow)ia=z.shadow,H.shadowBias=ia.bias,H.shadowRadius=ia.radius,H.shadowMapSize=ia.mapSize,b.directionalShadowMap[h]=la,b.directionalShadowMatrix[h]=z.shadow.matrix,w++;b.directional[h]=H;h++}else if(z.isSpotLight){H=a.get(z);H.position.setFromMatrixPosition(z.matrixWorld);H.position.applyMatrix4(l);H.color.copy(Ca).multiplyScalar(ia);H.distance=B;H.direction.setFromMatrixPosition(z.matrixWorld);d.setFromMatrixPosition(z.target.matrixWorld); +H.direction.sub(d);H.direction.transformDirection(l);H.coneCos=Math.cos(z.angle);H.penumbraCos=Math.cos(z.angle*(1-z.penumbra));H.decay=z.decay;if(H.shadow=z.castShadow)ia=z.shadow,H.shadowBias=ia.bias,H.shadowRadius=ia.radius,H.shadowMapSize=ia.mapSize,b.spotShadowMap[t]=la,b.spotShadowMatrix[t]=z.shadow.matrix,F++;b.spot[t]=H;t++}else if(z.isRectAreaLight)H=a.get(z),H.color.copy(Ca).multiplyScalar(ia),H.position.setFromMatrixPosition(z.matrixWorld),H.position.applyMatrix4(l),f.identity(),e.copy(z.matrixWorld), +e.premultiply(l),f.extractRotation(e),H.halfWidth.set(.5*z.width,0,0),H.halfHeight.set(0,.5*z.height,0),H.halfWidth.applyMatrix4(f),H.halfHeight.applyMatrix4(f),b.rectArea[v]=H,v++;else if(z.isPointLight){H=a.get(z);H.position.setFromMatrixPosition(z.matrixWorld);H.position.applyMatrix4(l);H.color.copy(z.color).multiplyScalar(z.intensity);H.distance=z.distance;H.decay=z.decay;if(H.shadow=z.castShadow)ia=z.shadow,H.shadowBias=ia.bias,H.shadowRadius=ia.radius,H.shadowMapSize=ia.mapSize,H.shadowCameraNear= +ia.camera.near,H.shadowCameraFar=ia.camera.far,b.pointShadowMap[p]=la,b.pointShadowMatrix[p]=z.shadow.matrix,x++;b.point[p]=H;p++}else z.isHemisphereLight&&(H=a.get(z),H.direction.setFromMatrixPosition(z.matrixWorld),H.direction.transformDirection(l),H.direction.normalize(),H.skyColor.copy(z.color).multiplyScalar(ia),H.groundColor.copy(z.groundColor).multiplyScalar(ia),b.hemi[n]=H,n++)}b.ambient[0]=g;b.ambient[1]=r;b.ambient[2]=q;c=b.hash;if(c.directionalLength!==h||c.pointLength!==p||c.spotLength!== +t||c.rectAreaLength!==v||c.hemiLength!==n||c.numDirectionalShadows!==w||c.numPointShadows!==x||c.numSpotShadows!==F)b.directional.length=h,b.spot.length=t,b.rectArea.length=v,b.point.length=p,b.hemi.length=n,b.directionalShadowMap.length=w,b.pointShadowMap.length=x,b.spotShadowMap.length=F,b.directionalShadowMatrix.length=w,b.pointShadowMatrix.length=x,b.spotShadowMatrix.length=F,c.directionalLength=h,c.pointLength=p,c.spotLength=t,c.rectAreaLength=v,c.hemiLength=n,c.numDirectionalShadows=w,c.numPointShadows= +x,c.numSpotShadows=F,b.version=hk++},state:b}}function Hh(){var a=new gk,b=[],c=[];return{init:function(){b.length=0;c.length=0},state:{lightsArray:b,shadowsArray:c,lights:a},setupLights:function(d){a.setup(b,c,d)},pushLight:function(a){b.push(a)},pushShadow:function(a){c.push(a)}}}function ik(){function a(c){c=c.target;c.removeEventListener("dispose",a);b.delete(c)}var b=new WeakMap;return{get:function(c,d){if(!1===b.has(c)){var e=new Hh;b.set(c,new WeakMap);b.get(c).set(d,e);c.addEventListener("dispose", +a)}else!1===b.get(c).has(d)?(e=new Hh,b.get(c).set(d,e)):e=b.get(c).get(d);return e},dispose:function(){b=new WeakMap}}}function Db(a){O.call(this);this.type="MeshDepthMaterial";this.depthPacking=3200;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.fog=!1;this.setValues(a)}function Eb(a){O.call(this);this.type="MeshDistanceMaterial";this.referencePosition=new n;this.nearDistance= +1;this.farDistance=1E3;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.fog=!1;this.setValues(a)}function Ih(a,b,c){function d(a,b,c){c=a<<0|b<<1|c<<2;var d=q[c];void 0===d&&(d=new Db({depthPacking:3201,morphTargets:a,skinning:b}),q[c]=d);return d}function e(a,b,c){c=a<<0|b<<1|c<<2;var d=k[c];void 0===d&&(d=new Eb({morphTargets:a,skinning:b}),k[c]=d);return d}function f(b,c,f,g,h,l){var m=b.geometry,r=d,q=b.customDepthMaterial; +!0===f.isPointLight&&(r=e,q=b.customDistanceMaterial);void 0===q?(q=!1,!0===c.morphTargets&&(!0===m.isBufferGeometry?q=m.morphAttributes&&m.morphAttributes.position&&0\nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\n \n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n for ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n #ifdef HORIZONAL_PASS\n vec2 distribution = decodeHalfRGBA ( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n mean += distribution.x;\n squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n #else\n float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean * HALF_SAMPLE_RATE;\n squared_mean = squared_mean * HALF_SAMPLE_RATE;\n float std_dev = pow( squared_mean - mean * mean, 0.5 );\n gl_FragColor = encodeHalfRGBA( vec2( mean, std_dev ) );\n}"}), +n=v.clone();n.defines.HORIZONAL_PASS=1;var w=new D;w.setAttribute("position",new N(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));var x=new ea(w,v),F=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=1;this.render=function(d,e,f){if(!1!==F.enabled&&(!1!==F.autoUpdate||!1!==F.needsUpdate)&&0!==d.length){var q=a.getRenderTarget(),k=a.getActiveCubeFace(),u=a.getActiveMipmapLevel(),t=a.state;t.setBlending(0);t.buffers.color.setClear(1,1,1,1);t.buffers.depth.setTest(!0);t.setScissorTest(!1); +for(var p=0,y=d.length;pc||l.y>c)console.warn("THREE.WebGLShadowMap:",w,"has shadow exceeding max texture size, reducing"),l.x>c&&(m.x=Math.floor(c/I.x),l.x=m.x*I.x,z.mapSize.x=m.x),l.y>c&&(m.y=Math.floor(c/I.y),l.y=m.y*I.y,z.mapSize.y=m.y);null!==z.map||z.isPointLightShadow||3!==this.type||(I={minFilter:1006,magFilter:1006, +format:1023},z.map=new Ba(l.x,l.y,I),z.map.texture.name=w.name+".shadowMap",z.mapPass=new Ba(l.x,l.y,I),z.camera.updateProjectionMatrix());null===z.map&&(I={minFilter:1003,magFilter:1003,format:1023},z.map=new Ba(l.x,l.y,I),z.map.texture.name=w.name+".shadowMap",z.camera.updateProjectionMatrix());a.setRenderTarget(z.map);a.clear();I=z.getViewportCount();for(var Ca=0;Cad||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof HTMLImageElement||"undefined"!==typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?P.floorPowerOfTwo:Math.floor,b=d(e*a.width),e=d(e*a.height),void 0===L&&(L=h(b,e)),c=c?h(b,e):L,c.width=b,c.height=e, +c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+b+"x"+e+")."),c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+").")}return a}function m(a){return P.isPowerOfTwo(a.width)&&P.isPowerOfTwo(a.height)}function r(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==a.minFilter}function q(b,c,e,f){a.generateMipmap(b);d.get(c).__maxMipLevel=Math.log(Math.max(e, +f))*Math.LOG2E}function k(a,c){if(!1===la)return a;var d=a;6403===a&&(5126===c&&(d=33326),5131===c&&(d=33325),5121===c&&(d=33321));6407===a&&(5126===c&&(d=34837),5131===c&&(d=34843),5121===c&&(d=32849));6408===a&&(5126===c&&(d=34836),5131===c&&(d=34842),5121===c&&(d=32856));33325===d||33326===d||34842===d||34836===d?b.get("EXT_color_buffer_float"):(34843===d||34837===d)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead.");return d}function p(a){return 1003=== +a||1004===a||1005===a?9728:9729}function t(b){b=b.target;b.removeEventListener("dispose",t);var c=d.get(b);void 0!==c.__webglInit&&(a.deleteTexture(c.__webglTexture),d.remove(b));b.isVideoTexture&&J.delete(b);g.memory.textures--}function v(b){b=b.target;b.removeEventListener("dispose",v);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e=0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]), +c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);if(b.isWebGLMultiviewRenderTarget){a.deleteTexture(c.__webglColorTexture);a.deleteTexture(c.__webglDepthStencilTexture);g.memory.textures-=2;e=0;for(var f=c.__webglViewFramebuffers.length;eu;u++)t[u]=h||e?e?b.image[u].image:b.image[u]:l(b.image[u],!1,!0,Hd);var p=t[0],v=m(p)||la,n=f.convert(b.format),y=f.convert(b.type),w=k(n,y);F(34067,b,v);if(h){for(u=0;6>u;u++){var z=t[u].mipmaps;for(h=0;hu;u++)if(e)for(c.texImage2D(34069+u,0,w,t[u].width,t[u].height,0,n,y,t[u].data),h=0;h=H&&console.warn("THREE.WebGLTextures: Trying to use "+a+" texture units while this GPU supports only "+ +H);G+=1;return a};this.resetTextureUnits=function(){G=0};this.setTexture2D=n;this.setTexture2DArray=function(a,b){var e=d.get(a);0w;w++)h.__webglFramebuffer[w]=a.createFramebuffer()}else if(h.__webglFramebuffer=a.createFramebuffer(),t)if(la){h.__webglMultisampledFramebuffer=a.createFramebuffer();h.__webglColorRenderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161, +h.__webglColorRenderbuffer);t=f.convert(e.texture.format);var z=f.convert(e.texture.type);t=k(t,z);z=A(e);a.renderbufferStorageMultisample(36161,z,t,e.width,e.height);a.bindFramebuffer(36160,h.__webglMultisampledFramebuffer);a.framebufferRenderbuffer(36160,36064,36161,h.__webglColorRenderbuffer);a.bindRenderbuffer(36161,null);e.depthBuffer&&(h.__webglDepthRenderbuffer=a.createRenderbuffer(),ia(h.__webglDepthRenderbuffer,e,!0));a.bindFramebuffer(36160,null)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2."); +else if(p){w=e.width;var x=e.height;t=e.numViews;a.bindFramebuffer(36160,h.__webglFramebuffer);var I=b.get("OVR_multiview2");g.memory.textures+=2;z=a.createTexture();a.bindTexture(35866,z);a.texParameteri(35866,10240,9728);a.texParameteri(35866,10241,9728);a.texImage3D(35866,0,32856,w,x,t,0,6408,5121,null);I.framebufferTextureMultiviewOVR(36160,36064,z,0,0,t);var H=a.createTexture();a.bindTexture(35866,H);a.texParameteri(35866,10240,9728);a.texParameteri(35866,10241,9728);a.texImage3D(35866,0,35056, +w,x,t,0,34041,34042,null);I.framebufferTextureMultiviewOVR(36160,33306,H,0,0,t);x=Array(t);for(w=0;ww;w++)B(h.__webglFramebuffer[w],e,36064,34069+w);r(e.texture,y)&&q(34067,e.texture, +e.width,e.height);c.bindTexture(34067,null)}else p||(c.bindTexture(3553,l.__webglTexture),F(3553,e.texture,y),B(h.__webglFramebuffer,e,36064,3553),r(e.texture,y)&&q(3553,e.texture,e.width,e.height),c.bindTexture(3553,null));if(e.depthBuffer){h=d.get(e);l=!0===e.isWebGLRenderTargetCube;if(e.depthTexture){if(l)throw Error("target.depthTexture not supported in Cube render targets");if(e&&e.isWebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported");a.bindFramebuffer(36160, +h.__webglFramebuffer);if(!e.depthTexture||!e.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(e.depthTexture).__webglTexture&&e.depthTexture.image.width===e.width&&e.depthTexture.image.height===e.height||(e.depthTexture.image.width=e.width,e.depthTexture.image.height=e.height,e.depthTexture.needsUpdate=!0);n(e.depthTexture,0);h=d.get(e.depthTexture).__webglTexture;if(1026===e.depthTexture.format)a.framebufferTexture2D(36160,36096, +3553,h,0);else if(1027===e.depthTexture.format)a.framebufferTexture2D(36160,33306,3553,h,0);else throw Error("Unknown depthTexture format");}else if(l)for(h.__webglDepthbuffer=[],l=0;6>l;l++)a.bindFramebuffer(36160,h.__webglFramebuffer[l]),h.__webglDepthbuffer[l]=a.createRenderbuffer(),ia(h.__webglDepthbuffer[l],e);else a.bindFramebuffer(36160,h.__webglFramebuffer),h.__webglDepthbuffer=a.createRenderbuffer(),ia(h.__webglDepthbuffer,e);a.bindFramebuffer(36160,null)}};this.updateRenderTargetMipmap= +function(a){var b=a.texture,e=m(a)||la;if(r(b,e)){e=a.isWebGLRenderTargetCube?34067:3553;var f=d.get(b).__webglTexture;c.bindTexture(e,f);q(e,b,a.width,a.height);c.bindTexture(e,null)}};this.updateMultisampleRenderTarget=function(b){if(b.isWebGLMultisampleRenderTarget)if(la){var c=d.get(b);a.bindFramebuffer(36008,c.__webglMultisampledFramebuffer);a.bindFramebuffer(36009,c.__webglFramebuffer);c=b.width;var e=b.height,f=16384;b.depthBuffer&&(f|=256);b.stencilBuffer&&(f|=1024);a.blitFramebuffer(0,0, +c,e,0,0,c,e,f,9728)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.")};this.safeSetTexture2D=function(a,b){a&&a.isWebGLRenderTarget&&(!1===Q&&(console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."),Q=!0),a=a.texture);n(a,b)};this.safeSetTextureCube=function(a,b){a&&a.isWebGLRenderTargetCube&&(!1===S&&(console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."), +S=!0),a=a.texture);a&&a.isCubeTexture||Array.isArray(a.image)&&6===a.image.length?w(a,b):x(a,b)}}function Kh(a,b,c){var d=c.isWebGL2;return{convert:function(a){if(1009===a)return 5121;if(1017===a)return 32819;if(1018===a)return 32820;if(1019===a)return 33635;if(1010===a)return 5120;if(1011===a)return 5122;if(1012===a)return 5123;if(1013===a)return 5124;if(1014===a)return 5125;if(1015===a)return 5126;if(1016===a){if(d)return 5131;var c=b.get("OES_texture_half_float");return null!==c?c.HALF_FLOAT_OES: +null}if(1021===a)return 6406;if(1022===a)return 6407;if(1023===a)return 6408;if(1024===a)return 6409;if(1025===a)return 6410;if(1026===a)return 6402;if(1027===a)return 34041;if(1028===a)return 6403;if(33776===a||33777===a||33778===a||33779===a)if(c=b.get("WEBGL_compressed_texture_s3tc"),null!==c){if(33776===a)return c.COMPRESSED_RGB_S3TC_DXT1_EXT;if(33777===a)return c.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(33778===a)return c.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(33779===a)return c.COMPRESSED_RGBA_S3TC_DXT5_EXT}else return null; +if(35840===a||35841===a||35842===a||35843===a)if(c=b.get("WEBGL_compressed_texture_pvrtc"),null!==c){if(35840===a)return c.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(35841===a)return c.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(35842===a)return c.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(35843===a)return c.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}else return null;if(36196===a)return c=b.get("WEBGL_compressed_texture_etc1"),null!==c?c.COMPRESSED_RGB_ETC1_WEBGL:null;if(37808===a||37809===a||37810===a||37811===a||37812===a||37813=== +a||37814===a||37815===a||37816===a||37817===a||37818===a||37819===a||37820===a||37821===a)return c=b.get("WEBGL_compressed_texture_astc"),null!==c?a:null;if(1020===a){if(d)return 34042;c=b.get("WEBGL_depth_texture");return null!==c?c.UNSIGNED_INT_24_8_WEBGL:null}}}}function fg(a,b,c,d){Ba.call(this,a,b,d);this.stencilBuffer=this.depthBuffer=!1;this.numViews=c}function lk(a,b){function c(a){if(a.isArrayCamera)return a.cameras;r[0]=a;return r}function d(a){if(void 0===a.isArrayCamera)return!0;a=a.cameras; +if(a.length>p)return!1;for(var b=1,c=a.length;bf.matrixWorld.determinant();aa.setMaterial(e,h);var l=k(a,c,e,f),m=!1;if(b!==d.id||Je!==l.id||Y!==(!0===e.wireframe))b=d.id,Je=l.id,Y=!0===e.wireframe,m=!0;f.morphTargetInfluences&&(ya.update(f,d,e,l), +m=!0);h=d.index;var r=d.attributes.position;c=1;!0===e.wireframe&&(h=xa.getWireframeAttribute(d),c=2);a=Aa;if(null!==h){var q=ra.get(h);a=Ba;a.setIndex(q)}if(m){if(!1!==Fa.isWebGL2||!f.isInstancedMesh&&!d.isInstancedBufferGeometry||null!==qa.get("ANGLE_instanced_arrays")){aa.initAttributes();m=d.attributes;l=l.getAttributes();var u=e.defaultAttributeValues;for(I in l){var p=l[I];if(0<=p){var t=m[I];if(void 0!==t){var n=t.normalized,v=t.itemSize,y=ra.get(t);if(void 0!==y){var w=y.buffer,x=y.type;y= +y.bytesPerElement;if(t.isInterleavedBufferAttribute){var z=t.data,F=z.stride;t=t.offset;z&&z.isInstancedInterleavedBuffer?(aa.enableAttributeAndDivisor(p,z.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=z.meshPerAttribute*z.count)):aa.enableAttribute(p);K.bindBuffer(34962,w);K.vertexAttribPointer(p,v,x,n,F*y,t*y)}else t.isInstancedBufferAttribute?(aa.enableAttributeAndDivisor(p,t.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=t.meshPerAttribute*t.count)): +aa.enableAttribute(p),K.bindBuffer(34962,w),K.vertexAttribPointer(p,v,x,n,0,0)}}else if("instanceMatrix"===I)y=ra.get(f.instanceMatrix),void 0!==y&&(w=y.buffer,x=y.type,aa.enableAttributeAndDivisor(p+0,1),aa.enableAttributeAndDivisor(p+1,1),aa.enableAttributeAndDivisor(p+2,1),aa.enableAttributeAndDivisor(p+3,1),K.bindBuffer(34962,w),K.vertexAttribPointer(p+0,4,x,!1,64,0),K.vertexAttribPointer(p+1,4,x,!1,64,16),K.vertexAttribPointer(p+2,4,x,!1,64,32),K.vertexAttribPointer(p+3,4,x,!1,64,48));else if(void 0!== +u&&(n=u[I],void 0!==n))switch(n.length){case 2:K.vertexAttrib2fv(p,n);break;case 3:K.vertexAttrib3fv(p,n);break;case 4:K.vertexAttrib4fv(p,n);break;default:K.vertexAttrib1fv(p,n)}}}aa.disableUnusedAttributes()}null!==h&&K.bindBuffer(34963,q.buffer)}q=Infinity;null!==h?q=h.count:void 0!==r&&(q=r.count);h=d.drawRange.start*c;r=null!==g?g.start*c:0;var I=Math.max(h,r);g=Math.max(0,Math.min(q,h+d.drawRange.count*c,r+(null!==g?g.count*c:Infinity))-1-I+1);if(0!==g){if(f.isMesh)if(!0===e.wireframe)aa.setLineWidth(e.wireframeLinewidth* +(null===R?fa:1)),a.setMode(1);else switch(f.drawMode){case 0:a.setMode(4);break;case 1:a.setMode(5);break;case 2:a.setMode(6)}else f.isLine?(e=e.linewidth,void 0===e&&(e=1),aa.setLineWidth(e*(null===R?fa:1)),f.isLineSegments?a.setMode(1):f.isLineLoop?a.setMode(2):a.setMode(3)):f.isPoints?a.setMode(0):f.isSprite&&a.setMode(4);f.isInstancedMesh?a.renderInstances(d,I,g,f.count):d.isInstancedBufferGeometry?a.renderInstances(d,I,g,d.maxInstancedCount):a.render(I,g)}};this.compile=function(a,b){C=va.get(a, +b);C.init();a.traverse(function(a){a.isLight&&(C.pushLight(a),a.castShadow&&C.pushShadow(a))});C.setupLights(b);a.traverse(function(b){if(b.material)if(Array.isArray(b.material))for(var c=0;ce.far||f.push({distance:a,distanceToRay:Math.sqrt(h),point:c,index:b,face:null,object:g}))}function lg(a,b,c,d,e,f,g,h,l){Y.call(this,a,b,c,d,e,f,g,h,l);this.format=void 0!==g?g:1022;this.minFilter=void 0!==f?f:1006;this.magFilter=void 0!==e?e:1006;this.generateMipmaps=!1}function Kc(a,b,c,d,e,f,g,h,l,m,r,q){Y.call(this,null,f,g,h,l,m,d,e,r,q);this.image= +{width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1}function Pd(a,b,c,d,e,f,g,h,l){Y.call(this,a,b,c,d,e,f,g,h,l);this.needsUpdate=!0}function Qd(a,b,c,d,e,f,g,h,l,m){m=void 0!==m?m:1026;if(1026!==m&&1027!==m)throw Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");void 0===c&&1026===m&&(c=1012);void 0===c&&1027===m&&(c=1020);Y.call(this,null,d,e,f,g,h,m,c,l);this.image={width:a,height:b};this.magFilter=void 0!==g?g:1003;this.minFilter=void 0!== +h?h:1003;this.generateMipmaps=this.flipY=!1}function Lc(a){D.call(this);this.type="WireframeGeometry";var b=[],c,d,e,f=[0,0],g={},h=["a","b","c"];if(a&&a.isGeometry){var l=a.faces;var m=0;for(d=l.length;mc;c++){var q=r[h[c]];var k=r[h[(c+1)%3]];f[0]=Math.min(q,k);f[1]=Math.max(q,k);q=f[0]+","+f[1];void 0===g[q]&&(g[q]={index1:f[0],index2:f[1]})}}for(q in g)m=g[q],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&a.isBufferGeometry)if(h= +new n,null!==a.index){l=a.attributes.position;r=a.index;var p=a.groups;0===p.length&&(p=[{start:0,count:r.count,materialIndex:0}]);a=0;for(e=p.length;ac;c++)q=r.getX(m+c),k=r.getX(m+(c+1)%3),f[0]=Math.min(q,k),f[1]=Math.max(q,k),q=f[0]+","+f[1],void 0===g[q]&&(g[q]={index1:f[0],index2:f[1]});for(q in g)m=g[q],h.fromBufferAttribute(l,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(l,m.index2),b.push(h.x,h.y,h.z)}else for(l=a.attributes.position, +m=0,d=l.count/3;mc;c++)g=3*m+c,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z);this.setAttribute("position",new A(b,3))}function Rd(a,b,c){G.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new Mc(a,b,c));this.mergeVertices()}function Mc(a,b,c){D.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h= +new n,l=new n,m=new n,r=new n,q=new n,k,p;3>a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.");var t=b+1;for(k=0;k<=c;k++){var v=k/c;for(p=0;p<=b;p++){var y=p/b;a(y,v,l);e.push(l.x,l.y,l.z);0<=y-1E-5?(a(y-1E-5,v,m),r.subVectors(l,m)):(a(y+1E-5,v,m),r.subVectors(m,l));0<=v-1E-5?(a(y,v-1E-5,m),q.subVectors(l,m)):(a(y,v+1E-5,m),q.subVectors(m,l));h.crossVectors(r,q).normalize();f.push(h.x,h.y,h.z);g.push(y,v)}}for(k=0;kd&&1===a.x&&(l[b]=a.x-1);0===c.x&&0===c.z&&(l[b]=d/2/Math.PI+.5)}D.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;var h=[],l=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;he&&(.2>b&&(l[a+0]+=1),.2>c&&(l[a+2]+=1),.2>d&&(l[a+4]+=1))})();this.setAttribute("position", +new A(h,3));this.setAttribute("normal",new A(h.slice(),3));this.setAttribute("uv",new A(l,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Td(a,b){G.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Nc(a,b));this.mergeVertices()}function Nc(a,b){Ea.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="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Ud(a,b){G.call(this); +this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new ac(a,b));this.mergeVertices()}function ac(a,b){Ea.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="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Vd(a,b){G.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Oc(a,b));this.mergeVertices()}function Oc(a,b){var c= +(1+Math.sqrt(5))/2;Ea.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Wd(a,b){G.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Pc(a,b));this.mergeVertices()}function Pc(a,b){var c= +(1+Math.sqrt(5))/2,d=1/c;Ea.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="DodecahedronBufferGeometry";this.parameters= +{radius:a,detail:b}}function Xd(a,b,c,d,e,f){G.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};void 0!==f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new bc(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function bc(a,b,c,d,e){function f(e){r=a.getPointAt(e/b,r);var f=g.normals[e];e=g.binormals[e];for(u=0;u<=d;u++){var m=u/d*Math.PI* +2,k=Math.sin(m);m=-Math.cos(m);l.x=m*f.x+k*e.x;l.y=m*f.y+k*e.y;l.z=m*f.z+k*e.z;l.normalize();t.push(l.x,l.y,l.z);h.x=r.x+c*l.x;h.y=r.y+c*l.y;h.z=r.z+c*l.z;p.push(h.x,h.y,h.z)}}D.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,l=new n,m=new B,r=new n,k,u,p=[],t=[],v=[],y=[];for(k= +0;k=b;e-=d)f=Sh(e,a[e],a[e+1],f);f&&cc(f,f.next)&&($d(f),f=f.next);return f}function ae(a,b){if(!a)return a; +b||(b=a);do{var c=!1;if(a.steiner||!cc(a,a.next)&&0!==xa(a.prev,a,a.next))a=a.next;else{$d(a);a=b=a.prev;if(a===a.next)break;c=!0}}while(c||a!==b);return b}function be(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,l=h;do null===l.z&&(l.z=mg(l.x,l.y,d,e,f)),l.prevZ=l.prev,l=l.nextZ=l.next;while(l!==h);l.prevZ.nextZ=null;l.prevZ=null;h=l;var m,r,k,u,p=1;do{l=h;var t=h=null;for(r=0;l;){r++;var n=l;for(m=k=0;mn!==t.next.y>n&&t.next.y!==t.y&&k<(t.next.x- +t.x)*(n-t.y)/(t.next.y-t.y)+t.x&&(r=!r),t=t.next;while(t!==l);t=r}l=t}if(l){a=Uh(g,h);g=ae(g,g.next);a=ae(a,a.next);be(g,b,c,d,e,f);be(a,b,c,d,e,f);break a}h=h.next}g=g.next}while(g!==a)}break}}}}function mk(a,b,c,d){var e=a.prev,f=a.next;if(0<=xa(e,a,f))return!1;var g=e.x>a.x?e.x>f.x?e.x:f.x:a.x>f.x?a.x:f.x,h=e.y>a.y?e.y>f.y?e.y:f.y:a.y>f.y?a.y:f.y,l=mg(e.x=l&&d&&d.z<= +b;){if(c!==a.prev&&c!==a.next&&Sc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=xa(c.prev,c,c.next))return!1;c=c.prevZ;if(d!==a.prev&&d!==a.next&&Sc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=xa(d.prev,d,d.next))return!1;d=d.nextZ}for(;c&&c.z>=l;){if(c!==a.prev&&c!==a.next&&Sc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=xa(c.prev,c,c.next))return!1;c=c.prevZ}for(;d&&d.z<=b;){if(d!==a.prev&&d!==a.next&&Sc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=xa(d.prev,d,d.next))return!1;d=d.nextZ}return!0}function nk(a,b){return a.x-b.x} +function ok(a,b){var c=b,d=a.x,e=a.y,f=-Infinity;do{if(e<=c.y&&e>=c.next.y&&c.next.y!==c.y){var g=c.x+(e-c.y)*(c.next.x-c.x)/(c.next.y-c.y);if(g<=d&&g>f){f=g;if(g===d){if(e===c.y)return c;if(e===c.next.y)return c.next}var h=c.x=c.x&&c.x>=g&&d!==c.x&&Sc(eh.x)&&ce(c,a)&&(h=c,m=r)}c= +c.next}return h}function mg(a,b,c,d,e){a=32767*(a-c)*e;b=32767*(b-d)*e;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135;a=(a|a<<2)&858993459;b=(b|b<<8)&16711935;b=(b|b<<4)&252645135;b=(b|b<<2)&858993459;return(a|a<<1)&1431655765|((b|b<<1)&1431655765)<<1}function pk(a){var b=a,c=a;do{if(b.xxa(a.prev,a,a.next)?0<=xa(a,b,a.next)&&0<=xa(a,a.prev,b):0>xa(a,b,a.prev)||0>xa(a,a.next,b)}function Uh(a,b){var c=new ng(a.i,a.x,a.y),d=new ng(b.i,b.x,b.y),e=a.next,f=b.prev;a.next=b;b.prev=a;c.next=e;e.prev=c;d.next=c;c.prev=d;f.next=d;d.prev=f;return d}function Sh(a,b,c,d){a=new ng(a, +b,c);d?(a.next=d.next,a.prev=d,d.next.prev=a,d.next=a):(a.prev=a,a.next=a);return a}function $d(a){a.next.prev=a.prev;a.prev.next=a.next;a.prevZ&&(a.prevZ.nextZ=a.nextZ);a.nextZ&&(a.nextZ.prevZ=a.prevZ)}function ng(a,b,c){this.i=a;this.x=b;this.y=c;this.nextZ=this.prevZ=this.z=this.next=this.prev=null;this.steiner=!1}function Vh(a){var b=a.length;2Number.EPSILON){var l=Math.sqrt(h),m=Math.sqrt(f*f+g*g);h=b.x-e/l;b=b.y+d/l;g=((c.x-g/m-h)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=h+d*g-a.x;d=b+e*g-a.y;e=f*f+ +d*d;if(2>=e)return new B(f,d);e=Math.sqrt(e/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?(f=-e,e=Math.sqrt(h)):(f=d,d=e,e=Math.sqrt(h/2));return new B(f/e,d/e)}function h(a,b){for(M=a.length;0<=--M;){var c=M;var f=M-1;0>f&&(f=a.length-1);var g,h=x+2*E;for(g=0;gk;k++){var q=m[f[k]];var n=m[f[(k+1)%3]];d[0]=Math.min(q,n);d[1]=Math.max(q,n);q=d[0]+","+d[1];void 0===e[q]?e[q]={index1:d[0],index2:d[1],face1:h,face2:void 0}:e[q].face2=h}for(q in e)if(d=e[q],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<= +b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.setAttribute("position",new A(c,3))}function gc(a,b,c,d,e,f,g,h){G.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new rb(a,b,c,d,e,f,g,h));this.mergeVertices()}function rb(a,b,c,d,e,f,g,h){function l(c){var e,f=new B,l=new n,r=0,v=!0===c?a:b,x=!0===c?1:-1;var A=t;for(e=1;e<=d;e++)q.push(0, +y*x,0),u.push(0,x,0),p.push(.5,.5),t++;var H=t;for(e=0;e<=d;e++){var E=e/d*h+g,C=Math.cos(E);E=Math.sin(E);l.x=v*E;l.y=y*x;l.z=v*C;q.push(l.x,l.y,l.z);u.push(0,x,0);f.x=.5*C+.5;f.y=.5*E*x+.5;p.push(f.x,f.y);t++}for(e=0;ethis.duration&& +this.resetDuration()}function rk(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return Zc;case "vector":case "vector2":case "vector3":case "vector4":return $c;case "color":return Ue;case "quaternion":return le;case "bool":case "boolean":return Te;case "string":return We}throw Error("THREE.KeyframeTrack: Unsupported typeName: "+a);}function sk(a){if(void 0===a.type)throw Error("THREE.KeyframeTrack: track type undefined, can not parse");var b=rk(a.type); +if(void 0===a.times){var c=[],d=[];ta.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)}function og(a,b,c){var d=this,e=!1,f=0,g=0,h=void 0,l=[];this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){g++;if(!1===e&&void 0!==d.onStart)d.onStart(a,f,g);e=!0};this.itemEnd=function(a){f++;if(void 0!==d.onProgress)d.onProgress(a,f,g);if(f===g&&(e=!1,void 0!==d.onLoad))d.onLoad()}; +this.itemError=function(a){if(void 0!==d.onError)d.onError(a)};this.resolveURL=function(a){return h?h(a):a};this.setURLModifier=function(a){h=a;return this};this.addHandler=function(a,b){l.push(a,b);return this};this.removeHandler=function(a){a=l.indexOf(a);-1!==a&&l.splice(a,2);return this};this.getHandler=function(a){for(var b=0,c=l.length;ba;a++)this.coefficients.push(new n)}function Xa(a,b){T.call(this,void 0,b);this.sh=void 0!==a?a:new of}function xg(a,b,c){Xa.call(this,void 0,c);a=(new J).set(a);c=(new J).set(b);b=new n(a.r,a.g,a.b);a=new n(c.r,c.g,c.b);c=Math.sqrt(Math.PI);var d=c*Math.sqrt(.75);this.sh.coefficients[0].copy(b).add(a).multiplyScalar(c);this.sh.coefficients[1].copy(b).sub(a).multiplyScalar(d)}function yg(a,b){Xa.call(this,void 0,b);a=(new J).set(a);this.sh.coefficients[0].set(a.r,a.g,a.b).multiplyScalar(2*Math.sqrt(Math.PI))} +function ai(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new U;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new U;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1;this._cache={focus:null,fov:null,aspect:null,near:null,far:null,zoom:null,eyeSep:null}}function zg(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}function Ag(){E.call(this);this.type="AudioListener";this.context=Bg.getContext(); +this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0;this._clock=new zg}function cd(a){E.call(this);this.type="Audio";this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=this.loopEnd=this.loopStart=0;this.duration=void 0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this._pausedAt= +this._startedAt=0;this.filters=[]}function Cg(a){cd.call(this,a);this.panner=this.context.createPanner();this.panner.panningModel="HRTF";this.panner.connect(this.gain)}function Dg(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)}function Eg(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a= +Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function bi(a,b,c){c=c||ya.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function ya(a,b,c){this.path=b;this.parsedPath=c||ya.parseTrackName(b);this.node=ya.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function ci(){this.uuid=P.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_= +0;var a={};this._indicesByUUID=a;for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length},get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function di(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400}, +e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart= +!0}function Fg(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1}function pf(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Gg(a,b,c){pb.call(this,a,b);this.meshPerAttribute=c||1}function ei(a,b,c,d){this.ray=new Rb(a,b);this.near=c||0;this.far=d||Infinity;this.camera=null;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}}})}function fi(a,b){return a.distance-b.distance}function Hg(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;dc;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.setAttribute("position",new A(b,3));b=new R({fog:!1});this.cone=new X(a,b);this.add(this.cone);this.update()}function ii(a){var b=[];a&&a.isBone&&b.push(a);for(var c= +0;ca?-1:0we;we++)oa[we]=(16>we?"0":"")+ +we.toString(16);var P={DEG2RAD:Math.PI/180,RAD2DEG:180/Math.PI,generateUUID:function(){var a=4294967295*Math.random()|0,b=4294967295*Math.random()|0,c=4294967295*Math.random()|0,d=4294967295*Math.random()|0;return(oa[a&255]+oa[a>>8&255]+oa[a>>16&255]+oa[a>>24&255]+"-"+oa[b&255]+oa[b>>8&255]+"-"+oa[b>>16&15|64]+oa[b>>24&255]+"-"+oa[c&63|128]+oa[c>>8&255]+"-"+oa[c>>16&255]+oa[c>>24&255]+oa[d&255]+oa[d>>8&255]+oa[d>>16&255]+oa[d>>24&255]).toUpperCase()},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)},lerp:function(a,b,c){return(1-c)*a+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)},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(a){return a*P.DEG2RAD},radToDeg:function(a){return a*P.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},ceilPowerOfTwo:function(a){return Math.pow(2,Math.ceil(Math.log(a)/Math.LN2))},floorPowerOfTwo:function(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))}};Object.defineProperties(B.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(B.prototype, +{isVector2:!0,set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x=a;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);}return this},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){return this.multiplyScalar(1/a)},applyMatrix3:function(a){var b=this.x,c=this.y;a=a.elements;this.x=a[0]*b+a[3]*c+a[6];this.y= +a[1]*b+a[4]*c+a[7];return this},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(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c|| +1).multiplyScalar(Math.max(a,Math.min(b,c)))},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},cross:function(a){return this.x*a.y-this.y*a.x},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||1)},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a},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},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},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){return this.subVectors(b,a).multiplyScalar(c).add(a)},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},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a,b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}});Object.assign(wa,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var h= +c[d+0],l=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var k=e[f+1],q=e[f+2];e=e[f+3];if(c!==e||h!==d||l!==k||m!==q){f=1-g;var n=h*d+l*k+m*q+c*e,p=0<=n?1:-1,t=1-n*n;t>Number.EPSILON&&(t=Math.sqrt(t),n=Math.atan2(t,n*p),f=Math.sin(f*n)/t,g=Math.sin(g*n)/t);p*=g;h=h*f+d*p;l=l*f+k*p;m=m*f+q*p;c=c*f+e*p;f===1-g&&(g=1/Math.sqrt(h*h+l*l+m*m+c*c),h*=g,l*=g,m*=g,c*=g)}a[b]=h;a[b+1]=l;a[b+2]=m;a[b+3]=c}});Object.defineProperties(wa.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}}, +y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this._onChangeCallback()}}});Object.assign(wa.prototype,{isQuaternion:!0,set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(a){this._x= +a.x;this._y=a.y;this._z=a.z;this._w=a.w;this._onChangeCallback();return this},setFromEuler:function(a,b){if(!a||!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z;a=a.order;var f=Math.cos,g=Math.sin,h=f(c/2),l=f(d/2);f=f(e/2);c=g(c/2);d=g(d/2);e=g(e/2);"XYZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"YXZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z= +h*l*e-c*d*f,this._w=h*l*f+c*d*e):"ZXY"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"ZYX"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f+c*d*e):"YZX"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f-c*d*e):"XZY"===a&&(this._x=c*l*f-h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f+c*d*e);!1!==b&&this._onChangeCallback();return this},setFromAxisAngle:function(a,b){b/=2;var c=Math.sin(b); +this._x=a.x*c;this._y=a.y*c;this._z=a.z*c;this._w=Math.cos(b);this._onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],l=b[6];b=b[10];var m=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(l-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(g+l)/ +c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+l)/c,this._z=.25*c);this._onChangeCallback();return this},setFromUnitVectors:function(a,b){var c=a.dot(b)+1;1E-6>c?(c=0,Math.abs(a.x)>Math.abs(a.z)?(this._x=-a.y,this._y=a.x,this._z=0):(this._x=0,this._y=-a.z,this._z=a.y)):(this._x=a.y*b.z-a.z*b.y,this._y=a.z*b.x-a.x*b.z,this._z=a.x*b.y-a.y*b.x);this._w=c;return this.normalize()},angleTo:function(a){return 2*Math.acos(Math.abs(P.clamp(this.dot(a),-1,1)))},rotateTowards:function(a, +b){var c=this.angleTo(a);if(0===c)return this;this.slerp(a,Math.min(1,b/c));return this},inverse:function(){return this.conjugate()},conjugate:function(){this._x*=-1;this._y*=-1;this._z*=-1;this._onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a= +this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this._onChangeCallback();return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z;a=a._w; +var f=b._x,g=b._y,h=b._z;b=b._w;this._x=c*b+a*f+d*h-e*g;this._y=d*b+a*g+e*f-c*h;this._z=e*b+a*h+c*g-d*f;this._w=a*b-c*f-d*g-e*h;this._onChangeCallback();return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;a=1-g*g;if(a<=Number.EPSILON)return g=1-b,this._w=g* +f+b*this._w,this._x=g*c+b*this._x,this._y=g*d+b*this._y,this._z=g*e+b*this._z,this.normalize(),this._onChangeCallback(),this;a=Math.sqrt(a);var h=Math.atan2(a,g);g=Math.sin((1-b)*h)/a;b=Math.sin(b*h)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;this._onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2]; +this._w=a[b+3];this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});var Mg=new n,li=new wa;Object.assign(n.prototype,{isVector3:!0,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;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);}return this},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(a){a&&a.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(li.setFromEuler(a))},applyAxisAngle:function(a,b){return this.applyQuaternion(li.setFromAxisAngle(a,b))},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;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,l=a*c+g*b-e*d,m=a*d+e*c-f*b;b=-e*b-f*c-g*d;this.x=h*a+b*-e+l*-g-m*-f;this.y=l*a+b*-f+m*-e-h*-g;this.z=m*a+b*-g+h*-f-l*-e;return this}, +project:function(a){return this.applyMatrix4(a.matrixWorldInverse).applyMatrix4(a.projectionMatrix)},unproject:function(a){return this.applyMatrix4(a.projectionMatrixInverse).applyMatrix4(a.matrixWorld)},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;return this.normalize()},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(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a, +Math.min(b,this.z));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},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)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+ +Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},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){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){return void 0!==b?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b)):this.crossVectors(this, +a)},crossVectors:function(a,b){var c=a.x,d=a.y;a=a.z;var e=b.x,f=b.y;b=b.z;this.x=d*b-a*f;this.y=a*e-c*b;this.z=c*f-d*e;return this},projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(a){Mg.copy(this).projectOnVector(a);return this.sub(Mg)},reflect:function(a){return this.sub(Mg.copy(a).multiplyScalar(2*this.dot(a)))},angleTo:function(a){var b=Math.sqrt(this.lengthSq()*a.lengthSq());0===b&&console.error("THREE.Vector3: angleTo() can't handle zero length vectors."); +a=this.dot(a)/b;return Math.acos(P.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},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){return this.setFromSphericalCoords(a.radius,a.phi,a.theta)},setFromSphericalCoords:function(a,b,c){var d=Math.sin(b)*a;this.x=d*Math.sin(c);this.y=Math.cos(b)* +a;this.z=d*Math.cos(c);return this},setFromCylindrical:function(a){return this.setFromCylindricalCoords(a.radius,a.theta,a.y)},setFromCylindricalCoords:function(a,b,c){this.x=a*Math.sin(b);this.y=c;this.z=a*Math.cos(b);return this},setFromMatrixPosition:function(a){a=a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},setFromMatrixScale:function(a){var b=this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a,2).length();this.x=b;this.y= +c;this.z=a;return this},setFromMatrixColumn:function(a,b){return this.fromArray(a.elements,4*b)},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},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute()."); +this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});var oc=new n;Object.assign(Z.prototype,{isMatrix3:!0,set:function(a,b,c,d,e,f,g,h,l){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=l;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]= +a[7];b[8]=a[8];return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this},applyToBufferAttribute:function(a){for(var b=0,c=a.count;bc;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);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}});var ld,Jb={getDataURL:function(a){if("undefined"==typeof HTMLCanvasElement)return a.src;if(!(a instanceof HTMLCanvasElement)){void 0===ld&&(ld=document.createElementNS("http://www.w3.org/1999/xhtml","canvas"));ld.width=a.width;ld.height=a.height;var b=ld.getContext("2d");a instanceof ImageData?b.putImageData(a,0,0):b.drawImage(a,0,0,a.width,a.height);a=ld}return 2048a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y);return a}});Object.defineProperty(Y.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.defineProperties(da.prototype,{width:{get:function(){return this.z}, +set:function(a){this.z=a}},height:{get:function(){return this.w},set:function(a){this.w=a}}});Object.assign(da.prototype,{isVector4:!0,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;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);}return this},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){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){a=a.elements;var b=a[0];var c=a[4];var d=a[8],e=a[1],f=a[5],g=a[9];var h=a[2];var l=a[6];var m=a[10];if(.01>Math.abs(c-e)&&.01>Math.abs(d-h)&&.01>Math.abs(g-l)){if(.1>Math.abs(c+ +e)&&.1>Math.abs(d+h)&&.1>Math.abs(g+l)&&.1>Math.abs(b+f+m-3))return this.set(1,0,0,0),this;a=Math.PI;b=(b+1)/2;f=(f+1)/2;m=(m+1)/2;c=(c+e)/4;d=(d+h)/4;g=(g+l)/4;b>f&&b>m?.01>b?(l=0,c=h=.707106781):(l=Math.sqrt(b),h=c/l,c=d/l):f>m?.01>f?(l=.707106781,h=0,c=.707106781):(h=Math.sqrt(f),l=c/h,c=g/h):.01>m?(h=l=.707106781,c=0):(c=Math.sqrt(m),l=d/c,h=g/c);this.set(l,h,c,a);return this}a=Math.sqrt((l-g)*(l-g)+(d-h)*(d-h)+(e-c)*(e-c));.001>Math.abs(a)&&(a=1);this.x=(l-g)/a;this.y=(d-h)/a;this.z=(e-c)/a; +this.w=Math.acos((b+f+m-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(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a,Math.min(b,this.z));this.w=Math.max(a,Math.min(b,this.w));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},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)},manhattanLength: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()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)}, +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){return this.subVectors(b,a).multiplyScalar(c).add(a)},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},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector4: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);this.w=a.getW(b);return this}});Ba.prototype=Object.assign(Object.create(Aa.prototype),{constructor:Ba,isWebGLRenderTarget:!0,setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.texture.image.width=a,this.texture.image.height=b,this.dispose();this.viewport.set(0,0, +a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport);this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});Sf.prototype=Object.assign(Object.create(Ba.prototype),{constructor:Sf,isWebGLMultisampleRenderTarget:!0,copy:function(a){Ba.prototype.copy.call(this, +a);this.samples=a.samples;return this}});var Ka=new n,ca=new Q,tk=new n(0,0,0),uk=new n(1,1,1),Kb=new n,uf=new n,pa=new n;Object.assign(Q.prototype,{isMatrix4:!0,set:function(a,b,c,d,e,f,g,h,l,m,k,q,n,p,t,v){var r=this.elements;r[0]=a;r[4]=b;r[8]=c;r[12]=d;r[1]=e;r[5]=f;r[9]=g;r[13]=h;r[2]=l;r[6]=m;r[10]=k;r[14]=q;r[3]=n;r[7]=p;r[11]=t;r[15]=v;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 Q).fromArray(this.elements)},copy:function(a){var b= +this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return this},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){a.setFromMatrixColumn(this,0);b.setFromMatrixColumn(this,1);c.setFromMatrixColumn(this,2);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(a){var b=this.elements,c=a.elements,d=1/Ka.setFromMatrixColumn(a,0).length(),e=1/Ka.setFromMatrixColumn(a,1).length();a=1/Ka.setFromMatrixColumn(a,2).length();b[0]=c[0]*d;b[1]=c[1]*d;b[2]=c[2]*d;b[3]=0;b[4]=c[4]*e;b[5]=c[5]*e;b[6]=c[6]*e;b[7]=0;b[8]=c[8]*a;b[9]=c[9]*a;b[10]=c[10]*a;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromEuler:function(a){a&&a.isEuler||console.error("THREE.Matrix4: .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,f=Math.cos(c);c=Math.sin(c);var g=Math.cos(d);d=Math.sin(d);var h=Math.cos(e);e=Math.sin(e);if("XYZ"===a.order){a=f*h;var l=f*e,m=c*h,k=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=l+m*d;b[5]=a-k*d;b[9]=-c*g;b[2]=k-a*d;b[6]=m+l*d;b[10]=f*g}else"YXZ"===a.order?(a=g*h,l=g*e,m=d*h,k=d*e,b[0]=a+k*c,b[4]=m*c-l,b[8]=f*d,b[1]=f*e,b[5]=f*h,b[9]=-c,b[2]=l*c-m,b[6]=k+a*c,b[10]=f*g):"ZXY"===a.order?(a=g*h,l=g*e,m=d*h,k=d*e,b[0]=a-k*c,b[4]=-f*e,b[8]=m+l*c,b[1]=l+m*c,b[5]=f*h,b[9]= +k-a*c,b[2]=-f*d,b[6]=c,b[10]=f*g):"ZYX"===a.order?(a=f*h,l=f*e,m=c*h,k=c*e,b[0]=g*h,b[4]=m*d-l,b[8]=a*d+k,b[1]=g*e,b[5]=k*d+a,b[9]=l*d-m,b[2]=-d,b[6]=c*g,b[10]=f*g):"YZX"===a.order?(a=f*g,l=f*d,m=c*g,k=c*d,b[0]=g*h,b[4]=k-a*e,b[8]=m*e+l,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=l*e+m,b[10]=a-k*e):"XZY"===a.order&&(a=f*g,l=f*d,m=c*g,k=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+k,b[5]=f*h,b[9]=l*e-m,b[2]=m*e-l,b[6]=c*h,b[10]=k*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},makeRotationFromQuaternion:function(a){return this.compose(tk, +a,uk)},lookAt:function(a,b,c){var d=this.elements;pa.subVectors(a,b);0===pa.lengthSq()&&(pa.z=1);pa.normalize();Kb.crossVectors(c,pa);0===Kb.lengthSq()&&(1===Math.abs(c.z)?pa.x+=1E-4:pa.z+=1E-4,pa.normalize(),Kb.crossVectors(c,pa));Kb.normalize();uf.crossVectors(pa,Kb);d[0]=Kb.x;d[4]=uf.x;d[8]=pa.x;d[1]=Kb.y;d[5]=uf.y;d[9]=pa.y;d[2]=Kb.z;d[6]=uf.z;d[10]=pa.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)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements;b=this.elements;a=c[0];var e=c[4],f=c[8],g=c[12],h=c[1],l=c[5],m=c[9],k=c[13],q=c[2],n=c[6],p=c[10],t=c[14],v=c[3],y=c[7],w=c[11];c=c[15];var x=d[0],B=d[4],I=d[8],z=d[12],A=d[1],E=d[5],C=d[9],D=d[13],H=d[2],G=d[6],J=d[10],L=d[14],N=d[3],O=d[7],P=d[11];d=d[15];b[0]=a*x+e*A+f*H+g*N;b[4]=a*B+e*E+f*G+g*O;b[8]=a*I+e*C+f*J+ +g*P;b[12]=a*z+e*D+f*L+g*d;b[1]=h*x+l*A+m*H+k*N;b[5]=h*B+l*E+m*G+k*O;b[9]=h*I+l*C+m*J+k*P;b[13]=h*z+l*D+m*L+k*d;b[2]=q*x+n*A+p*H+t*N;b[6]=q*B+n*E+p*G+t*O;b[10]=q*I+n*C+p*J+t*P;b[14]=q*z+n*D+p*L+t*d;b[3]=v*x+y*A+w*H+c*N;b[7]=v*B+y*E+w*G+c*O;b[11]=v*I+y*C+w*J+c*P;b[15]=v*z+y*D+w*L+c*d;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},applyToBufferAttribute:function(a){for(var b= +0,c=a.count;bthis.determinant()&&(e=-e);a.x=d[12];a.y=d[13];a.z=d[14];ca.copy(this);a=1/e;d=1/f;var h=1/g;ca.elements[0]*=a;ca.elements[1]*=a;ca.elements[2]*=a;ca.elements[4]*=d;ca.elements[5]*=d;ca.elements[6]*=d;ca.elements[8]*=h;ca.elements[9]*=h;ca.elements[10]*=h;b.setFromRotationMatrix(ca);c.x=e;c.y=f;c.z=g;return this},makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs."); +var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(c-d);g[9]=(c+d)/(c-d);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),l=1/(c-d),m=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*l;g[9]=0;g[13]=-((c+d)*l);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+e)*m);g[3]=0;g[7]=0;g[11]=0;g[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,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);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}});var mi=new Q,ni=new wa;Pb.RotationOrders= +"XYZ YZX ZXY XZY YXZ ZYX".split(" ");Pb.DefaultOrder="XYZ";Object.defineProperties(Pb.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},order:{get:function(){return this._order},set:function(a){this._order=a;this._onChangeCallback()}}});Object.assign(Pb.prototype,{isEuler:!0,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=P.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],l=e[5],m=e[9],k=e[2],n=e[6];e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.9999999>Math.abs(g)? +(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(n,l),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.9999999>Math.abs(m)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h,l)):(this._y=Math.atan2(-k,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(n,-1,1)),.9999999>Math.abs(n)?(this._y=Math.atan2(-k,e),this._z=Math.atan2(-f,l)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(k,-1,1)),.9999999>Math.abs(k)?(this._x=Math.atan2(n,e),this._z=Math.atan2(h,a)): +(this._x=0,this._z=Math.atan2(-f,l))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.9999999>Math.abs(h)?(this._x=Math.atan2(-m,l),this._y=Math.atan2(-k,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.9999999>Math.abs(f)?(this._x=Math.atan2(n,l),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;!1!==c&&this._onChangeCallback();return this},setFromQuaternion:function(a, +b,c){mi.makeRotationFromQuaternion(a);return this.setFromRotationMatrix(mi,b,c)},setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(a){ni.setFromEuler(this);return this.setFromQuaternion(ni,a)},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 n(this._x,this._y,this._z)},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});Object.assign(Tf.prototype,{set:function(a){this.mask=1<e&&(e=m);k>f&&(f=k);n>g&&(g=n)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,l=a.count;he&&(e=m);k>f&&(f=k);n>g&&(g=n)}this.min.set(b,c,d); +this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<= +this.max.z},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box3: .getParameter() target is now required"),b=new n);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},intersectsSphere:function(a){this.clampPoint(a.center,ib);return ib.distanceToSquared(a.center)<= +a.radius*a.radius},intersectsPlane:function(a){if(0=-a.constant},intersectsTriangle:function(a){if(this.isEmpty())return!1; +this.getCenter(ye);wf.subVectors(this.max,ye);nd.subVectors(a.a,ye);od.subVectors(a.b,ye);pd.subVectors(a.c,ye);Lb.subVectors(od,nd);Mb.subVectors(pd,od);pc.subVectors(nd,pd);a=[0,-Lb.z,Lb.y,0,-Mb.z,Mb.y,0,-pc.z,pc.y,Lb.z,0,-Lb.x,Mb.z,0,-Mb.x,pc.z,0,-pc.x,-Lb.y,Lb.x,0,-Mb.y,Mb.x,0,-pc.y,pc.x,0];if(!Uf(a,nd,od,pd,wf))return!1;a=[1,0,0,0,1,0,0,0,1];if(!Uf(a,nd,od,pd,wf))return!1;xf.crossVectors(Lb,Mb);a=[xf.x,xf.y,xf.z];return Uf(a,nd,od,pd,wf)},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box3: .clampPoint() target is now required"), +b=new n);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return ib.copy(a).clamp(this.min,this.max).sub(a).length()},getBoundingSphere:function(a){void 0===a&&console.error("THREE.Box3: .getBoundingSphere() target is now required");this.getCenter(a.center);a.radius=.5*this.getSize(ib).length();return a},intersect:function(a){this.min.max(a.min);this.max.min(a.max);this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this}, +applyMatrix4:function(a){if(this.isEmpty())return this;wb[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(a);wb[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(a);wb[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(a);wb[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(a);wb[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(a);wb[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(a);wb[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(a);wb[7].set(this.max.x,this.max.y, +this.max.z).applyMatrix4(a);this.setFromPoints(wb);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});var zk=new ab;Object.assign(mb.prototype,{set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(a,b){var c=this.center;void 0!==b?c.copy(b):zk.setFromPoints(a).getCenter(c);for(var d=b=0,e=a.length;d=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},intersectsBox:function(a){return a.intersectsSphere(this)}, +intersectsPlane:function(a){return Math.abs(a.distanceToPoint(this.center))<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a);void 0===b&&(console.warn("THREE.Sphere: .clampPoint() target is now required"),b=new n);b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center));return b},getBoundingBox:function(a){void 0===a&&(console.warn("THREE.Sphere: .getBoundingBox() target is now required"),a=new ab);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}});var xb=new n,Ng=new n,yf=new n,Nb=new n,Og=new n,zf=new n,Pg=new n;Object.assign(Rb.prototype,{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){void 0===b&&(console.warn("THREE.Ray: .at() target is now required"),b=new n);return b.copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(a){this.origin.copy(this.at(a,xb));return this},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Ray: .closestPointToPoint() target is now required"), +b=new n);b.subVectors(a,this.origin);a=b.dot(this.direction);return 0>a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(a){var b=xb.subVectors(a,this.origin).dot(this.direction);if(0>b)return this.origin.distanceToSquared(a);xb.copy(this.direction).multiplyScalar(b).add(this.origin);return xb.distanceToSquared(a)},distanceSqToSegment:function(a,b,c,d){Ng.copy(a).add(b).multiplyScalar(.5); +yf.copy(b).sub(a).normalize();Nb.copy(this.origin).sub(Ng);var e=.5*a.distanceTo(b),f=-this.direction.dot(yf),g=Nb.dot(this.direction),h=-Nb.dot(yf),l=Nb.lengthSq(),m=Math.abs(1-f*f);if(0=-k?b<=k?(e=1/m,a*=e,b*=e,f=a*(a+f*b+2*g)+b*(f*a+b+2*h)+l):(b=e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):(b=-e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):b<=-k?(a=Math.max(0,-(-f*e+g)),b=0a)return null;a=Math.sqrt(a-d);d=c-a;c+=a;return 0>d&&0>c?null:0>d?this.at(c,b):this.at(d,b)}, +intersectsSphere:function(a){return this.distanceSqToPoint(a.center)<=a.radius*a.radius},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){a=this.distanceToPlane(a);return null===a?null:this.at(a,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a, +b){var c=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z,f=this.origin;if(0<=c){var g=(a.min.x-f.x)*c;c*=a.max.x-f.x}else g=(a.max.x-f.x)*c,c*=a.min.x-f.x;if(0<=d){var h=(a.min.y-f.y)*d;d*=a.max.y-f.y}else h=(a.max.y-f.y)*d,d*=a.min.y-f.y;if(g>d||h>c)return null;if(h>g||g!==g)g=h;if(da||h>c)return null;if(h>g||g!==g)g=h;if(ac?null:this.at(0<=g?g:c,b)},intersectsBox:function(a){return null!== +this.intersectBox(a,xb)},intersectTriangle:function(a,b,c,d,e){Og.subVectors(b,a);zf.subVectors(c,a);Pg.crossVectors(Og,zf);b=this.direction.dot(Pg);if(0b)d=-1,b=-b;else return null;Nb.subVectors(this.origin,a);a=d*this.direction.dot(zf.crossVectors(Nb,zf));if(0>a)return null;c=d*this.direction.dot(Og.cross(Nb));if(0>c||a+c>b)return null;a=-d*Nb.dot(Pg);return 0>a?null:this.at(a/b,e)},applyMatrix4:function(a){this.origin.applyMatrix4(a);this.direction.transformDirection(a); +return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});var Qg=new n,Ak=new n,Bk=new Z;Object.assign(Oa.prototype,{isPlane:!0,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(a,b,c){b=Qg.subVectors(c,b).cross(Ak.subVectors(a, +b)).normalize();this.setFromNormalAndCoplanarPoint(b,a);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)- +a.radius},projectPoint:function(a,b){void 0===b&&(console.warn("THREE.Plane: .projectPoint() target is now required"),b=new n);return b.copy(this.normal).multiplyScalar(-this.distanceToPoint(a)).add(a)},intersectLine:function(a,b){void 0===b&&(console.warn("THREE.Plane: .intersectLine() target is now required"),b=new n);var c=a.delta(Qg),d=this.normal.dot(c);if(0===d){if(0===this.distanceToPoint(a.start))return b.copy(a.start)}else if(d=-(a.start.dot(this.normal)+this.constant)/d,!(0>d||1b&&0a&&0=zb.x+zb.y},getUV:function(a,b,c,d,e,f,g,h){this.getBarycoord(a,b,c,d,zb);h.set(0,0);h.addScaledVector(e,zb.x);h.addScaledVector(f,zb.y);h.addScaledVector(g,zb.z);return h},isFrontFacing:function(a,b,c,d){Ya.subVectors(c,b);yb.subVectors(a,b);return 0>Ya.cross(yb).dot(d)?!0:!1}});Object.assign(ba.prototype,{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},getArea:function(){Ya.subVectors(this.c,this.b);yb.subVectors(this.a,this.b);return.5*Ya.cross(yb).length()},getMidpoint:function(a){void 0===a&&(console.warn("THREE.Triangle: .getMidpoint() target is now required"),a=new n);return a.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},getNormal:function(a){return ba.getNormal(this.a,this.b, +this.c,a)},getPlane:function(a){void 0===a&&(console.warn("THREE.Triangle: .getPlane() target is now required"),a=new Oa);return a.setFromCoplanarPoints(this.a,this.b,this.c)},getBarycoord:function(a,b){return ba.getBarycoord(a,this.a,this.b,this.c,b)},getUV:function(a,b,c,d,e){return ba.getUV(a,this.a,this.b,this.c,b,c,d,e)},containsPoint:function(a){return ba.containsPoint(a,this.a,this.b,this.c)},isFrontFacing:function(a){return ba.isFrontFacing(this.a,this.b,this.c,a)},intersectsBox:function(a){return a.intersectsTriangle(this)}, +closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),b=new n);var c=this.a,d=this.b,e=this.c;qd.subVectors(d,c);rd.subVectors(e,c);Sg.subVectors(a,c);var f=qd.dot(Sg),g=rd.dot(Sg);if(0>=f&&0>=g)return b.copy(c);Tg.subVectors(a,d);var h=qd.dot(Tg),l=rd.dot(Tg);if(0<=h&&l<=h)return b.copy(d);var m=f*l-h*g;if(0>=m&&0<=f&&0>=h)return d=f/(f-h),b.copy(c).addScaledVector(qd,d);Ug.subVectors(a,e);a=qd.dot(Ug);var k=rd.dot(Ug);if(0<= +k&&a<=k)return b.copy(e);f=a*g-f*k;if(0>=f&&0<=g&&0>=k)return m=g/(g-k),b.copy(c).addScaledVector(rd,m);g=h*k-a*l;if(0>=g&&0<=l-h&&0<=a-k)return si.subVectors(e,d),m=(l-h)/(l-h+(a-k)),b.copy(d).addScaledVector(si,m);e=1/(g+f+m);d=f*e;m*=e;return b.copy(c).addScaledVector(qd,d).addScaledVector(rd,m)},equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}});var ti={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244, +black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347, +darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365, +lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683, +mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910, +purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074}, +za={h:0,s:0,l:0},Af={h:0,s:0,l:0};Object.assign(J.prototype,{isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a=Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){a=P.euclideanModulo(a,1);b=P.clamp(b, +0,1);c=P.clamp(c,0,1);0===b?this.r=this.g=this.b=c:(b=.5>=c?c*(1+b):c+b-c*b,c=2*c-b,this.r=Vf(c,b,a+1/3),this.g=Vf(c,b,a),this.b=Vf(c,b,a-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)){d=parseFloat(c[1])/360;var e=parseInt(c[2], +10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}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}return a&&0=h?l/(e+f):l/(2-e-f);switch(e){case b:g=(c-d)/l+(cthis.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;d.stencilWrite=this.stencilWrite;d.stencilWriteMask=this.stencilWriteMask;d.stencilFunc=this.stencilFunc;d.stencilRef=this.stencilRef; +d.stencilFuncMask=this.stencilFuncMask;d.stencilFail=this.stencilFail;d.stencilZFail=this.stencilZFail;d.stencilZPass=this.stencilZPass;this.rotation&&0!==this.rotation&&(d.rotation=this.rotation);!0===this.polygonOffset&&(d.polygonOffset=!0);0!==this.polygonOffsetFactor&&(d.polygonOffsetFactor=this.polygonOffsetFactor);0!==this.polygonOffsetUnits&&(d.polygonOffsetUnits=this.polygonOffsetUnits);this.linewidth&&1!==this.linewidth&&(d.linewidth=this.linewidth);void 0!==this.dashSize&&(d.dashSize=this.dashSize); +void 0!==this.gapSize&&(d.gapSize=this.gapSize);void 0!==this.scale&&(d.scale=this.scale);!0===this.dithering&&(d.dithering=!0);0g;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;c\n\t#include \n}", +fragmentShader:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}",side:1,blending:0});d.uniforms.tEquirect.value=b;b=new ea(new Fd(5, +5,5),d);c.add(b);d=new Bc(1,10,1);d.renderTarget=this;d.renderTarget.texture.name="CubeCameraTexture";d.update(a,c);b.geometry.dispose();b.material.dispose();return this};Yb.prototype=Object.create(Y.prototype);Yb.prototype.constructor=Yb;Yb.prototype.isDataTexture=!0;var sd=new mb,Df=new n;Object.assign(Dd.prototype,{set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},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],f=c[3],g=c[4],h=c[5],l=c[6],m=c[7],k=c[8],n=c[9],u=c[10],p=c[11],t=c[12],v=c[13],y=c[14];c=c[15];b[0].setComponents(f-a,m-g,p-k,c-t).normalize();b[1].setComponents(f+a,m+g,p+k,c+t).normalize();b[2].setComponents(f+d,m+h,p+n,c+v).normalize();b[3].setComponents(f-d,m-h,p-n,c-v).normalize();b[4].setComponents(f-e,m-l,p-u,c-y).normalize(); +b[5].setComponents(f+e,m+l,p+u,c+y).normalize();return this},intersectsObject:function(a){var b=a.geometry;null===b.boundingSphere&&b.computeBoundingSphere();sd.copy(b.boundingSphere).applyMatrix4(a.matrixWorld);return this.intersectsSphere(sd)},intersectsSprite:function(a){sd.center.set(0,0,0);sd.radius=.7071067811865476;sd.applyMatrix4(a.matrixWorld);return this.intersectsSphere(sd)},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(a){for(var b=this.planes,c=0;6>c;c++){var d=b[c];Df.x=0d.distanceToPoint(Df))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}});var S={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif",alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif", +alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif",aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif", +aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif",begin_vertex:"vec3 transformed = vec3( position );",beginnormal_vertex:"vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif",bsdfs:"vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif", +bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif", +clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif", +clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif", +color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == - 1.0;\n}", +cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif", +defaultnormal_vertex:"vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\ttransformedNormal = mat3( instanceMatrix ) * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = normalMatrix * objectTangent;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif", +displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif", +encodings_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",encodings_pars_fragment:"\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}", +envmap_fragment:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\t\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif", +envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif", +envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, roughness );\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif", +envmap_vertex:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) { \n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif", +fog_vertex:"#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif", +gradientmap_pars_fragment:"#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif", +lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_vertex:"vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif", +lights_pars_begin:"uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif", +lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)", +lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = saturate( clearcoat );\tmaterial.clearcoatRoughness = clamp( clearcoatRoughness, 0.04, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif", +lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}", +lights_fragment_begin:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec3( pointLight.shadow, directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec3( spotLight.shadow, directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec3( directionalLight.shadow, directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif", +lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif", +lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif", +logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif", +map_fragment:"#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",map_particle_fragment:"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif", +map_particle_pars_fragment:"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif", +morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif", +morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif", +normal_fragment_begin:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;", +normal_fragment_maps:"#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, normalScale, normalMap );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif", +normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec2 normalScale, in sampler2D normalMap ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy *= normalScale;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tbool frontFacing = dot( cross( S, T ), N ) > 0.0;\n\t\t\tmapN.xy *= ( float( frontFacing ) * 2.0 - 1.0 );\n\t\t#else\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif", +clearcoat_normal_fragment_begin:"#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif",clearcoat_normal_fragment_maps:"#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, clearcoatNormal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = clearcoatNormalScale * mapN.xy;\n\t\tclearcoatNormal = normalize( vTBN * mapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatNormalScale, clearcoatNormalMap );\n\t#endif\n#endif", +clearcoat_normalmap_pars_fragment:"#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif",packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 encodeHalfRGBA ( vec2 v ) {\n\tvec4 encoded = vec4( 0.0 );\n\tconst vec2 offset = vec2( 1.0 / 255.0, 0.0 );\n\tencoded.xy = vec2( v.x, fract( v.x * 255.0 ) );\n\tencoded.xy = encoded.xy - ( encoded.yy * offset );\n\tencoded.zw = vec2( v.y, fract( v.y * 255.0 ) );\n\tencoded.zw = encoded.zw - ( encoded.ww * offset );\n\treturn encoded;\n}\nvec2 decodeHalfRGBA( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}", +premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif", +roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn decodeHalfRGBA( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = ( floor( uv * size - 0.5 ) + 0.5 ) * texelSize;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif", +shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif", +shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif", +shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= all( bvec2( directionalLight.shadow, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= all( bvec2( spotLight.shadow, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= all( bvec2( pointLight.shadow, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}", +skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif", +skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif", +specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}", +uv_pars_fragment:"#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif",uv_vertex:"#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif", +uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif",background_frag:"uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}", +background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}", +cube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}", +depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +distanceRGBA_frag:"#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}", +distanceRGBA_vert:"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}", +equirect_frag:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}", +equirect_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}",linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}", +meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshbasic_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshlambert_frag:"uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshlambert_vert:"#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshmatcap_frag:"#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshmatcap_vert:"#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}", +meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshphysical_frag:"#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSPARENCY\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSPARENCY\n\tuniform float transparency;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSPARENCY\n\t\tdiffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshphysical_vert:"#define STANDARD\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}", +normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}", +normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}", +points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +points_vert:"uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}", +shadow_frag:"uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}",shadow_vert:"#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}", +sprite_vert:"uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"}, +L={common:{diffuse:{value:new J(15658734)},opacity:{value:1},map:{value:null},uvTransform:{value:new Z},alphaMap:{value:null}},specularmap:{specularMap:{value:null}},envmap:{envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},refractionRatio:{value:.98},maxMipLevel:{value:0}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1}},emissivemap:{emissiveMap:{value:null}},bumpmap:{bumpMap:{value:null},bumpScale:{value:1}},normalmap:{normalMap:{value:null}, +normalScale:{value:new B(1,1)}},displacementmap:{displacementMap:{value:null},displacementScale:{value:1},displacementBias:{value:0}},roughnessmap:{roughnessMap:{value:null}},metalnessmap:{metalnessMap:{value:null}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:2.5E-4},fogNear:{value:1},fogFar:{value:2E3},fogColor:{value:new J(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{},shadow:{},shadowBias:{}, +shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},spotShadowMap:{value:[]},spotShadowMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}}, +pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}}},points:{diffuse:{value:new J(15658734)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},uvTransform:{value:new Z}},sprite:{diffuse:{value:new J(15658734)},opacity:{value:1},center:{value:new B(.5,.5)},rotation:{value:0},map:{value:null},alphaMap:{value:null}, +uvTransform:{value:new Z}}},cb={basic:{uniforms:ua([L.common,L.specularmap,L.envmap,L.aomap,L.lightmap,L.fog]),vertexShader:S.meshbasic_vert,fragmentShader:S.meshbasic_frag},lambert:{uniforms:ua([L.common,L.specularmap,L.envmap,L.aomap,L.lightmap,L.emissivemap,L.fog,L.lights,{emissive:{value:new J(0)}}]),vertexShader:S.meshlambert_vert,fragmentShader:S.meshlambert_frag},phong:{uniforms:ua([L.common,L.specularmap,L.envmap,L.aomap,L.lightmap,L.emissivemap,L.bumpmap,L.normalmap,L.displacementmap,L.gradientmap, +L.fog,L.lights,{emissive:{value:new J(0)},specular:{value:new J(1118481)},shininess:{value:30}}]),vertexShader:S.meshphong_vert,fragmentShader:S.meshphong_frag},standard:{uniforms:ua([L.common,L.envmap,L.aomap,L.lightmap,L.emissivemap,L.bumpmap,L.normalmap,L.displacementmap,L.roughnessmap,L.metalnessmap,L.fog,L.lights,{emissive:{value:new J(0)},roughness:{value:.5},metalness:{value:.5},envMapIntensity:{value:1}}]),vertexShader:S.meshphysical_vert,fragmentShader:S.meshphysical_frag},matcap:{uniforms:ua([L.common, +L.bumpmap,L.normalmap,L.displacementmap,L.fog,{matcap:{value:null}}]),vertexShader:S.meshmatcap_vert,fragmentShader:S.meshmatcap_frag},points:{uniforms:ua([L.points,L.fog]),vertexShader:S.points_vert,fragmentShader:S.points_frag},dashed:{uniforms:ua([L.common,L.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:S.linedashed_vert,fragmentShader:S.linedashed_frag},depth:{uniforms:ua([L.common,L.displacementmap]),vertexShader:S.depth_vert,fragmentShader:S.depth_frag},normal:{uniforms:ua([L.common, +L.bumpmap,L.normalmap,L.displacementmap,{opacity:{value:1}}]),vertexShader:S.normal_vert,fragmentShader:S.normal_frag},sprite:{uniforms:ua([L.sprite,L.fog]),vertexShader:S.sprite_vert,fragmentShader:S.sprite_frag},background:{uniforms:{uvTransform:{value:new Z},t2D:{value:null}},vertexShader:S.background_vert,fragmentShader:S.background_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:S.cube_vert,fragmentShader:S.cube_frag},equirect:{uniforms:{tEquirect:{value:null}}, +vertexShader:S.equirect_vert,fragmentShader:S.equirect_frag},distanceRGBA:{uniforms:ua([L.common,L.displacementmap,{referencePosition:{value:new n},nearDistance:{value:1},farDistance:{value:1E3}}]),vertexShader:S.distanceRGBA_vert,fragmentShader:S.distanceRGBA_frag},shadow:{uniforms:ua([L.lights,L.fog,{color:{value:new J(0)},opacity:{value:1}}]),vertexShader:S.shadow_vert,fragmentShader:S.shadow_frag}};cb.physical={uniforms:ua([cb.standard.uniforms,{transparency:{value:0},clearcoat:{value:0},clearcoatRoughness:{value:0}, +sheen:{value:new J(0)},clearcoatNormalScale:{value:new B(1,1)},clearcoatNormalMap:{value:null}}]),vertexShader:S.meshphysical_vert,fragmentShader:S.meshphysical_frag};Ed.prototype=Object.create(G.prototype);Ed.prototype.constructor=Ed;Zb.prototype=Object.create(D.prototype);Zb.prototype.constructor=Zb;nb.prototype=Object.create(Y.prototype);nb.prototype.constructor=nb;nb.prototype.isCubeTexture=!0;Object.defineProperty(nb.prototype,"images",{get:function(){return this.image},set:function(a){this.image= +a}});Cc.prototype=Object.create(Y.prototype);Cc.prototype.constructor=Cc;Cc.prototype.isDataTexture2DArray=!0;Dc.prototype=Object.create(Y.prototype);Dc.prototype.constructor=Dc;Dc.prototype.isDataTexture3D=!0;var uh=new Y,rj=new Cc,tj=new Dc,vh=new nb,oh=[],qh=[],th=new Float32Array(16),sh=new Float32Array(9),rh=new Float32Array(4);wh.prototype.updateCache=function(a){var b=this.cache;a instanceof Float32Array&&b.length!==a.length&&(this.cache=new Float32Array(a.length));Ha(b,a)};xh.prototype.setValue= +function(a,b,c){for(var d=this.seq,e=0,f=d.length;e!==f;++e){var g=d[e];g.setValue(a,b[g.id],c)}};var bg=/([\w\d_]+)(\])?(\[|\.)?/g;Cb.prototype.setValue=function(a,b,c,d){b=this.map[b];void 0!==b&&b.setValue(a,c,d)};Cb.prototype.setOptional=function(a,b,c){b=b[c];void 0!==b&&this.setValue(a,c,b)};Cb.upload=function(a,b,c,d){for(var e=0,f=b.length;e!==f;++e){var g=b[e],h=c[g.id];!1!==h.needsUpdate&&g.setValue(a,h.value,d)}};Cb.seqWithValue=function(a,b){for(var c=[],d=0,e=a.length;d!==e;++d){var f= +a[d];f.id in b&&c.push(f)}return c};var Yj=0,dg=/^[ \t]*#include +<([\w\d./]+)>/gm,Fh=/#pragma unroll_loop[\s]+?for \( int i = (\d+); i < (\d+); i \+\+ \) \{([\s\S]+?)(?=\})\}/g,hk=0;Db.prototype=Object.create(O.prototype);Db.prototype.constructor=Db;Db.prototype.isMeshDepthMaterial=!0;Db.prototype.copy=function(a){O.prototype.copy.call(this,a);this.depthPacking=a.depthPacking;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap; +this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;return this};Eb.prototype=Object.create(O.prototype);Eb.prototype.constructor=Eb;Eb.prototype.isMeshDistanceMaterial=!0;Eb.prototype.copy=function(a){O.prototype.copy.call(this,a);this.referencePosition.copy(a.referencePosition);this.nearDistance=a.nearDistance;this.farDistance=a.farDistance;this.skinning=a.skinning;this.morphTargets=a.morphTargets; +this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;return this};fg.prototype=Object.assign(Object.create(Ba.prototype),{constructor:fg,isWebGLMultiviewRenderTarget:!0,copy:function(a){Ba.prototype.copy.call(this,a);this.numViews=a.numViews;return this},setNumViews:function(a){this.numViews!==a&&(this.numViews=a,this.dispose());return this}});Gc.prototype=Object.assign(Object.create(E.prototype), +{constructor:Gc,isGroup:!0});Jd.prototype=Object.assign(Object.create(U.prototype),{constructor:Jd,isArrayCamera:!0});var Mh=new n,Nh=new n;Object.assign(gg.prototype,Aa.prototype);Object.assign(Oh.prototype,Aa.prototype);Object.assign(Le.prototype,{isFogExp2:!0,clone:function(){return new Le(this.color,this.density)},toJSON:function(){return{type:"FogExp2",color:this.color.getHex(),density:this.density}}});Object.assign(Me.prototype,{isFog:!0,clone:function(){return new Me(this.color,this.near,this.far)}, +toJSON:function(){return{type:"Fog",color:this.color.getHex(),near:this.near,far:this.far}}});Object.defineProperty(pb.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(pb.prototype,{isInterleavedBuffer:!0,onUploadCallback:function(){},setUsage:function(a){this.usage=a;return this},copy:function(a){this.array=new a.array.constructor(a.array);this.count=a.count;this.stride=a.stride;this.usage=a.usage;return this},copyAt:function(a,b,c){a*=this.stride;c*=b.stride;for(var d= +0,e=this.stride;da.far||b.push({distance:e,point:ze.clone(),uv:ba.getUV(ze,Ef,Ae,Ff,vi,$g,wi,new B),face:null,object:this})},clone:function(){return(new this.constructor(this.material)).copy(this)}, +copy:function(a){E.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});var Gf=new n,xi=new n;Nd.prototype=Object.assign(Object.create(E.prototype),{constructor:Nd,isLOD:!0,copy:function(a){E.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b=b[c].distance)b[c-1].object.visible=!1,b[c].object.visible=!0;else break;for(;cc||(h.applyMatrix4(this.matrixWorld),u=a.ray.origin.distanceTo(h),ua.far||b.push({distance:u,point:e.clone().applyMatrix4(this.matrixWorld),index:d,face:null,faceIndex:null,object:this}))}}else for(d=0,q=k.length/3-1;dc||(h.applyMatrix4(this.matrixWorld),u=a.ray.origin.distanceTo(h),ua.far||b.push({distance:u,point:e.clone().applyMatrix4(this.matrixWorld), +index:d,face:null,faceIndex:null,object:this}))}else if(d.isGeometry)for(f=d.vertices,g=f.length,d=0;dc||(h.applyMatrix4(this.matrixWorld),u=a.ray.origin.distanceTo(h),ua.far||b.push({distance:u,point:e.clone().applyMatrix4(this.matrixWorld),index:d,face:null,faceIndex:null,object:this}))}},clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});var If=new n,Jf=new n;X.prototype=Object.assign(Object.create(ra.prototype), +{constructor:X,isLineSegments:!0,computeLineDistances:function(){var a=this.geometry;if(a.isBufferGeometry)if(null===a.index){for(var b=a.attributes.position,c=[],d=0,e=b.count;d= +a.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}});Kc.prototype=Object.create(Y.prototype);Kc.prototype.constructor=Kc;Kc.prototype.isCompressedTexture=!0;Pd.prototype=Object.create(Y.prototype);Pd.prototype.constructor=Pd;Pd.prototype.isCanvasTexture=!0;Qd.prototype=Object.create(Y.prototype);Qd.prototype.constructor=Qd;Qd.prototype.isDepthTexture=!0;Lc.prototype=Object.create(D.prototype);Lc.prototype.constructor=Lc;Rd.prototype=Object.create(G.prototype);Rd.prototype.constructor=Rd;Mc.prototype=Object.create(D.prototype); +Mc.prototype.constructor=Mc;Sd.prototype=Object.create(G.prototype);Sd.prototype.constructor=Sd;Ea.prototype=Object.create(D.prototype);Ea.prototype.constructor=Ea;Td.prototype=Object.create(G.prototype);Td.prototype.constructor=Td;Nc.prototype=Object.create(Ea.prototype);Nc.prototype.constructor=Nc;Ud.prototype=Object.create(G.prototype);Ud.prototype.constructor=Ud;ac.prototype=Object.create(Ea.prototype);ac.prototype.constructor=ac;Vd.prototype=Object.create(G.prototype);Vd.prototype.constructor= +Vd;Oc.prototype=Object.create(Ea.prototype);Oc.prototype.constructor=Oc;Wd.prototype=Object.create(G.prototype);Wd.prototype.constructor=Wd;Pc.prototype=Object.create(Ea.prototype);Pc.prototype.constructor=Pc;Xd.prototype=Object.create(G.prototype);Xd.prototype.constructor=Xd;bc.prototype=Object.create(D.prototype);bc.prototype.constructor=bc;bc.prototype.toJSON=function(){var a=D.prototype.toJSON.call(this);a.path=this.parameters.path.toJSON();return a};Yd.prototype=Object.create(G.prototype);Yd.prototype.constructor= +Yd;Qc.prototype=Object.create(D.prototype);Qc.prototype.constructor=Qc;Zd.prototype=Object.create(G.prototype);Zd.prototype.constructor=Zd;Rc.prototype=Object.create(D.prototype);Rc.prototype.constructor=Rc;var Ek={triangulate:function(a,b,c){c=c||2;var d=b&&b.length,e=d?b[0]*c:a.length,f=Rh(a,0,e,c,!0),g=[];if(!f||f.next===f.prev)return g;var h;if(d){var l=c;d=[];var m;var k=0;for(m=b.length;k80*c){var p=h=a[0];var t=d=a[1];for(l=c;lh&&(h=k),b>d&&(d=b);h=Math.max(h-p,d-t);h=0!==h?1/h:0}be(f,g,c,p,t,h);return g}},qb={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;eqb.area(a)},triangulateShape:function(a,b){var c=[],d=[],e=[];Vh(a);Wh(c,a);var f=a.length;b.forEach(Vh); +for(a=0;aMath.abs(g-l)?[new B(a,1-c),new B(h,1-d),new B(k,1-e),new B(q,1-b)]:[new B(g,1-c),new B(l,1-d),new B(n,1-e),new B(u,1-b)]}};de.prototype=Object.create(G.prototype); +de.prototype.constructor=de;Tc.prototype=Object.create(db.prototype);Tc.prototype.constructor=Tc;ee.prototype=Object.create(G.prototype);ee.prototype.constructor=ee;Hb.prototype=Object.create(D.prototype);Hb.prototype.constructor=Hb;fe.prototype=Object.create(G.prototype);fe.prototype.constructor=fe;Uc.prototype=Object.create(D.prototype);Uc.prototype.constructor=Uc;ge.prototype=Object.create(G.prototype);ge.prototype.constructor=ge;Vc.prototype=Object.create(D.prototype);Vc.prototype.constructor= +Vc;ec.prototype=Object.create(G.prototype);ec.prototype.constructor=ec;ec.prototype.toJSON=function(){var a=G.prototype.toJSON.call(this);return Yh(this.parameters.shapes,a)};fc.prototype=Object.create(D.prototype);fc.prototype.constructor=fc;fc.prototype.toJSON=function(){var a=D.prototype.toJSON.call(this);return Yh(this.parameters.shapes,a)};Wc.prototype=Object.create(D.prototype);Wc.prototype.constructor=Wc;gc.prototype=Object.create(G.prototype);gc.prototype.constructor=gc;rb.prototype=Object.create(D.prototype); +rb.prototype.constructor=rb;he.prototype=Object.create(gc.prototype);he.prototype.constructor=he;ie.prototype=Object.create(rb.prototype);ie.prototype.constructor=ie;je.prototype=Object.create(G.prototype);je.prototype.constructor=je;Xc.prototype=Object.create(D.prototype);Xc.prototype.constructor=Xc;var ja=Object.freeze({__proto__:null,WireframeGeometry:Lc,ParametricGeometry:Rd,ParametricBufferGeometry:Mc,TetrahedronGeometry:Td,TetrahedronBufferGeometry:Nc,OctahedronGeometry:Ud,OctahedronBufferGeometry:ac, +IcosahedronGeometry:Vd,IcosahedronBufferGeometry:Oc,DodecahedronGeometry:Wd,DodecahedronBufferGeometry:Pc,PolyhedronGeometry:Sd,PolyhedronBufferGeometry:Ea,TubeGeometry:Xd,TubeBufferGeometry:bc,TorusKnotGeometry:Yd,TorusKnotBufferGeometry:Qc,TorusGeometry:Zd,TorusBufferGeometry:Rc,TextGeometry:de,TextBufferGeometry:Tc,SphereGeometry:ee,SphereBufferGeometry:Hb,RingGeometry:fe,RingBufferGeometry:Uc,PlaneGeometry:Ed,PlaneBufferGeometry:Zb,LatheGeometry:ge,LatheBufferGeometry:Vc,ShapeGeometry:ec,ShapeBufferGeometry:fc, +ExtrudeGeometry:dc,ExtrudeBufferGeometry:db,EdgesGeometry:Wc,ConeGeometry:he,ConeBufferGeometry:ie,CylinderGeometry:gc,CylinderBufferGeometry:rb,CircleGeometry:je,CircleBufferGeometry:Xc,BoxGeometry:Zg,BoxBufferGeometry:Fd});hc.prototype=Object.create(O.prototype);hc.prototype.constructor=hc;hc.prototype.isShadowMaterial=!0;hc.prototype.copy=function(a){O.prototype.copy.call(this,a);this.color.copy(a.color);return this};Yc.prototype=Object.create(va.prototype);Yc.prototype.constructor=Yc;Yc.prototype.isRawShaderMaterial= +!0;eb.prototype=Object.create(O.prototype);eb.prototype.constructor=eb;eb.prototype.isMeshStandardMaterial=!0;eb.prototype.copy=function(a){O.prototype.copy.call(this,a);this.defines={STANDARD:""};this.color.copy(a.color);this.roughness=a.roughness;this.metalness=a.metalness;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity; +this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.roughnessMap=a.roughnessMap;this.metalnessMap=a.metalnessMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth= +a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};ic.prototype=Object.create(eb.prototype);ic.prototype.constructor=ic;ic.prototype.isMeshPhysicalMaterial=!0;ic.prototype.copy=function(a){eb.prototype.copy.call(this,a);this.defines={STANDARD:"",PHYSICAL:""};this.reflectivity=a.reflectivity;this.clearcoat=a.clearcoat;this.clearcoatRoughness= +a.clearcoatRoughness;this.sheen=a.sheen?(this.sheen||new J).copy(a.sheen):null;this.clearcoatNormalMap=a.clearcoatNormalMap;this.clearcoatNormalScale.copy(a.clearcoatNormalScale);this.transparency=a.transparency;return this};Ra.prototype=Object.create(O.prototype);Ra.prototype.constructor=Ra;Ra.prototype.isMeshPhongMaterial=!0;Ra.prototype.copy=function(a){O.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap= +a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap= +a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};jc.prototype=Object.create(Ra.prototype);jc.prototype.constructor=jc;jc.prototype.isMeshToonMaterial= +!0;jc.prototype.copy=function(a){Ra.prototype.copy.call(this,a);this.gradientMap=a.gradientMap;return this};kc.prototype=Object.create(O.prototype);kc.prototype.constructor=kc;kc.prototype.isMeshNormalMaterial=!0;kc.prototype.copy=function(a){O.prototype.copy.call(this,a);this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale; +this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};lc.prototype=Object.create(O.prototype);lc.prototype.constructor=lc;lc.prototype.isMeshLambertMaterial=!0;lc.prototype.copy=function(a){O.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap= +a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning; +this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};mc.prototype=Object.create(O.prototype);mc.prototype.constructor=mc;mc.prototype.isMeshMatcapMaterial=!0;mc.prototype.copy=function(a){O.prototype.copy.call(this,a);this.defines={MATCAP:""};this.color.copy(a.color);this.matcap=a.matcap;this.map=a.map;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap; +this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.alphaMap=a.alphaMap;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};nc.prototype=Object.create(R.prototype);nc.prototype.constructor=nc;nc.prototype.isLineDashedMaterial=!0;nc.prototype.copy=function(a){R.prototype.copy.call(this,a);this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize=a.gapSize;return this};var Fk=Object.freeze({__proto__:null,ShadowMaterial:hc, +SpriteMaterial:Gb,RawShaderMaterial:Yc,ShaderMaterial:va,PointsMaterial:Qa,MeshPhysicalMaterial:ic,MeshStandardMaterial:eb,MeshPhongMaterial:Ra,MeshToonMaterial:jc,MeshNormalMaterial:kc,MeshLambertMaterial:lc,MeshDepthMaterial:Db,MeshDistanceMaterial:Eb,MeshBasicMaterial:Ga,MeshMatcapMaterial:mc,LineDashedMaterial:nc,LineBasicMaterial:R,Material:O}),ta={arraySlice:function(a,b,c){return ta.isTypedArray(a)?new a.constructor(a.subarray(b,void 0!==c?c:a.length)):a.slice(b,c)},convertArray:function(a, +b,c){return!a||!c&&a.constructor===b?a:"number"===typeof b.BYTES_PER_ELEMENT?new b(a):Array.prototype.slice.call(a)},isTypedArray:function(a){return ArrayBuffer.isView(a)&&!(a instanceof DataView)},getKeyframeOrder:function(a){for(var b=a.length,c=Array(b),d=0;d!==b;++d)c[d]=d;c.sort(function(b,c){return a[b]-a[c]});return c},sortedArray:function(a,b,c){for(var d=a.length,e=new a.constructor(d),f=0,g=0;g!==d;++f)for(var h=c[f]*b,l=0;l!==b;++l)e[g++]=a[h+l];return e},flattenJSON:function(a,b,c,d){for(var e= +1,f=a[0];void 0!==f&&void 0===f[d];)f=a[e++];if(void 0!==f){var g=f[d];if(void 0!==g)if(Array.isArray(g)){do g=f[d],void 0!==g&&(b.push(f.time),c.push.apply(c,g)),f=a[e++];while(void 0!==f)}else if(void 0!==g.toArray){do g=f[d],void 0!==g&&(b.push(f.time),g.toArray(c,c.length)),f=a[e++];while(void 0!==f)}else{do g=f[d],void 0!==g&&(b.push(f.time),c.push(g)),f=a[e++];while(void 0!==f)}}},subclip:function(a,b,c,d,e){e=e||30;a=a.clone();a.name=b;var f=[];for(b=0;b=d))for(l.push(g.times[n]),q=0;qa.tracks[b].times[0]&&(c=a.tracks[b].times[0]);for(b=0;b=e)break a;else{f=b[1];a=e)break b}d=c;c=0}}for(;c>>1,ab;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),a=this.getValueSize(),this.times=ta.arraySlice(c,e,f),this.values=ta.arraySlice(this.values,e*a,f*a);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),a=!1);var c=this.times; +b=this.values;var d=c.length;0===d&&(console.error("THREE.KeyframeTrack: Track is empty.",this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if("number"===typeof g&&isNaN(g)){console.error("THREE.KeyframeTrack: Time is not a valid number.",this,f,g);a=!1;break}if(null!==e&&e>g){console.error("THREE.KeyframeTrack: Out of order keys.",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&ta.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("THREE.KeyframeTrack: Value is not a valid number.", +this,f,d);a=!1;break}return a},optimize:function(){for(var a=this.times,b=this.values,c=this.getValueSize(),d=2302===this.getInterpolation(),e=1,f=a.length-1,g=1;gg)e=a+1;else if(0b&&(b=0);1Number.EPSILON&&(g.normalize(),c=Math.acos(P.clamp(d[l-1].dot(d[l]),-1,1)),e[l].applyMatrix4(h.makeRotationAxis(g,c))),f[l].crossVectors(d[l],e[l]);if(!0===b)for(c=Math.acos(P.clamp(e[0].dot(e[a]),-1,1)),c/=a,0d;)d+=c;for(;d>c;)d-=c;de&&(e=1);1E-4>d&&(d=e);1E-4>l&&(l=e);ah.initNonuniformCatmullRom(f.x,g.x,h.x,c.x,d,e,l);bh.initNonuniformCatmullRom(f.y,g.y,h.y,c.y,d,e,l);ch.initNonuniformCatmullRom(f.z,g.z,h.z,c.z,d,e,l)}else"catmullrom"===this.curveType&&(ah.initCatmullRom(f.x,g.x,h.x,c.x,this.tension),bh.initCatmullRom(f.y,g.y,h.y,c.y,this.tension),ch.initCatmullRom(f.z,g.z,h.z,c.z,this.tension));b.set(ah.calc(a), +bh.calc(a),ch.calc(a));return b};ma.prototype.copy=function(a){C.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;bc.length-2?c.length-1:a+1];c=c[a>c.length-3?c.length-1:a+2];b.set($h(d,e.x,f.x,g.x,c.x),$h(d,e.y,f.y,g.y,c.y));return b};Va.prototype.copy=function(a){C.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;b=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null},getLength:function(){var a= +this.getCurveLengths();return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=!0;this.cacheLengths=null;this.getCurveLengths()},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;cNumber.EPSILON){if(0>k&&(g=b[f],l=-l,h=b[e],k=-k),!(a.yh.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e=k*(a.x-g.x)-l*(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=qb.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);b=[];if(1===f.length){var g=f[0];var h=new Ib;h.curves=g.curves;b.push(h);return b}var l=!e(f[0].getPoints());l=a?!l:l;h=[];var k=[],n=[],q=0;k[q]=void 0;n[q]=[];for(var u=0,p=f.length;ub;b++)this.coefficients[b].copy(a[b]);return this},zero:function(){for(var a=0;9>a;a++)this.coefficients[a].set(0,0,0);return this},getAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.282095); +b.addScale(e[1],.488603*d);b.addScale(e[2],.488603*a);b.addScale(e[3],.488603*c);b.addScale(e[4],1.092548*c*d);b.addScale(e[5],1.092548*d*a);b.addScale(e[6],.315392*(3*a*a-1));b.addScale(e[7],1.092548*c*a);b.addScale(e[8],.546274*(c*c-d*d));return b},getIrradianceAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.886227);b.addScale(e[1],1.023328*d);b.addScale(e[2],1.023328*a);b.addScale(e[3],1.023328*c);b.addScale(e[4],.858086*c*d);b.addScale(e[5],.858086* +d*a);b.addScale(e[6],.743125*a*a-.247708);b.addScale(e[7],.858086*c*a);b.addScale(e[8],.429043*(c*c-d*d));return b},add:function(a){for(var b=0;9>b;b++)this.coefficients[b].add(a.coefficients[b]);return this},scale:function(a){for(var b=0;9>b;b++)this.coefficients[b].multiplyScalar(a);return this},lerp:function(a,b){for(var c=0;9>c;c++)this.coefficients[c].lerp(a.coefficients[c],b);return this},equals:function(a){for(var b=0;9>b;b++)if(!this.coefficients[b].equals(a.coefficients[b]))return!1;return!0}, +copy:function(a){return this.set(a.coefficients)},clone:function(){return(new this.constructor).copy(this)},fromArray:function(a,b){void 0===b&&(b=0);for(var c=this.coefficients,d=0;9>d;d++)c[d].fromArray(a,b+3*d);return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);for(var c=this.coefficients,d=0;9>d;d++)c[d].toArray(a,b+3*d);return a}});Object.assign(of,{getBasisAt:function(a,b){var c=a.x,d=a.y;a=a.z;b[0]=.282095;b[1]=.488603*d;b[2]=.488603*a;b[3]=.488603*c;b[4]=1.092548*c*d; +b[5]=1.092548*d*a;b[6]=.315392*(3*a*a-1);b[7]=1.092548*c*a;b[8]=.546274*(c*c-d*d)}});Xa.prototype=Object.assign(Object.create(T.prototype),{constructor:Xa,isLightProbe:!0,copy:function(a){T.prototype.copy.call(this,a);this.sh.copy(a.sh);this.intensity=a.intensity;return this},toJSON:function(a){return T.prototype.toJSON.call(this,a)}});xg.prototype=Object.assign(Object.create(Xa.prototype),{constructor:xg,isHemisphereLightProbe:!0,copy:function(a){Xa.prototype.copy.call(this,a);return this},toJSON:function(a){return Xa.prototype.toJSON.call(this, +a)}});yg.prototype=Object.assign(Object.create(Xa.prototype),{constructor:yg,isAmbientLightProbe:!0,copy:function(a){Xa.prototype.copy.call(this,a);return this},toJSON:function(a){return Xa.prototype.toJSON.call(this,a)}});var Fi=new Q,Gi=new Q;Object.assign(ai.prototype,{update:function(a){var b=this._cache;if(b.focus!==a.focus||b.fov!==a.fov||b.aspect!==a.aspect*this.aspect||b.near!==a.near||b.far!==a.far||b.zoom!==a.zoom||b.eyeSep!==this.eyeSep){b.focus=a.focus;b.fov=a.fov;b.aspect=a.aspect*this.aspect; +b.near=a.near;b.far=a.far;b.zoom=a.zoom;b.eyeSep=this.eyeSep;var c=a.projectionMatrix.clone(),d=b.eyeSep/2,e=d*b.near/b.focus,f=b.near*Math.tan(P.DEG2RAD*b.fov*.5)/b.zoom;Gi.elements[12]=-d;Fi.elements[12]=d;d=-f*b.aspect+e;var g=f*b.aspect+e;c.elements[0]=2*b.near/(g-d);c.elements[8]=(g+d)/(g-d);this.cameraL.projectionMatrix.copy(c);d=-f*b.aspect-e;g=f*b.aspect-e;c.elements[0]=2*b.near/(g-d);c.elements[8]=(g+d)/(g-d);this.cameraR.projectionMatrix.copy(c)}this.cameraL.matrixWorld.copy(a.matrixWorld).multiply(Gi); +this.cameraR.matrixWorld.copy(a.matrixWorld).multiply(Fi)}});Object.assign(zg.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now();this.elapsedTime=0;this.running=!0},stop:function(){this.getElapsedTime();this.autoStart=this.running=!1},getElapsedTime:function(){this.getDelta();return this.elapsedTime},getDelta:function(){var a=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance? +Date:performance).now();a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});var tc=new n,Hi=new wa,Hk=new n,uc=new n;Ag.prototype=Object.assign(Object.create(E.prototype),{constructor:Ag,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination),this.filter=null);return this},getFilter:function(){return this.filter},setFilter:function(a){null!== +this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination);this.filter=a;this.gain.connect(this.filter);this.filter.connect(this.context.destination);return this},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(a){this.gain.gain.setTargetAtTime(a,this.context.currentTime,.01);return this},updateMatrixWorld:function(a){E.prototype.updateMatrixWorld.call(this,a);a=this.context.listener; +var b=this.up;this.timeDelta=this._clock.getDelta();this.matrixWorld.decompose(tc,Hi,Hk);uc.set(0,0,-1).applyQuaternion(Hi);if(a.positionX){var c=this.context.currentTime+this.timeDelta;a.positionX.linearRampToValueAtTime(tc.x,c);a.positionY.linearRampToValueAtTime(tc.y,c);a.positionZ.linearRampToValueAtTime(tc.z,c);a.forwardX.linearRampToValueAtTime(uc.x,c);a.forwardY.linearRampToValueAtTime(uc.y,c);a.forwardZ.linearRampToValueAtTime(uc.z,c);a.upX.linearRampToValueAtTime(b.x,c);a.upY.linearRampToValueAtTime(b.y, +c);a.upZ.linearRampToValueAtTime(b.z,c)}else a.setPosition(tc.x,tc.y,tc.z),a.setOrientation(uc.x,uc.y,uc.z,b.x,b.y,b.z)}});cd.prototype=Object.assign(Object.create(E.prototype),{constructor:cd,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=!1;this.sourceType="audioNode";this.source=a;this.connect();return this},setMediaElementSource:function(a){this.hasPlaybackControl=!1;this.sourceType="mediaNode";this.source=this.context.createMediaElementSource(a);this.connect(); +return this},setMediaStreamSource:function(a){this.hasPlaybackControl=!1;this.sourceType="mediaStreamNode";this.source=this.context.createMediaStreamSource(a);this.connect();return this},setBuffer:function(a){this.buffer=a;this.sourceType="buffer";this.autoplay&&this.play();return this},play:function(a){void 0===a&&(a=0);if(!0===this.isPlaying)console.warn("THREE.Audio: Audio is already playing.");else if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control."); +else return this._startedAt=this.context.currentTime+a,a=this.context.createBufferSource(),a.buffer=this.buffer,a.loop=this.loop,a.loopStart=this.loopStart,a.loopEnd=this.loopEnd,a.onended=this.onEnded.bind(this),a.start(this._startedAt,this._pausedAt+this.offset,this.duration),this.isPlaying=!0,this.source=a,this.setDetune(this.detune),this.setPlaybackRate(this.playbackRate),this.connect()},pause:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control."); +else return!0===this.isPlaying&&(this._pausedAt=(this.context.currentTime-this._startedAt)*this.playbackRate,this.source.stop(),this.source.onended=null,this.isPlaying=!1),this},stop:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this._pausedAt=0,this.source.stop(),this.source.onended=null,this.isPlaying=!1,this},connect:function(){if(0d&&this._mixBufferRegion(c,a,3*b,1-d,b);d=b;for(var f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a,c);for(var d=b;d!==c;++d)a[d]= +a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a,b,c,d,e){if(.5<=d)for(d=0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d){wa.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d,e){for(var f=1-d,g=0;g!==e;++g){var h=b+g;a[h]=a[h]*f+a[c+g]*d}}});var Jk=/[\[\]\.:\/]/g,Kk="[^"+"\\[\\]\\.:\\/".replace("\\.","")+"]",Lk=/((?:WC+[\/:])*)/.source.replace("WC","[^\\[\\]\\.:\\/]"),Mk=/(WCOD+)?/.source.replace("WCOD",Kk), +Nk=/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC","[^\\[\\]\\.:\\/]"),Ok=/\.(WC+)(?:\[(.+)\])?/.source.replace("WC","[^\\[\\]\\.:\\/]"),Pk=new RegExp("^"+Lk+Mk+Nk+Ok+"$"),Qk=["material","materials","bones"];Object.assign(bi.prototype,{getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a,b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a= +this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].unbind()}});Object.assign(ya,{Composite:bi,create:function(a,b,c){return a&&a.isAnimationObjectGroup?new ya.Composite(a,b,c):new ya(a,b,c)},sanitizeNodeName:function(a){return a.replace(/\s/g,"_").replace(Jk,"")},parseTrackName:function(a){var b=Pk.exec(a);if(!b)throw Error("PropertyBinding: Cannot parse trackName: "+ +a);b={nodeName:b[2],objectName:b[3],objectIndex:b[4],propertyName:b[5],propertyIndex:b[6]};var c=b.nodeName&&b.nodeName.lastIndexOf(".");if(void 0!==c&&-1!==c){var d=b.nodeName.substring(c+1);-1!==Qk.indexOf(d)&&(b.nodeName=b.nodeName.substring(0,c),b.objectName=d)}if(null===b.propertyName||0===b.propertyName.length)throw Error("PropertyBinding: can not parse propertyName from trackName: "+a);return b},findNode:function(a,b){if(!b||""===b||"root"===b||"."===b||-1===b||b===a.name||b===a.uuid)return a; +if(a.skeleton){var c=a.skeleton.getBoneByName(b);if(void 0!==c)return c}if(a.children){var d=function(a){for(var c=0;c=b){var n=b++,q=a[n];c[q.uuid]=m;a[m]=q;c[k]=n;a[n]=h;h=0;for(k=e;h!==k;++h){q=d[h];var u=q[m];q[m]=q[n];q[n]=u}}}this.nCachedObjects_=b},uncache:function(){for(var a=this._objects,b=a.length,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,h=arguments.length;g!==h;++g){var k= +arguments[g].uuid,m=d[k];if(void 0!==m)if(delete d[k],mb||0===c)return;this._startTime=null;b*=c}b*=this._updateTimeScale(a);c=this._updateTime(b);a=this._updateWeight(a);if(0c.parameterPositions[1]&&(this.stopFading(),0===d&&(this.enabled=!1))}}return this._effectiveWeight=b},_updateTimeScale:function(a){var b=0;if(!this.paused){b=this.timeScale;var c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0];b*=d;a>c.parameterPositions[1]&&(this.stopWarping(),0===b?this.paused=!0:this.timeScale=b)}}return this._effectiveTimeScale=b},_updateTime:function(a){var b=this.time+a,c=this._clip.duration,d=this.loop,e=this._loopCount,f=2202===d;if(0===a)return-1=== +e?b:f&&1===(e&1)?c-b:b;if(2200===d)a:{if(-1===e&&(this._loopCount=0,this._setEndings(!0,!0,!1)),b>=c)b=c;else if(0>b)b=0;else{this.time=b;break a}this.clampWhenFinished?this.paused=!0:this.enabled=!1;this.time=b;this._mixer.dispatchEvent({type:"finished",action:this,direction:0>a?-1:1})}else{-1===e&&(0<=a?(e=0,this._setEndings(!0,0===this.repetitions,f)):this._setEndings(0===this.repetitions,!0,f));if(b>=c||0>b){d=Math.floor(b/c);b-=c*d;e+=Math.abs(d);var g=this.repetitions-e;0>=g?(this.clampWhenFinished? +this.paused=!0:this.enabled=!1,this.time=b=0a,this._setEndings(a,!a,f)):this._setEndings(!1,!1,f),this._loopCount=e,this.time=b,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:d}))}else this.time=b;if(f&&1===(e&1))return c-b}return b},_setEndings:function(a,b,c){var d=this._interpolantSettings;c?(d.endingStart=2401,d.endingEnd=2401):(d.endingStart=a?this.zeroSlopeAtStart?2401:2400:2402,d.endingEnd= +b?this.zeroSlopeAtEnd?2401:2400:2402)},_scheduleFading:function(a,b,c){var d=this._mixer,e=d.time,f=this._weightInterpolant;null===f&&(this._weightInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions;f=f.sampleValues;d[0]=e;f[0]=b;d[1]=e+a;f[1]=c;return this}});Fg.prototype=Object.assign(Object.create(Aa.prototype),{constructor:Fg,_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings;a=a._interpolants;var g=c.uuid,h=this._bindingsByRootAndName, +k=h[g];void 0===k&&(k={},h[g]=k);for(h=0;h!==e;++h){var m=d[h],n=m.name,q=k[n];if(void 0===q){q=f[h];if(void 0!==q){null===q._cacheIndex&&(++q.referenceCount,this._addInactiveBinding(q,g,n));continue}q=new Eg(ya.create(c,n,b&&b._propertyBindings[h].binding.parsedPath),m.ValueTypeName,m.getValueSize());++q.referenceCount;this._addInactiveBinding(q,g,n)}f[h]=q;a[h].resultBuffer=q.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid, +c=a._clip.uuid,d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];0===e.useCount++&&(this._lendBinding(e),e.saveOriginalState())}this._lendAction(a)}},_deactivateAction:function(a){if(this._isActiveAction(a)){for(var b=a._propertyBindings,c=0,d=b.length;c!==d;++c){var e=b[c];0===--e.useCount&&(e.restoreOriginalState(),this._takeBackBinding(e))}this._takeBackAction(a)}},_initMemoryManager:function(){this._actions= +[];this._nActiveActions=0;this._actionsByClip={};this._bindings=[];this._nActiveBindings=0;this._bindingsByRootAndName={};this._controlInterpolants=[];this._nActiveControlInterpolants=0;var a=this;this.stats={actions:{get total(){return a._actions.length},get inUse(){return a._nActiveActions}},bindings:{get total(){return a._bindings.length},get inUse(){return a._nActiveBindings}},controlInterpolants:{get total(){return a._controlInterpolants.length},get inUse(){return a._nActiveControlInterpolants}}}}, +_isActiveAction:function(a){a=a._cacheIndex;return null!==a&&athis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box2: .getParameter() target is now required"),b=new B);return b.set((a.x-this.min.x)/(this.max.x-this.min.x), +(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y?!1:!0},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box2: .clampPoint() target is now required"),b=new B);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return Ji.copy(a).clamp(this.min,this.max).sub(a).length()},intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min); +this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});var Ki=new n,Nf=new n;Object.assign(Jg.prototype,{set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},getCenter:function(a){void 0===a&&(console.warn("THREE.Line3: .getCenter() target is now required"), +a=new n);return a.addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){void 0===a&&(console.warn("THREE.Line3: .delta() target is now required"),a=new n);return a.subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a,b){void 0===b&&(console.warn("THREE.Line3: .at() target is now required"),b=new n);return this.delta(b).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(a, +b){Ki.subVectors(a,this.start);Nf.subVectors(this.end,this.start);a=Nf.dot(Nf);a=Nf.dot(Ki)/a;b&&(a=P.clamp(a,0,1));return a},closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);void 0===c&&(console.warn("THREE.Line3: .closestPointToPoint() target is now required"),c=new n);return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a);this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}}); +pe.prototype=Object.create(E.prototype);pe.prototype.constructor=pe;pe.prototype.isImmediateRenderObject=!0;var lb=new n,Ab=new n,gh=new Z,Rk=["a","b","c"];qe.prototype=Object.create(X.prototype);qe.prototype.constructor=qe;qe.prototype.update=function(){this.object.updateMatrixWorld(!0);gh.getNormalMatrix(this.object.matrixWorld);var a=this.object.matrixWorld,b=this.geometry.attributes.position,c=this.object.geometry;if(c&&c.isGeometry)for(var d=c.vertices,e=c.faces,f=c=0,g=e.length;fMath.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side= +0>b?1:0;this.lookAt(this.plane.normal);E.prototype.updateMatrixWorld.call(this,a)};var Ri=new n,tf,Kg;ub.prototype=Object.create(E.prototype);ub.prototype.constructor=ub;ub.prototype.setDirection=function(a){.99999a.y?this.quaternion.set(1,0,0,0):(Ri.set(a.z,0,-a.x).normalize(),this.quaternion.setFromAxisAngle(Ri,Math.acos(a.y)))};ub.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(1E-4,a-b),1);this.line.updateMatrix(); +this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};ub.prototype.setColor=function(a){this.line.material.color.set(a);this.cone.material.color.set(a)};ub.prototype.copy=function(a){E.prototype.copy.call(this,a,!1);this.line.copy(a.line);this.cone.copy(a.cone);return this};ub.prototype.clone=function(){return(new this.constructor).copy(this)};ve.prototype=Object.create(X.prototype);ve.prototype.constructor=ve;C.create=function(a,b){console.log("THREE.Curve.create() has been deprecated"); +a.prototype=Object.create(C.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};Object.assign(sb.prototype,{createPointsGeometry:function(a){console.warn("THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");a=this.getPoints(a);return this.createGeometry(a)},createSpacedPointsGeometry:function(a){console.warn("THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead."); +a=this.getSpacedPoints(a);return this.createGeometry(a)},createGeometry:function(a){console.warn("THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");for(var b=new G,c=0,d=a.length;c 0) { + this._tweensAddedDuringUpdate = {}; + for (var i = 0; i < tweenIds.length; i++) { + var tween = this._tweens[tweenIds[i]]; + var autoStart = !preserve; + if (tween && tween.update(time, autoStart) === false && !preserve) { + delete this._tweens[tweenIds[i]]; + } + } + tweenIds = Object.keys(this._tweensAddedDuringUpdate); + } + return true; + }; + return Group; + }()); + + /** + * + */ + var Interpolation = { + Linear: function (v, k) { + var m = v.length - 1; + var f = m * k; + var i = Math.floor(f); + var fn = Interpolation.Utils.Linear; + if (k < 0) { + return fn(v[0], v[1], f); + } + if (k > 1) { + return fn(v[m], v[m - 1], m - f); + } + return fn(v[i], v[i + 1 > m ? m : i + 1], f - i); + }, + Bezier: function (v, k) { + var b = 0; + var n = v.length - 1; + var pw = Math.pow; + var bn = Interpolation.Utils.Bernstein; + for (var i = 0; i <= n; i++) { + b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i); + } + return b; + }, + CatmullRom: function (v, k) { + var m = v.length - 1; + var f = m * k; + var i = Math.floor(f); + var fn = Interpolation.Utils.CatmullRom; + if (v[0] === v[m]) { + if (k < 0) { + i = Math.floor((f = m * (1 + k))); + } + return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i); + } + else { + if (k < 0) { + return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]); + } + if (k > 1) { + return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]); + } + return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i); + } + }, + Utils: { + Linear: function (p0, p1, t) { + return (p1 - p0) * t + p0; + }, + Bernstein: function (n, i) { + var fc = Interpolation.Utils.Factorial; + return fc(n) / fc(i) / fc(n - i); + }, + Factorial: (function () { + var a = [1]; + return function (n) { + var s = 1; + if (a[n]) { + return a[n]; + } + for (var i = n; i > 1; i--) { + s *= i; + } + a[n] = s; + return s; + }; + })(), + CatmullRom: 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; + }, + }, + }; + + /** + * Utils + */ + var Sequence = /** @class */ (function () { + function Sequence() { + } + Sequence.nextId = function () { + return Sequence._nextId++; + }; + Sequence._nextId = 0; + return Sequence; + }()); + + var mainGroup = new Group(); + + /** + * Tween.js - Licensed under the MIT license + * https://github.com/tweenjs/tween.js + * ---------------------------------------------- + * + * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors. + * Thank you all, you're awesome! + */ + var Tween = /** @class */ (function () { + function Tween(_object, _group) { + if (_group === void 0) { _group = mainGroup; } + this._object = _object; + this._group = _group; + this._isPaused = false; + this._pauseStart = 0; + this._valuesStart = {}; + this._valuesEnd = {}; + this._valuesStartRepeat = {}; + this._duration = 1000; + this._initialRepeat = 0; + this._repeat = 0; + this._yoyo = false; + this._isPlaying = false; + this._reversed = false; + this._delayTime = 0; + this._startTime = 0; + this._easingFunction = Easing.Linear.None; + this._interpolationFunction = Interpolation.Linear; + this._chainedTweens = []; + this._onStartCallbackFired = false; + this._id = Sequence.nextId(); + this._isChainStopped = false; + this._goToEnd = false; + } + Tween.prototype.getId = function () { + return this._id; + }; + Tween.prototype.isPlaying = function () { + return this._isPlaying; + }; + Tween.prototype.isPaused = function () { + return this._isPaused; + }; + Tween.prototype.to = function (properties, duration) { + // TODO? restore this, then update the 07_dynamic_to example to set fox + // tween's to on each update. That way the behavior is opt-in (there's + // currently no opt-out). + // for (const prop in properties) this._valuesEnd[prop] = properties[prop] + this._valuesEnd = Object.create(properties); + if (duration !== undefined) { + this._duration = duration; + } + return this; + }; + Tween.prototype.duration = function (d) { + this._duration = d; + return this; + }; + Tween.prototype.start = function (time) { + if (this._isPlaying) { + return this; + } + // eslint-disable-next-line + this._group && this._group.add(this); + this._repeat = this._initialRepeat; + if (this._reversed) { + // If we were reversed (f.e. using the yoyo feature) then we need to + // flip the tween direction back to forward. + this._reversed = false; + for (var property in this._valuesStartRepeat) { + this._swapEndStartRepeatValues(property); + this._valuesStart[property] = this._valuesStartRepeat[property]; + } + } + this._isPlaying = true; + this._isPaused = false; + this._onStartCallbackFired = false; + this._isChainStopped = false; + this._startTime = time !== undefined ? (typeof time === 'string' ? now$1() + parseFloat(time) : time) : now$1(); + this._startTime += this._delayTime; + this._setupProperties(this._object, this._valuesStart, this._valuesEnd, this._valuesStartRepeat); + return this; + }; + Tween.prototype._setupProperties = function (_object, _valuesStart, _valuesEnd, _valuesStartRepeat) { + for (var property in _valuesEnd) { + var startValue = _object[property]; + var startValueIsArray = Array.isArray(startValue); + var propType = startValueIsArray ? 'array' : typeof startValue; + var isInterpolationList = !startValueIsArray && Array.isArray(_valuesEnd[property]); + // If `to()` specifies a property that doesn't exist in the source object, + // we should not set that property in the object + if (propType === 'undefined' || propType === 'function') { + continue; + } + // Check if an Array was provided as property value + if (isInterpolationList) { + var endValues = _valuesEnd[property]; + if (endValues.length === 0) { + continue; + } + // handle an array of relative values + endValues = endValues.map(this._handleRelativeValue.bind(this, startValue)); + // Create a local copy of the Array with the start value at the front + _valuesEnd[property] = [startValue].concat(endValues); + } + // handle the deepness of the values + if ((propType === 'object' || startValueIsArray) && startValue && !isInterpolationList) { + _valuesStart[property] = startValueIsArray ? [] : {}; + // eslint-disable-next-line + for (var prop in startValue) { + // eslint-disable-next-line + // @ts-ignore FIXME? + _valuesStart[property][prop] = startValue[prop]; + } + _valuesStartRepeat[property] = startValueIsArray ? [] : {}; // TODO? repeat nested values? And yoyo? And array values? + // eslint-disable-next-line + // @ts-ignore FIXME? + this._setupProperties(startValue, _valuesStart[property], _valuesEnd[property], _valuesStartRepeat[property]); + } + else { + // Save the starting value, but only once. + if (typeof _valuesStart[property] === 'undefined') { + _valuesStart[property] = startValue; + } + if (!startValueIsArray) { + // eslint-disable-next-line + // @ts-ignore FIXME? + _valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings + } + if (isInterpolationList) { + // eslint-disable-next-line + // @ts-ignore FIXME? + _valuesStartRepeat[property] = _valuesEnd[property].slice().reverse(); + } + else { + _valuesStartRepeat[property] = _valuesStart[property] || 0; + } + } + } + }; + Tween.prototype.stop = function () { + if (!this._isChainStopped) { + this._isChainStopped = true; + this.stopChainedTweens(); + } + if (!this._isPlaying) { + return this; + } + // eslint-disable-next-line + this._group && this._group.remove(this); + this._isPlaying = false; + this._isPaused = false; + if (this._onStopCallback) { + this._onStopCallback(this._object); + } + return this; + }; + Tween.prototype.end = function () { + this._goToEnd = true; + this.update(Infinity); + return this; + }; + Tween.prototype.pause = function (time) { + if (time === void 0) { time = now$1(); } + if (this._isPaused || !this._isPlaying) { + return this; + } + this._isPaused = true; + this._pauseStart = time; + // eslint-disable-next-line + this._group && this._group.remove(this); + return this; + }; + Tween.prototype.resume = function (time) { + if (time === void 0) { time = now$1(); } + if (!this._isPaused || !this._isPlaying) { + return this; + } + this._isPaused = false; + this._startTime += time - this._pauseStart; + this._pauseStart = 0; + // eslint-disable-next-line + this._group && this._group.add(this); + return this; + }; + Tween.prototype.stopChainedTweens = function () { + for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { + this._chainedTweens[i].stop(); + } + return this; + }; + Tween.prototype.group = function (group) { + this._group = group; + return this; + }; + Tween.prototype.delay = function (amount) { + this._delayTime = amount; + return this; + }; + Tween.prototype.repeat = function (times) { + this._initialRepeat = times; + this._repeat = times; + return this; + }; + Tween.prototype.repeatDelay = function (amount) { + this._repeatDelayTime = amount; + return this; + }; + Tween.prototype.yoyo = function (yoyo) { + this._yoyo = yoyo; + return this; + }; + Tween.prototype.easing = function (easingFunction) { + this._easingFunction = easingFunction; + return this; + }; + Tween.prototype.interpolation = function (interpolationFunction) { + this._interpolationFunction = interpolationFunction; + return this; + }; + Tween.prototype.chain = function () { + var tweens = []; + for (var _i = 0; _i < arguments.length; _i++) { + tweens[_i] = arguments[_i]; + } + this._chainedTweens = tweens; + return this; + }; + Tween.prototype.onStart = function (callback) { + this._onStartCallback = callback; + return this; + }; + Tween.prototype.onUpdate = function (callback) { + this._onUpdateCallback = callback; + return this; + }; + Tween.prototype.onRepeat = function (callback) { + this._onRepeatCallback = callback; + return this; + }; + Tween.prototype.onComplete = function (callback) { + this._onCompleteCallback = callback; + return this; + }; + Tween.prototype.onStop = function (callback) { + this._onStopCallback = callback; + return this; + }; + /** + * @returns true if the tween is still playing after the update, false + * otherwise (calling update on a paused tween still returns true because + * it is still playing, just paused). + */ + Tween.prototype.update = function (time, autoStart) { + if (time === void 0) { time = now$1(); } + if (autoStart === void 0) { autoStart = true; } + if (this._isPaused) + return true; + var property; + var elapsed; + var endTime = this._startTime + this._duration; + if (!this._goToEnd && !this._isPlaying) { + if (time > endTime) + return false; + if (autoStart) + this.start(time); + } + this._goToEnd = false; + if (time < this._startTime) { + return true; + } + if (this._onStartCallbackFired === false) { + if (this._onStartCallback) { + this._onStartCallback(this._object); + } + this._onStartCallbackFired = true; + } + elapsed = (time - this._startTime) / this._duration; + elapsed = this._duration === 0 || elapsed > 1 ? 1 : elapsed; + var value = this._easingFunction(elapsed); + // properties transformations + this._updateProperties(this._object, this._valuesStart, this._valuesEnd, value); + if (this._onUpdateCallback) { + this._onUpdateCallback(this._object, elapsed); + } + if (elapsed === 1) { + if (this._repeat > 0) { + if (isFinite(this._repeat)) { + this._repeat--; + } + // Reassign starting values, restart by making startTime = now + for (property in this._valuesStartRepeat) { + if (!this._yoyo && typeof this._valuesEnd[property] === 'string') { + this._valuesStartRepeat[property] = + // eslint-disable-next-line + // @ts-ignore FIXME? + this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property]); + } + if (this._yoyo) { + this._swapEndStartRepeatValues(property); + } + this._valuesStart[property] = this._valuesStartRepeat[property]; + } + if (this._yoyo) { + this._reversed = !this._reversed; + } + if (this._repeatDelayTime !== undefined) { + this._startTime = time + this._repeatDelayTime; + } + else { + this._startTime = time + this._delayTime; + } + if (this._onRepeatCallback) { + this._onRepeatCallback(this._object); + } + return true; + } + else { + if (this._onCompleteCallback) { + this._onCompleteCallback(this._object); + } + for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { + // Make the chained tweens start exactly at the time they should, + // even if the `update()` method was called way past the duration of the tween + this._chainedTweens[i].start(this._startTime + this._duration); + } + this._isPlaying = false; + return false; + } + } + return true; + }; + Tween.prototype._updateProperties = function (_object, _valuesStart, _valuesEnd, value) { + for (var property in _valuesEnd) { + // Don't update properties that do not exist in the source object + if (_valuesStart[property] === undefined) { + continue; + } + var start = _valuesStart[property] || 0; + var end = _valuesEnd[property]; + var startIsArray = Array.isArray(_object[property]); + var endIsArray = Array.isArray(end); + var isInterpolationList = !startIsArray && endIsArray; + if (isInterpolationList) { + _object[property] = this._interpolationFunction(end, value); + } + else if (typeof end === 'object' && end) { + // eslint-disable-next-line + // @ts-ignore FIXME? + this._updateProperties(_object[property], start, end, value); + } + else { + // Parses relative end values with start as base (e.g.: +10, -3) + end = this._handleRelativeValue(start, end); + // Protect against non numeric properties. + if (typeof end === 'number') { + // eslint-disable-next-line + // @ts-ignore FIXME? + _object[property] = start + (end - start) * value; + } + } + } + }; + Tween.prototype._handleRelativeValue = function (start, end) { + if (typeof end !== 'string') { + return end; + } + if (end.charAt(0) === '+' || end.charAt(0) === '-') { + return start + parseFloat(end); + } + else { + return parseFloat(end); + } + }; + Tween.prototype._swapEndStartRepeatValues = function (property) { + var tmp = this._valuesStartRepeat[property]; + var endValue = this._valuesEnd[property]; + if (typeof endValue === 'string') { + this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(endValue); + } + else { + this._valuesStartRepeat[property] = this._valuesEnd[property]; + } + this._valuesEnd[property] = tmp; + }; + return Tween; + }()); + + var VERSION = '18.6.4'; + + /** + * Tween.js - Licensed under the MIT license + * https://github.com/tweenjs/tween.js + * ---------------------------------------------- + * + * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors. + * Thank you all, you're awesome! + */ + var nextId = Sequence.nextId; + /** + * Controlling groups of tweens + * + * Using the TWEEN singleton to manage your tweens can cause issues in large apps with many components. + * In these cases, you may want to create your own smaller groups of tweens. + */ + var TWEEN = mainGroup; + // This is the best way to export things in a way that's compatible with both ES + // Modules and CommonJS, without build hacks, and so as not to break the + // existing API. + // https://github.com/rollup/rollup/issues/1961#issuecomment-423037881 + var getAll = TWEEN.getAll.bind(TWEEN); + var removeAll = TWEEN.removeAll.bind(TWEEN); + var add = TWEEN.add.bind(TWEEN); + var remove = TWEEN.remove.bind(TWEEN); + var update = TWEEN.update.bind(TWEEN); + var exports$1 = { + Easing: Easing, + Group: Group, + Interpolation: Interpolation, + now: now$1, + Sequence: Sequence, + nextId: nextId, + Tween: Tween, + VERSION: VERSION, + getAll: getAll, + removeAll: removeAll, + add: add, + remove: remove, + update: update, + }; + + exports.Easing = Easing; + exports.Group = Group; + exports.Interpolation = Interpolation; + exports.Sequence = Sequence; + exports.Tween = Tween; + exports.VERSION = VERSION; + exports.add = add; + exports.default = exports$1; + exports.getAll = getAll; + exports.nextId = nextId; + exports.now = now$1; + exports.remove = remove; + exports.removeAll = removeAll; + exports.update = update; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/source/replace_images.txt b/source/replace_images.txt index 29a7931a..f9146964 100644 --- a/source/replace_images.txt +++ b/source/replace_images.txt @@ -7,10 +7,10 @@ .. Examples .. |Kibiji| image:: ./images/examples/kibiji.png - :target: https://qgis2threejs-examples-27.netlify.com/kibiji/ + :target: /examples/27/kibiji/ .. |Mt_Fuji| image:: ./images/examples/mt_fuji.png - :target: https://qgis2threejs-examples-24.netlify.com/mt_fuji.html + :target: /examples/24/mt_fuji.html .. |ForestBasins| image:: ./images/examples/forest_basins.png - :target: https://qgis2threejs-examples-24.netlify.com/forest_basins.html + :target: /examples/24/forest_basins.html