Last active
May 28, 2023 04:55
-
-
Save 1wheel/ab8f9c6af32724d8303972395a9cb074 to your computer and use it in GitHub Desktop.
hello-point-cloud
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @license | |
* Lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE | |
*/ | |
;(function(){function n(n,t){return n.set(t[0],t[1]),n}function t(n,t){return n.add(t),n}function r(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function e(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u<i;){var o=n[u];t(e,o,r(o),n)}return e}function u(n,t){for(var r=-1,e=null==n?0:n.length;++r<e&&false!==t(n[r],r,n););return n}function i(n,t){for(var r=null==n?0:n.length;r--&&false!==t(n[r],r,n);); | |
return n}function o(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(!t(n[r],r,n))return false;return true}function f(n,t){for(var r=-1,e=null==n?0:n.length,u=0,i=[];++r<e;){var o=n[r];t(o,r,n)&&(i[u++]=o)}return i}function c(n,t){return!(null==n||!n.length)&&-1<d(n,t,0)}function a(n,t,r){for(var e=-1,u=null==n?0:n.length;++e<u;)if(r(t,n[e]))return true;return false}function l(n,t){for(var r=-1,e=null==n?0:n.length,u=Array(e);++r<e;)u[r]=t(n[r],r,n);return u}function s(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r]; | |
return n}function h(n,t,r,e){var u=-1,i=null==n?0:n.length;for(e&&i&&(r=n[++u]);++u<i;)r=t(r,n[u],u,n);return r}function p(n,t,r,e){var u=null==n?0:n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r}function _(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(t(n[r],r,n))return true;return false}function v(n,t,r){var e;return r(n,function(n,r,u){if(t(n,r,u))return e=r,false}),e}function g(n,t,r,e){var u=n.length;for(r+=e?1:-1;e?r--:++r<u;)if(t(n[r],r,n))return r;return-1}function d(n,t,r){if(t===t)n:{ | |
--r;for(var e=n.length;++r<e;)if(n[r]===t){n=r;break n}n=-1}else n=g(n,b,r);return n}function y(n,t,r,e){--r;for(var u=n.length;++r<u;)if(e(n[r],t))return r;return-1}function b(n){return n!==n}function x(n,t){var r=null==n?0:n.length;return r?k(n,t)/r:P}function j(n){return function(t){return null==t?F:t[n]}}function w(n){return function(t){return null==n?F:n[t]}}function m(n,t,r,e,u){return u(n,function(n,u,i){r=e?(e=false,n):t(r,n,u,i)}),r}function A(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c; | |
return n}function k(n,t){for(var r,e=-1,u=n.length;++e<u;){var i=t(n[e]);i!==F&&(r=r===F?i:r+i)}return r}function E(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function O(n,t){return l(t,function(t){return[t,n[t]]})}function S(n){return function(t){return n(t)}}function I(n,t){return l(t,function(t){return n[t]})}function R(n,t){return n.has(t)}function z(n,t){for(var r=-1,e=n.length;++r<e&&-1<d(t,n[r],0););return r}function W(n,t){for(var r=n.length;r--&&-1<d(t,n[r],0););return r}function B(n){ | |
return"\\"+Tn[n]}function L(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n]}),r}function U(n,t){return function(r){return n(t(r))}}function C(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r];o!==t&&"__lodash_placeholder__"!==o||(n[r]="__lodash_placeholder__",i[u++]=r)}return i}function D(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=n}),r}function M(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function T(n){if(Bn.test(n)){ | |
for(var t=zn.lastIndex=0;zn.test(n);)++t;n=t}else n=tt(n);return n}function $(n){return Bn.test(n)?n.match(zn)||[]:n.split("")}var F,N=1/0,P=NaN,Z=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],q=/\b__p\+='';/g,V=/\b(__p\+=)''\+/g,K=/(__e\(.*?\)|\b__t\))\+'';/g,G=/&(?:amp|lt|gt|quot|#39);/g,H=/[&<>"']/g,J=RegExp(G.source),Y=RegExp(H.source),Q=/<%-([\s\S]+?)%>/g,X=/<%([\s\S]+?)%>/g,nn=/<%=([\s\S]+?)%>/g,tn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,rn=/^\w*$/,en=/^\./,un=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,on=/[\\^$.*+?()[\]{}|]/g,fn=RegExp(on.source),cn=/^\s+|\s+$/g,an=/^\s+/,ln=/\s+$/,sn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,hn=/\{\n\/\* \[wrapped with (.+)\] \*/,pn=/,? & /,_n=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,vn=/\\(\\)?/g,gn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,dn=/\w*$/,yn=/^[-+]0x[0-9a-f]+$/i,bn=/^0b[01]+$/i,xn=/^\[object .+?Constructor\]$/,jn=/^0o[0-7]+$/i,wn=/^(?:0|[1-9]\d*)$/,mn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,An=/($^)/,kn=/['\n\r\u2028\u2029\\]/g,En="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",On="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+En,Sn="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",In=RegExp("['\u2019]","g"),Rn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),zn=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+Sn+En,"g"),Wn=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)|\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)|\\d+",On].join("|"),"g"),Bn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),Ln=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Un="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Cn={}; | |
Cn["[object Float32Array]"]=Cn["[object Float64Array]"]=Cn["[object Int8Array]"]=Cn["[object Int16Array]"]=Cn["[object Int32Array]"]=Cn["[object Uint8Array]"]=Cn["[object Uint8ClampedArray]"]=Cn["[object Uint16Array]"]=Cn["[object Uint32Array]"]=true,Cn["[object Arguments]"]=Cn["[object Array]"]=Cn["[object ArrayBuffer]"]=Cn["[object Boolean]"]=Cn["[object DataView]"]=Cn["[object Date]"]=Cn["[object Error]"]=Cn["[object Function]"]=Cn["[object Map]"]=Cn["[object Number]"]=Cn["[object Object]"]=Cn["[object RegExp]"]=Cn["[object Set]"]=Cn["[object String]"]=Cn["[object WeakMap]"]=false; | |
var Dn={};Dn["[object Arguments]"]=Dn["[object Array]"]=Dn["[object ArrayBuffer]"]=Dn["[object DataView]"]=Dn["[object Boolean]"]=Dn["[object Date]"]=Dn["[object Float32Array]"]=Dn["[object Float64Array]"]=Dn["[object Int8Array]"]=Dn["[object Int16Array]"]=Dn["[object Int32Array]"]=Dn["[object Map]"]=Dn["[object Number]"]=Dn["[object Object]"]=Dn["[object RegExp]"]=Dn["[object Set]"]=Dn["[object String]"]=Dn["[object Symbol]"]=Dn["[object Uint8Array]"]=Dn["[object Uint8ClampedArray]"]=Dn["[object Uint16Array]"]=Dn["[object Uint32Array]"]=true, | |
Dn["[object Error]"]=Dn["[object Function]"]=Dn["[object WeakMap]"]=false;var Mn,Tn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},$n=parseFloat,Fn=parseInt,Nn=typeof global=="object"&&global&&global.Object===Object&&global,Pn=typeof self=="object"&&self&&self.Object===Object&&self,Zn=Nn||Pn||Function("return this")(),qn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Vn=qn&&typeof module=="object"&&module&&!module.nodeType&&module,Kn=Vn&&Vn.exports===qn,Gn=Kn&&Nn.process; | |
n:{try{Mn=Gn&&Gn.binding&&Gn.binding("util");break n}catch(n){}Mn=void 0}var Hn=Mn&&Mn.isArrayBuffer,Jn=Mn&&Mn.isDate,Yn=Mn&&Mn.isMap,Qn=Mn&&Mn.isRegExp,Xn=Mn&&Mn.isSet,nt=Mn&&Mn.isTypedArray,tt=j("length"),rt=w({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I", | |
"\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C","\u0108":"C","\u010a":"C", | |
"\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i","\u012b":"i","\u012d":"i", | |
"\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r","\u015a":"S","\u015c":"S", | |
"\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij","\u0152":"Oe","\u0153":"oe", | |
"\u0149":"'n","\u017f":"s"}),et=w({"&":"&","<":"<",">":">",'"':""","'":"'"}),ut=w({"&":"&","<":"<",">":">",""":'"',"'":"'"}),it=function w(En){function On(n){if(xu(n)&&!af(n)&&!(n instanceof Mn)){if(n instanceof zn)return n;if(ci.call(n,"__wrapped__"))return Pe(n)}return new zn(n)}function Sn(){}function zn(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=F}function Mn(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1, | |
this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Tn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Nn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Pn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function qn(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new Pn;++t<r;)this.add(n[t])}function Vn(n){ | |
this.size=(this.__data__=new Nn(n)).size}function Gn(n,t){var r,e=af(n),u=!e&&cf(n),i=!e&&!u&&sf(n),o=!e&&!u&&!i&&gf(n),u=(e=e||u||i||o)?E(n.length,ri):[],f=u.length;for(r in n)!t&&!ci.call(n,r)||e&&("length"==r||i&&("offset"==r||"parent"==r)||o&&("buffer"==r||"byteLength"==r||"byteOffset"==r)||Re(r,f))||u.push(r);return u}function tt(n){var t=n.length;return t?n[cr(0,t-1)]:F}function ot(n,t){return Te(Mr(n),gt(t,0,n.length))}function ft(n){return Te(Mr(n))}function ct(n,t,r){(r===F||hu(n[t],r))&&(r!==F||t in n)||_t(n,t,r); | |
}function at(n,t,r){var e=n[t];ci.call(n,t)&&hu(e,r)&&(r!==F||t in n)||_t(n,t,r)}function lt(n,t){for(var r=n.length;r--;)if(hu(n[r][0],t))return r;return-1}function st(n,t,r,e){return oo(n,function(n,u,i){t(e,n,r(n),i)}),e}function ht(n,t){return n&&Tr(t,Lu(t),n)}function pt(n,t){return n&&Tr(t,Uu(t),n)}function _t(n,t,r){"__proto__"==t&&Ei?Ei(n,t,{configurable:true,enumerable:true,value:r,writable:true}):n[t]=r}function vt(n,t){for(var r=-1,e=t.length,u=Hu(e),i=null==n;++r<e;)u[r]=i?F:Wu(n,t[r]);return u; | |
}function gt(n,t,r){return n===n&&(r!==F&&(n=n<=r?n:r),t!==F&&(n=n>=t?n:t)),n}function dt(n,t,r,e,i,o){var f,c=1&t,a=2&t,l=4&t;if(r&&(f=i?r(n,e,i,o):r(n)),f!==F)return f;if(!bu(n))return n;if(e=af(n)){if(f=Ee(n),!c)return Mr(n,f)}else{var s=yo(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(sf(n))return Wr(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Oe(n),!c)return a?Fr(n,pt(f,n)):$r(n,ht(f,n))}else{if(!Dn[s])return i?n:{};f=Se(n,s,dt,c)}}if(o||(o=new Vn), | |
i=o.get(n))return i;o.set(n,f);var a=l?a?ye:de:a?Uu:Lu,p=e?F:a(n);return u(p||n,function(e,u){p&&(u=e,e=n[u]),at(f,u,dt(e,t,r,u,n,o))}),f}function yt(n){var t=Lu(n);return function(r){return bt(r,n,t)}}function bt(n,t,r){var e=r.length;if(null==n)return!e;for(n=ni(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===F&&!(u in n)||!i(o))return false}return true}function xt(n,t,r){if(typeof n!="function")throw new ei("Expected a function");return jo(function(){n.apply(F,r)},t)}function jt(n,t,r,e){var u=-1,i=c,o=true,f=n.length,s=[],h=t.length; | |
if(!f)return s;r&&(t=l(t,S(r))),e?(i=a,o=false):200<=t.length&&(i=R,o=false,t=new qn(t));n:for(;++u<f;){var p=n[u],_=null==r?p:r(p),p=e||0!==p?p:0;if(o&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function wt(n,t){var r=true;return oo(n,function(n,e,u){return r=!!t(n,e,u)}),r}function mt(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===F?o===o&&!Au(o):r(o,f)))var f=o,c=i}return c}function At(n,t){var r=[];return oo(n,function(n,e,u){ | |
t(n,e,u)&&r.push(n)}),r}function kt(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=Ie),u||(u=[]);++i<o;){var f=n[i];0<t&&r(f)?1<t?kt(f,t-1,r,e,u):s(u,f):e||(u[u.length]=f)}return u}function Et(n,t){return n&&co(n,t,Lu)}function Ot(n,t){return n&&ao(n,t,Lu)}function St(n,t){return f(t,function(t){return gu(n[t])})}function It(n,t){t=Rr(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[$e(t[r++])];return r&&r==e?n:F}function Rt(n,t,r){return t=t(n),af(n)?t:s(t,r(n))}function zt(n){if(null==n)n=n===F?"[object Undefined]":"[object Null]";else if(ki&&ki in ni(n)){ | |
var t=ci.call(n,ki),r=n[ki];try{n[ki]=F;var e=true}catch(n){}var u=si.call(n);e&&(t?n[ki]=r:delete n[ki]),n=u}else n=si.call(n);return n}function Wt(n,t){return n>t}function Bt(n,t){return null!=n&&ci.call(n,t)}function Lt(n,t){return null!=n&&t in ni(n)}function Ut(n,t,r){for(var e=r?a:c,u=n[0].length,i=n.length,o=i,f=Hu(i),s=1/0,h=[];o--;){var p=n[o];o&&t&&(p=l(p,S(t))),s=Mi(p.length,s),f[o]=!r&&(t||120<=u&&120<=p.length)?new qn(o&&p):F}var p=n[0],_=-1,v=f[0];n:for(;++_<u&&h.length<s;){var g=p[_],d=t?t(g):g,g=r||0!==g?g:0; | |
if(v?!R(v,d):!e(h,d,r)){for(o=i;--o;){var y=f[o];if(y?!R(y,d):!e(n[o],d,r))continue n}v&&v.push(d),h.push(g)}}return h}function Ct(n,t,r){var e={};return Et(n,function(n,u,i){t(e,r(n),u,i)}),e}function Dt(n,t,e){return t=Rr(t,n),n=2>t.length?n:It(n,vr(t,0,-1)),t=null==n?n:n[$e(Ge(t))],null==t?F:r(t,n,e)}function Mt(n){return xu(n)&&"[object Arguments]"==zt(n)}function Tt(n){return xu(n)&&"[object ArrayBuffer]"==zt(n)}function $t(n){return xu(n)&&"[object Date]"==zt(n)}function Ft(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!xu(n)&&!xu(t))t=n!==n&&t!==t;else n:{ | |
var i=af(n),o=af(t),f=i?"[object Array]":yo(n),c=o?"[object Array]":yo(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&sf(n)){if(!sf(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Vn),t=i||gf(n)?_e(n,t,r,e,Ft,u):ve(n,t,f,r,e,Ft,u);else{if(!(1&r)&&(i=a&&ci.call(n,"__wrapped__"),f=o&&ci.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Vn),t=Ft(n,t,r,e,u);break n}if(c)t:if(u||(u=new Vn), | |
i=1&r,f=de(n),o=f.length,c=de(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:ci.call(t,l))){t=false;break t}}if((c=u.get(n))&&u.get(t))t=c==t;else{c=true,u.set(n,t),u.set(t,n);for(var s=i;++a<o;){var l=f[a],h=n[l],p=t[l];if(e)var _=i?e(p,h,l,t,n,u):e(h,p,l,n,t,u);if(_===F?h!==p&&!Ft(h,p,r,e,u):!_){c=false;break}s||(s="constructor"==l)}c&&!s&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(c=false)), | |
u.delete(n),u.delete(t),t=c}}else t=false;else t=false}}return t}function Nt(n){return xu(n)&&"[object Map]"==yo(n)}function Pt(n,t,r,e){var u=r.length,i=u,o=!e;if(null==n)return!i;for(n=ni(n);u--;){var f=r[u];if(o&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return false}for(;++u<i;){var f=r[u],c=f[0],a=n[c],l=f[1];if(o&&f[2]){if(a===F&&!(c in n))return false}else{if(f=new Vn,e)var s=e(a,l,c,n,t,f);if(s===F?!Ft(l,a,3,e,f):!s)return false}}return true}function Zt(n){return!(!bu(n)||li&&li in n)&&(gu(n)?_i:xn).test(Fe(n))}function qt(n){ | |
return xu(n)&&"[object RegExp]"==zt(n)}function Vt(n){return xu(n)&&"[object Set]"==yo(n)}function Kt(n){return xu(n)&&yu(n.length)&&!!Cn[zt(n)]}function Gt(n){return typeof n=="function"?n:null==n?Nu:typeof n=="object"?af(n)?Xt(n[0],n[1]):Qt(n):Vu(n)}function Ht(n){if(!Le(n))return Ci(n);var t,r=[];for(t in ni(n))ci.call(n,t)&&"constructor"!=t&&r.push(t);return r}function Jt(n,t){return n<t}function Yt(n,t){var r=-1,e=pu(n)?Hu(n.length):[];return oo(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Qt(n){ | |
var t=me(n);return 1==t.length&&t[0][2]?Ue(t[0][0],t[0][1]):function(r){return r===n||Pt(r,n,t)}}function Xt(n,t){return We(n)&&t===t&&!bu(t)?Ue($e(n),t):function(r){var e=Wu(r,n);return e===F&&e===t?Bu(r,n):Ft(t,e,3)}}function nr(n,t,r,e,u){n!==t&&co(t,function(i,o){if(bu(i)){u||(u=new Vn);var f=u,c=n[o],a=t[o],l=f.get(a);if(l)ct(n,o,l);else{var l=e?e(c,a,o+"",n,t,f):F,s=l===F;if(s){var h=af(a),p=!h&&sf(a),_=!h&&!p&&gf(a),l=a;h||p||_?af(c)?l=c:_u(c)?l=Mr(c):p?(s=false,l=Wr(a,true)):_?(s=false,l=Lr(a,true)):l=[]:wu(a)||cf(a)?(l=c, | |
cf(c)?l=Ru(c):(!bu(c)||r&&gu(c))&&(l=Oe(a))):s=false}s&&(f.set(a,l),nr(l,a,r,e,f),f.delete(a)),ct(n,o,l)}}else f=e?e(n[o],i,o+"",n,t,u):F,f===F&&(f=i),ct(n,o,f)},Uu)}function tr(n,t){var r=n.length;if(r)return t+=0>t?r:0,Re(t,r)?n[t]:F}function rr(n,t,r){var e=-1;return t=l(t.length?t:[Nu],S(je())),n=Yt(n,function(n){return{a:l(t,function(t){return t(n)}),b:++e,c:n}}),A(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e<o;){var c=Ur(u[e],i[e]);if(c){e=e>=f?c:c*("desc"==r[e]?-1:1); | |
break n}}e=n.b-t.b}return e})}function er(n,t){return ur(n,t,function(t,r){return Bu(n,r)})}function ur(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=It(n,o);r(f,o)&&pr(i,Rr(o,n),f)}return i}function ir(n){return function(t){return It(t,n)}}function or(n,t,r,e){var u=e?y:d,i=-1,o=t.length,f=n;for(n===t&&(t=Mr(t)),r&&(f=l(n,S(r)));++i<o;)for(var c=0,a=t[i],a=r?r(a):a;-1<(c=u(f,a,c,e));)f!==n&&wi.call(f,c,1),wi.call(n,c,1);return n}function fr(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r]; | |
if(r==e||u!==i){var i=u;Re(u)?wi.call(n,u,1):mr(n,u)}}}function cr(n,t){return n+zi(Fi()*(t-n+1))}function ar(n,t){var r="";if(!n||1>t||9007199254740991<t)return r;do t%2&&(r+=n),(t=zi(t/2))&&(n+=n);while(t);return r}function lr(n,t){return wo(Ce(n,t,Nu),n+"")}function sr(n){return tt(Du(n))}function hr(n,t){var r=Du(n);return Te(r,gt(t,0,r.length))}function pr(n,t,r,e){if(!bu(n))return n;t=Rr(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){var c=$e(t[u]),a=r;if(u!=o){var l=f[c],a=e?e(l,c,f):F; | |
a===F&&(a=bu(l)?l:Re(t[u+1])?[]:{})}at(f,c,a),f=f[c]}return n}function _r(n){return Te(Du(n))}function vr(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Hu(u);++e<u;)r[e]=n[e+t];return r}function gr(n,t){var r;return oo(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function dr(n,t,r){var e=0,u=null==n?e:n.length;if(typeof t=="number"&&t===t&&2147483647>=u){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!Au(o)&&(r?o<=t:o<t)?e=i+1:u=i}return u}return yr(n,t,Nu,r); | |
}function yr(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=Au(t),a=t===F;u<i;){var l=zi((u+i)/2),s=r(n[l]),h=s!==F,p=null===s,_=s===s,v=Au(s);(o?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?s<=t:s<t)?u=l+1:i=l}return Mi(i,4294967294)}function br(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r],f=t?t(o):o;if(!r||!hu(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function xr(n){return typeof n=="number"?n:Au(n)?P:+n}function jr(n){if(typeof n=="string")return n; | |
if(af(n))return l(n,jr)+"";if(Au(n))return uo?uo.call(n):"";var t=n+"";return"0"==t&&1/n==-N?"-0":t}function wr(n,t,r){var e=-1,u=c,i=n.length,o=true,f=[],l=f;if(r)o=false,u=a;else if(200<=i){if(u=t?null:po(n))return D(u);o=false,u=R,l=new qn}else l=t?[]:f;n:for(;++e<i;){var s=n[e],h=t?t(s):s,s=r||0!==s?s:0;if(o&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;t&&l.push(h),f.push(s)}else u(l,h,r)||(l!==f&&l.push(h),f.push(s))}return f}function mr(n,t){return t=Rr(t,n),n=2>t.length?n:It(n,vr(t,0,-1)), | |
null==n||delete n[$e(Ge(t))]}function Ar(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?vr(n,e?0:i,e?i+1:u):vr(n,e?i+1:0,e?u:i)}function kr(n,t){var r=n;return r instanceof Mn&&(r=r.value()),h(t,function(n,t){return t.func.apply(t.thisArg,s([n],t.args))},r)}function Er(n,t,r){var e=n.length;if(2>e)return e?wr(n[0]):[];for(var u=-1,i=Hu(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=jt(i[u]||o,n[f],t,r));return wr(kt(i,1),t,r)}function Or(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;)r(o,n[e],e<i?t[e]:F); | |
return o}function Sr(n){return _u(n)?n:[]}function Ir(n){return typeof n=="function"?n:Nu}function Rr(n,t){return af(n)?n:We(n,t)?[n]:mo(zu(n))}function zr(n,t,r){var e=n.length;return r=r===F?e:r,!t&&r>=e?n:vr(n,t,r)}function Wr(n,t){if(t)return n.slice();var r=n.length,r=yi?yi(r):new n.constructor(r);return n.copy(r),r}function Br(n){var t=new n.constructor(n.byteLength);return new di(t).set(new di(n)),t}function Lr(n,t){return new n.constructor(t?Br(n.buffer):n.buffer,n.byteOffset,n.length)}function Ur(n,t){ | |
if(n!==t){var r=n!==F,e=null===n,u=n===n,i=Au(n),o=t!==F,f=null===t,c=t===t,a=Au(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Cr(n,t,r,e){var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Di(i-o,0),l=Hu(c+a);for(e=!e;++f<c;)l[f]=t[f];for(;++u<o;)(e||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];return l}function Dr(n,t,r,e){var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Di(i-f,0),s=Hu(l+a); | |
for(e=!e;++u<l;)s[u]=n[u];for(l=u;++c<a;)s[l+c]=t[c];for(;++o<f;)(e||u<i)&&(s[l+r[o]]=n[u++]);return s}function Mr(n,t){var r=-1,e=n.length;for(t||(t=Hu(e));++r<e;)t[r]=n[r];return t}function Tr(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):F;c===F&&(c=n[f]),u?_t(r,f,c):at(r,f,c)}return r}function $r(n,t){return Tr(n,vo(n),t)}function Fr(n,t){return Tr(n,go(n),t)}function Nr(n,t){return function(r,u){var i=af(r)?e:st,o=t?t():{};return i(r,n,je(u,2),o); | |
}}function Pr(n){return lr(function(t,r){var e=-1,u=r.length,i=1<u?r[u-1]:F,o=2<u?r[2]:F,i=3<n.length&&typeof i=="function"?(u--,i):F;for(o&&ze(r[0],r[1],o)&&(i=3>u?F:i,u=1),t=ni(t);++e<u;)(o=r[e])&&n(t,o,e,i);return t})}function Zr(n,t){return function(r,e){if(null==r)return r;if(!pu(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=ni(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function qr(n){return function(t,r,e){var u=-1,i=ni(t);e=e(t);for(var o=e.length;o--;){var f=e[n?o:++u];if(false===r(i[f],f,i))break; | |
}return t}}function Vr(n,t,r){function e(){return(this&&this!==Zn&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=1&t,i=Hr(n);return e}function Kr(n){return function(t){t=zu(t);var r=Bn.test(t)?$(t):F,e=r?r[0]:t.charAt(0);return t=r?zr(r,1).join(""):t.slice(1),e[n]()+t}}function Gr(n){return function(t){return h($u(Tu(t).replace(In,"")),n,"")}}function Hr(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3: | |
return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=io(n.prototype),t=n.apply(r,t);return bu(t)?t:r}}function Jr(n,t,e){function u(){for(var o=arguments.length,f=Hu(o),c=o,a=xe(u);c--;)f[c]=arguments[c];return c=3>o&&f[0]!==a&&f[o-1]!==a?[]:C(f,a),o-=c.length,o<e?fe(n,t,Xr,u.placeholder,F,f,c,F,F,e-o):r(this&&this!==Zn&&this instanceof u?i:n,this,f); | |
}var i=Hr(n);return u}function Yr(n){return function(t,r,e){var u=ni(t);if(!pu(t)){var i=je(r,3);t=Lu(t),r=function(n){return i(u[n],n,u)}}return r=n(t,r,e),-1<r?u[i?t[r]:r]:F}}function Qr(n){return ge(function(t){var r=t.length,e=r,u=zn.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if(typeof i!="function")throw new ei("Expected a function");if(u&&!o&&"wrapper"==be(i))var o=new zn([],true)}for(e=o?e:r;++e<r;)var i=t[e],u=be(i),f="wrapper"==u?_o(i):F,o=f&&Be(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?o[be(f[0])].apply(o,f[3]):1==i.length&&Be(i)?o[u]():o.thru(i); | |
return function(){var n=arguments,e=n[0];if(o&&1==n.length&&af(e))return o.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}})}function Xr(n,t,r,e,u,i,o,f,c,a){function l(){for(var d=arguments.length,y=Hu(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=xe(l),b=y.length;for(x=0;b--;)y[b]===j&&++x}if(e&&(y=Cr(y,e,u,_)),i&&(y=Dr(y,i,o,_)),d-=x,_&&d<a)return j=C(y,j),fe(n,t,Xr,l.placeholder,r,y,j,f,c,a-d);if(j=h?r:this,b=p?j[n]:n,d=y.length,f){x=y.length;for(var w=Mi(f.length,x),m=Mr(y);w--;){ | |
var A=f[w];y[w]=Re(A,x)?m[A]:F}}else v&&1<d&&y.reverse();return s&&c<d&&(y.length=c),this&&this!==Zn&&this instanceof l&&(b=g||Hr(b)),b.apply(j,y)}var s=128&t,h=1&t,p=2&t,_=24&t,v=512&t,g=p?F:Hr(n);return l}function ne(n,t){return function(r,e){return Ct(r,n,t(e))}}function te(n,t){return function(r,e){var u;if(r===F&&e===F)return t;if(r!==F&&(u=r),e!==F){if(u===F)return e;typeof r=="string"||typeof e=="string"?(r=jr(r),e=jr(e)):(r=xr(r),e=xr(e)),u=n(r,e)}return u}}function re(n){return ge(function(t){ | |
return t=l(t,S(je())),lr(function(e){var u=this;return n(t,function(n){return r(n,u,e)})})})}function ee(n,t){t=t===F?" ":jr(t);var r=t.length;return 2>r?r?ar(t,n):t:(r=ar(t,Ri(n/T(t))),Bn.test(t)?zr($(r),0,n).join(""):r.slice(0,n))}function ue(n,t,e,u){function i(){for(var t=-1,c=arguments.length,a=-1,l=u.length,s=Hu(l+c),h=this&&this!==Zn&&this instanceof i?f:n;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++t];return r(h,o?e:this,s)}var o=1&t,f=Hr(n);return i}function ie(n){return function(t,r,e){ | |
e&&typeof e!="number"&&ze(t,r,e)&&(r=e=F),t=Eu(t),r===F?(r=t,t=0):r=Eu(r),e=e===F?t<r?1:-1:Eu(e);var u=-1;r=Di(Ri((r-t)/(e||1)),0);for(var i=Hu(r);r--;)i[n?r:++u]=t,t+=e;return i}}function oe(n){return function(t,r){return typeof t=="string"&&typeof r=="string"||(t=Iu(t),r=Iu(r)),n(t,r)}}function fe(n,t,r,e,u,i,o,f,c,a){var l=8&t,s=l?o:F;o=l?F:o;var h=l?i:F;return i=l?F:i,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),u=[n,t,u,h,s,i,o,f,c,a],r=r.apply(F,u),Be(n)&&xo(r,u),r.placeholder=e,De(r,n,t)}function ce(n){ | |
var t=Xu[n];return function(n,r){if(n=Iu(n),r=null==r?0:Mi(Ou(r),292)){var e=(zu(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(zu(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function ae(n){return function(t){var r=yo(t);return"[object Map]"==r?L(t):"[object Set]"==r?M(t):O(t,n(t))}}function le(n,t,r,e,u,i,o,f){var c=2&t;if(!c&&typeof n!="function")throw new ei("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=F),o=o===F?o:Di(Ou(o),0),f=f===F?f:Ou(f),a-=u?u.length:0,64&t){ | |
var l=e,s=u;e=u=F}var h=c?F:_o(n);return i=[n,t,r,e,u,l,s,i,o,f],h&&(r=i[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&i[7].length<=h[8]||384==n&&h[7].length<=h[8]&&8==r,131>t||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Cr(e,r,h[4]):r,i[4]=e?C(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Dr(e,r,h[6]):r,i[6]=e?C(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Mi(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],t=i[1], | |
r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===F?c?0:n.length:Di(i[9]-a,0),!f&&24&t&&(t&=-25),De((h?lo:xo)(t&&1!=t?8==t||16==t?Jr(n,t,f):32!=t&&33!=t||u.length?Xr.apply(F,i):ue(n,t,r,e):Vr(n,t,r),i),n,t)}function se(n,t,r,e){return n===F||hu(n,ii[r])&&!ci.call(e,r)?t:n}function he(n,t,r,e,u,i){return bu(n)&&bu(t)&&(i.set(t,n),nr(n,t,F,he,i),i.delete(t)),n}function pe(n){return wu(n)?F:n}function _e(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;var c=-1,a=true,l=2&r?new qn:F; | |
for(i.set(n,t),i.set(t,n);++c<f;){var s=n[c],h=t[c];if(e)var p=o?e(h,s,c,t,n,i):e(s,h,c,n,t,i);if(p!==F){if(p)continue;a=false;break}if(l){if(!_(t,function(n,t){if(!R(l,t)&&(s===n||u(s,n,r,e,i)))return l.push(t)})){a=false;break}}else if(s!==h&&!u(s,h,r,e,i)){a=false;break}}return i.delete(n),i.delete(t),a}function ve(n,t,r,e,u,i,o){switch(r){case"[object DataView]":if(n.byteLength!=t.byteLength||n.byteOffset!=t.byteOffset)break;n=n.buffer,t=t.buffer;case"[object ArrayBuffer]":if(n.byteLength!=t.byteLength||!i(new di(n),new di(t)))break; | |
return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return hu(+n,+t);case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object RegExp]":case"[object String]":return n==t+"";case"[object Map]":var f=L;case"[object Set]":if(f||(f=D),n.size!=t.size&&!(1&e))break;return(r=o.get(n))?r==t:(e|=2,o.set(n,t),t=_e(f(n),f(t),e,u,i,o),o.delete(n),t);case"[object Symbol]":if(eo)return eo.call(n)==eo.call(t)}return false}function ge(n){return wo(Ce(n,F,Ve),n+"")}function de(n){ | |
return Rt(n,Lu,vo)}function ye(n){return Rt(n,Uu,go)}function be(n){for(var t=n.name+"",r=Ji[t],e=ci.call(Ji,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function xe(n){return(ci.call(On,"placeholder")?On:n).placeholder}function je(){var n=On.iteratee||Pu,n=n===Pu?Gt:n;return arguments.length?n(arguments[0],arguments[1]):n}function we(n,t){var r=n.__data__,e=typeof t;return("string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t)?r[typeof t=="string"?"string":"hash"]:r.map; | |
}function me(n){for(var t=Lu(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,u===u&&!bu(u)]}return t}function Ae(n,t){var r=null==n?F:n[t];return Zt(r)?r:F}function ke(n,t,r){t=Rr(t,n);for(var e=-1,u=t.length,i=false;++e<u;){var o=$e(t[e]);if(!(i=null!=n&&r(n,o)))break;n=n[o]}return i||++e!=u?i:(u=null==n?0:n.length,!!u&&yu(u)&&Re(o,u)&&(af(n)||cf(n)))}function Ee(n){var t=n.length,r=n.constructor(t);return t&&"string"==typeof n[0]&&ci.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Oe(n){ | |
return typeof n.constructor!="function"||Le(n)?{}:io(bi(n))}function Se(r,e,u,i){var o=r.constructor;switch(e){case"[object ArrayBuffer]":return Br(r);case"[object Boolean]":case"[object Date]":return new o(+r);case"[object DataView]":return e=i?Br(r.buffer):r.buffer,new r.constructor(e,r.byteOffset,r.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]": | |
case"[object Uint16Array]":case"[object Uint32Array]":return Lr(r,i);case"[object Map]":return e=i?u(L(r),1):L(r),h(e,n,new r.constructor);case"[object Number]":case"[object String]":return new o(r);case"[object RegExp]":return e=new r.constructor(r.source,dn.exec(r)),e.lastIndex=r.lastIndex,e;case"[object Set]":return e=i?u(D(r),1):D(r),h(e,t,new r.constructor);case"[object Symbol]":return eo?ni(eo.call(r)):{}}}function Ie(n){return af(n)||cf(n)||!!(mi&&n&&n[mi])}function Re(n,t){return t=null==t?9007199254740991:t, | |
!!t&&(typeof n=="number"||wn.test(n))&&-1<n&&0==n%1&&n<t}function ze(n,t,r){if(!bu(r))return false;var e=typeof t;return!!("number"==e?pu(r)&&Re(t,r.length):"string"==e&&t in r)&&hu(r[t],n)}function We(n,t){if(af(n))return false;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!Au(n))||(rn.test(n)||!tn.test(n)||null!=t&&n in ni(t))}function Be(n){var t=be(n),r=On[t];return typeof r=="function"&&t in Mn.prototype&&(n===r||(t=_o(r),!!t&&n===t[0]))}function Le(n){var t=n&&n.constructor; | |
return n===(typeof t=="function"&&t.prototype||ii)}function Ue(n,t){return function(r){return null!=r&&(r[n]===t&&(t!==F||n in ni(r)))}}function Ce(n,t,e){return t=Di(t===F?n.length-1:t,0),function(){for(var u=arguments,i=-1,o=Di(u.length-t,0),f=Hu(o);++i<o;)f[i]=u[t+i];for(i=-1,o=Hu(t+1);++i<t;)o[i]=u[i];return o[t]=e(f),r(n,this,o)}}function De(n,t,r){var e=t+"";t=wo;var u,i=Ne;return u=(u=e.match(hn))?u[1].split(pn):[],r=i(u,r),(i=r.length)&&(u=i-1,r[u]=(1<i?"& ":"")+r[u],r=r.join(2<i?", ":" "), | |
e=e.replace(sn,"{\n/* [wrapped with "+r+"] */\n")),t(n,e)}function Me(n){var t=0,r=0;return function(){var e=Ti(),u=16-(e-r);if(r=e,0<u){if(800<=++t)return arguments[0]}else t=0;return n.apply(F,arguments)}}function Te(n,t){var r=-1,e=n.length,u=e-1;for(t=t===F?e:t;++r<t;){var e=cr(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function $e(n){if(typeof n=="string"||Au(n))return n;var t=n+"";return"0"==t&&1/n==-N?"-0":t}function Fe(n){if(null!=n){try{return fi.call(n)}catch(n){}return n+""}return""; | |
}function Ne(n,t){return u(Z,function(r){var e="_."+r[0];t&r[1]&&!c(n,e)&&n.push(e)}),n.sort()}function Pe(n){if(n instanceof Mn)return n.clone();var t=new zn(n.__wrapped__,n.__chain__);return t.__actions__=Mr(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Ze(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Ou(r),0>r&&(r=Di(e+r,0)),g(n,je(t,3),r)):-1}function qe(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==F&&(u=Ou(r),u=0>r?Di(e+u,0):Mi(u,e-1)), | |
g(n,je(t,3),u,true)}function Ve(n){return(null==n?0:n.length)?kt(n,1):[]}function Ke(n){return n&&n.length?n[0]:F}function Ge(n){var t=null==n?0:n.length;return t?n[t-1]:F}function He(n,t){return n&&n.length&&t&&t.length?or(n,t):n}function Je(n){return null==n?n:Ni.call(n)}function Ye(n){if(!n||!n.length)return[];var t=0;return n=f(n,function(n){if(_u(n))return t=Di(n.length,t),true}),E(t,function(t){return l(n,j(t))})}function Qe(n,t){if(!n||!n.length)return[];var e=Ye(n);return null==t?e:l(e,function(n){ | |
return r(t,F,n)})}function Xe(n){return n=On(n),n.__chain__=true,n}function nu(n,t){return t(n)}function tu(){return this}function ru(n,t){return(af(n)?u:oo)(n,je(t,3))}function eu(n,t){return(af(n)?i:fo)(n,je(t,3))}function uu(n,t){return(af(n)?l:Yt)(n,je(t,3))}function iu(n,t,r){return t=r?F:t,t=n&&null==t?n.length:t,le(n,128,F,F,F,F,t)}function ou(n,t){var r;if(typeof t!="function")throw new ei("Expected a function");return n=Ou(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=F), | |
r}}function fu(n,t,r){return t=r?F:t,n=le(n,8,F,F,F,F,F,t),n.placeholder=fu.placeholder,n}function cu(n,t,r){return t=r?F:t,n=le(n,16,F,F,F,F,F,t),n.placeholder=cu.placeholder,n}function au(n,t,r){function e(t){var r=c,e=a;return c=a=F,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===F||r>=t||0>r||g&&n>=l}function i(){var n=Jo();if(u(n))return o(n);var r,e=jo;r=n-_,n=t-(n-p),r=g?Mi(n,l-r):n,h=e(i,r)}function o(n){return h=F,d&&c?e(n):(c=a=F,s)}function f(){var n=Jo(),r=u(n);if(c=arguments, | |
a=this,p=n,r){if(h===F)return _=n=p,h=jo(i,t),v?e(n):s;if(g)return h=jo(i,t),e(p)}return h===F&&(h=jo(i,t)),s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ei("Expected a function");return t=Iu(t)||0,bu(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Di(Iu(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==F&&ho(h),_=0,c=p=a=h=F},f.flush=function(){return h===F?s:o(Jo())},f}function lu(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e), | |
r.cache=i.set(u,e)||i,e)}if(typeof n!="function"||null!=t&&typeof t!="function")throw new ei("Expected a function");return r.cache=new(lu.Cache||Pn),r}function su(n){if(typeof n!="function")throw new ei("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function hu(n,t){return n===t||n!==n&&t!==t}function pu(n){return null!=n&&yu(n.length)&&!gu(n); | |
}function _u(n){return xu(n)&&pu(n)}function vu(n){if(!xu(n))return false;var t=zt(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!wu(n)}function gu(n){return!!bu(n)&&(n=zt(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function du(n){return typeof n=="number"&&n==Ou(n)}function yu(n){return typeof n=="number"&&-1<n&&0==n%1&&9007199254740991>=n}function bu(n){var t=typeof n;return null!=n&&("object"==t||"function"==t); | |
}function xu(n){return null!=n&&typeof n=="object"}function ju(n){return typeof n=="number"||xu(n)&&"[object Number]"==zt(n)}function wu(n){return!(!xu(n)||"[object Object]"!=zt(n))&&(n=bi(n),null===n||(n=ci.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&fi.call(n)==hi))}function mu(n){return typeof n=="string"||!af(n)&&xu(n)&&"[object String]"==zt(n)}function Au(n){return typeof n=="symbol"||xu(n)&&"[object Symbol]"==zt(n)}function ku(n){if(!n)return[];if(pu(n))return mu(n)?$(n):Mr(n); | |
if(Ai&&n[Ai]){n=n[Ai]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=yo(n),("[object Map]"==t?L:"[object Set]"==t?D:Du)(n)}function Eu(n){return n?(n=Iu(n),n===N||n===-N?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Ou(n){n=Eu(n);var t=n%1;return n===n?t?n-t:n:0}function Su(n){return n?gt(Ou(n),0,4294967295):0}function Iu(n){if(typeof n=="number")return n;if(Au(n))return P;if(bu(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,n=bu(n)?n+"":n),typeof n!="string")return 0===n?n:+n; | |
n=n.replace(cn,"");var t=bn.test(n);return t||jn.test(n)?Fn(n.slice(2),t?2:8):yn.test(n)?P:+n}function Ru(n){return Tr(n,Uu(n))}function zu(n){return null==n?"":jr(n)}function Wu(n,t,r){return n=null==n?F:It(n,t),n===F?r:n}function Bu(n,t){return null!=n&&ke(n,t,Lt)}function Lu(n){return pu(n)?Gn(n):Ht(n)}function Uu(n){if(pu(n))n=Gn(n,true);else if(bu(n)){var t,r=Le(n),e=[];for(t in n)("constructor"!=t||!r&&ci.call(n,t))&&e.push(t);n=e}else{if(t=[],null!=n)for(r in ni(n))t.push(r);n=t}return n}function Cu(n,t){ | |
if(null==n)return{};var r=l(ye(n),function(n){return[n]});return t=je(t),ur(n,r,function(n,r){return t(n,r[0])})}function Du(n){return null==n?[]:I(n,Lu(n))}function Mu(n){return Nf(zu(n).toLowerCase())}function Tu(n){return(n=zu(n))&&n.replace(mn,rt).replace(Rn,"")}function $u(n,t,r){return n=zu(n),t=r?F:t,t===F?Ln.test(n)?n.match(Wn)||[]:n.match(_n)||[]:n.match(t)||[]}function Fu(n){return function(){return n}}function Nu(n){return n}function Pu(n){return Gt(typeof n=="function"?n:dt(n,1))}function Zu(n,t,r){ | |
var e=Lu(t),i=St(t,e);null!=r||bu(t)&&(i.length||!e.length)||(r=t,t=n,n=this,i=St(t,Lu(t)));var o=!(bu(r)&&"chain"in r&&!r.chain),f=gu(n);return u(i,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Mr(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,s([this.value()],arguments))})}),n}function qu(){}function Vu(n){return We(n)?j($e(n)):ir(n)}function Ku(){return[]}function Gu(){ | |
return false}En=null==En?Zn:it.defaults(Zn.Object(),En,it.pick(Zn,Un));var Hu=En.Array,Ju=En.Date,Yu=En.Error,Qu=En.Function,Xu=En.Math,ni=En.Object,ti=En.RegExp,ri=En.String,ei=En.TypeError,ui=Hu.prototype,ii=ni.prototype,oi=En["__core-js_shared__"],fi=Qu.prototype.toString,ci=ii.hasOwnProperty,ai=0,li=function(){var n=/[^.]+$/.exec(oi&&oi.keys&&oi.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),si=ii.toString,hi=fi.call(ni),pi=Zn._,_i=ti("^"+fi.call(ci).replace(on,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),vi=Kn?En.Buffer:F,gi=En.Symbol,di=En.Uint8Array,yi=vi?vi.f:F,bi=U(ni.getPrototypeOf,ni),xi=ni.create,ji=ii.propertyIsEnumerable,wi=ui.splice,mi=gi?gi.isConcatSpreadable:F,Ai=gi?gi.iterator:F,ki=gi?gi.toStringTag:F,Ei=function(){ | |
try{var n=Ae(ni,"defineProperty");return n({},"",{}),n}catch(n){}}(),Oi=En.clearTimeout!==Zn.clearTimeout&&En.clearTimeout,Si=Ju&&Ju.now!==Zn.Date.now&&Ju.now,Ii=En.setTimeout!==Zn.setTimeout&&En.setTimeout,Ri=Xu.ceil,zi=Xu.floor,Wi=ni.getOwnPropertySymbols,Bi=vi?vi.isBuffer:F,Li=En.isFinite,Ui=ui.join,Ci=U(ni.keys,ni),Di=Xu.max,Mi=Xu.min,Ti=Ju.now,$i=En.parseInt,Fi=Xu.random,Ni=ui.reverse,Pi=Ae(En,"DataView"),Zi=Ae(En,"Map"),qi=Ae(En,"Promise"),Vi=Ae(En,"Set"),Ki=Ae(En,"WeakMap"),Gi=Ae(ni,"create"),Hi=Ki&&new Ki,Ji={},Yi=Fe(Pi),Qi=Fe(Zi),Xi=Fe(qi),no=Fe(Vi),to=Fe(Ki),ro=gi?gi.prototype:F,eo=ro?ro.valueOf:F,uo=ro?ro.toString:F,io=function(){ | |
function n(){}return function(t){return bu(t)?xi?xi(t):(n.prototype=t,t=new n,n.prototype=F,t):{}}}();On.templateSettings={escape:Q,evaluate:X,interpolate:nn,variable:"",imports:{_:On}},On.prototype=Sn.prototype,On.prototype.constructor=On,zn.prototype=io(Sn.prototype),zn.prototype.constructor=zn,Mn.prototype=io(Sn.prototype),Mn.prototype.constructor=Mn,Tn.prototype.clear=function(){this.__data__=Gi?Gi(null):{},this.size=0},Tn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n], | |
this.size-=n?1:0,n},Tn.prototype.get=function(n){var t=this.__data__;return Gi?(n=t[n],"__lodash_hash_undefined__"===n?F:n):ci.call(t,n)?t[n]:F},Tn.prototype.has=function(n){var t=this.__data__;return Gi?t[n]!==F:ci.call(t,n)},Tn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=Gi&&t===F?"__lodash_hash_undefined__":t,this},Nn.prototype.clear=function(){this.__data__=[],this.size=0},Nn.prototype.delete=function(n){var t=this.__data__;return n=lt(t,n),!(0>n)&&(n==t.length-1?t.pop():wi.call(t,n,1), | |
--this.size,true)},Nn.prototype.get=function(n){var t=this.__data__;return n=lt(t,n),0>n?F:t[n][1]},Nn.prototype.has=function(n){return-1<lt(this.__data__,n)},Nn.prototype.set=function(n,t){var r=this.__data__,e=lt(r,n);return 0>e?(++this.size,r.push([n,t])):r[e][1]=t,this},Pn.prototype.clear=function(){this.size=0,this.__data__={hash:new Tn,map:new(Zi||Nn),string:new Tn}},Pn.prototype.delete=function(n){return n=we(this,n).delete(n),this.size-=n?1:0,n},Pn.prototype.get=function(n){return we(this,n).get(n); | |
},Pn.prototype.has=function(n){return we(this,n).has(n)},Pn.prototype.set=function(n,t){var r=we(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},qn.prototype.add=qn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},qn.prototype.has=function(n){return this.__data__.has(n)},Vn.prototype.clear=function(){this.__data__=new Nn,this.size=0},Vn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Vn.prototype.get=function(n){ | |
return this.__data__.get(n)},Vn.prototype.has=function(n){return this.__data__.has(n)},Vn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Nn){var e=r.__data__;if(!Zi||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Pn(e)}return r.set(n,t),this.size=r.size,this};var oo=Zr(Et),fo=Zr(Ot,true),co=qr(),ao=qr(true),lo=Hi?function(n,t){return Hi.set(n,t),n}:Nu,so=Ei?function(n,t){return Ei(n,"toString",{configurable:true,enumerable:false,value:Fu(t),writable:true})}:Nu,ho=Oi||function(n){ | |
return Zn.clearTimeout(n)},po=Vi&&1/D(new Vi([,-0]))[1]==N?function(n){return new Vi(n)}:qu,_o=Hi?function(n){return Hi.get(n)}:qu,vo=Wi?function(n){return null==n?[]:(n=ni(n),f(Wi(n),function(t){return ji.call(n,t)}))}:Ku,go=Wi?function(n){for(var t=[];n;)s(t,vo(n)),n=bi(n);return t}:Ku,yo=zt;(Pi&&"[object DataView]"!=yo(new Pi(new ArrayBuffer(1)))||Zi&&"[object Map]"!=yo(new Zi)||qi&&"[object Promise]"!=yo(qi.resolve())||Vi&&"[object Set]"!=yo(new Vi)||Ki&&"[object WeakMap]"!=yo(new Ki))&&(yo=function(n){ | |
var t=zt(n);if(n=(n="[object Object]"==t?n.constructor:F)?Fe(n):"")switch(n){case Yi:return"[object DataView]";case Qi:return"[object Map]";case Xi:return"[object Promise]";case no:return"[object Set]";case to:return"[object WeakMap]"}return t});var bo=oi?gu:Gu,xo=Me(lo),jo=Ii||function(n,t){return Zn.setTimeout(n,t)},wo=Me(so),mo=function(n){n=lu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return en.test(n)&&t.push(""),n.replace(un,function(n,r,e,u){ | |
t.push(e?u.replace(vn,"$1"):r||n)}),t}),Ao=lr(function(n,t){return _u(n)?jt(n,kt(t,1,_u,true)):[]}),ko=lr(function(n,t){var r=Ge(t);return _u(r)&&(r=F),_u(n)?jt(n,kt(t,1,_u,true),je(r,2)):[]}),Eo=lr(function(n,t){var r=Ge(t);return _u(r)&&(r=F),_u(n)?jt(n,kt(t,1,_u,true),F,r):[]}),Oo=lr(function(n){var t=l(n,Sr);return t.length&&t[0]===n[0]?Ut(t):[]}),So=lr(function(n){var t=Ge(n),r=l(n,Sr);return t===Ge(r)?t=F:r.pop(),r.length&&r[0]===n[0]?Ut(r,je(t,2)):[]}),Io=lr(function(n){var t=Ge(n),r=l(n,Sr);return(t=typeof t=="function"?t:F)&&r.pop(), | |
r.length&&r[0]===n[0]?Ut(r,F,t):[]}),Ro=lr(He),zo=ge(function(n,t){var r=null==n?0:n.length,e=vt(n,t);return fr(n,l(t,function(n){return Re(n,r)?+n:n}).sort(Ur)),e}),Wo=lr(function(n){return wr(kt(n,1,_u,true))}),Bo=lr(function(n){var t=Ge(n);return _u(t)&&(t=F),wr(kt(n,1,_u,true),je(t,2))}),Lo=lr(function(n){var t=Ge(n),t=typeof t=="function"?t:F;return wr(kt(n,1,_u,true),F,t)}),Uo=lr(function(n,t){return _u(n)?jt(n,t):[]}),Co=lr(function(n){return Er(f(n,_u))}),Do=lr(function(n){var t=Ge(n);return _u(t)&&(t=F), | |
Er(f(n,_u),je(t,2))}),Mo=lr(function(n){var t=Ge(n),t=typeof t=="function"?t:F;return Er(f(n,_u),F,t)}),To=lr(Ye),$o=lr(function(n){var t=n.length,t=1<t?n[t-1]:F,t=typeof t=="function"?(n.pop(),t):F;return Qe(n,t)}),Fo=ge(function(n){function t(t){return vt(t,n)}var r=n.length,e=r?n[0]:0,u=this.__wrapped__;return!(1<r||this.__actions__.length)&&u instanceof Mn&&Re(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:nu,args:[t],thisArg:F}),new zn(u,this.__chain__).thru(function(n){return r&&!n.length&&n.push(F), | |
n})):this.thru(t)}),No=Nr(function(n,t,r){ci.call(n,r)?++n[r]:_t(n,r,1)}),Po=Yr(Ze),Zo=Yr(qe),qo=Nr(function(n,t,r){ci.call(n,r)?n[r].push(t):_t(n,r,[t])}),Vo=lr(function(n,t,e){var u=-1,i=typeof t=="function",o=pu(n)?Hu(n.length):[];return oo(n,function(n){o[++u]=i?r(t,n,e):Dt(n,t,e)}),o}),Ko=Nr(function(n,t,r){_t(n,r,t)}),Go=Nr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Ho=lr(function(n,t){if(null==n)return[];var r=t.length;return 1<r&&ze(n,t[0],t[1])?t=[]:2<r&&ze(t[0],t[1],t[2])&&(t=[t[0]]), | |
rr(n,kt(t,1),[])}),Jo=Si||function(){return Zn.Date.now()},Yo=lr(function(n,t,r){var e=1;if(r.length)var u=C(r,xe(Yo)),e=32|e;return le(n,e,t,r,u)}),Qo=lr(function(n,t,r){var e=3;if(r.length)var u=C(r,xe(Qo)),e=32|e;return le(t,e,n,r,u)}),Xo=lr(function(n,t){return xt(n,1,t)}),nf=lr(function(n,t,r){return xt(n,Iu(t)||0,r)});lu.Cache=Pn;var tf=lr(function(n,t){t=1==t.length&&af(t[0])?l(t[0],S(je())):l(kt(t,1),S(je()));var e=t.length;return lr(function(u){for(var i=-1,o=Mi(u.length,e);++i<o;)u[i]=t[i].call(this,u[i]); | |
return r(n,this,u)})}),rf=lr(function(n,t){return le(n,32,F,t,C(t,xe(rf)))}),ef=lr(function(n,t){return le(n,64,F,t,C(t,xe(ef)))}),uf=ge(function(n,t){return le(n,256,F,F,F,t)}),of=oe(Wt),ff=oe(function(n,t){return n>=t}),cf=Mt(function(){return arguments}())?Mt:function(n){return xu(n)&&ci.call(n,"callee")&&!ji.call(n,"callee")},af=Hu.isArray,lf=Hn?S(Hn):Tt,sf=Bi||Gu,hf=Jn?S(Jn):$t,pf=Yn?S(Yn):Nt,_f=Qn?S(Qn):qt,vf=Xn?S(Xn):Vt,gf=nt?S(nt):Kt,df=oe(Jt),yf=oe(function(n,t){return n<=t}),bf=Pr(function(n,t){ | |
if(Le(t)||pu(t))Tr(t,Lu(t),n);else for(var r in t)ci.call(t,r)&&at(n,r,t[r])}),xf=Pr(function(n,t){Tr(t,Uu(t),n)}),jf=Pr(function(n,t,r,e){Tr(t,Uu(t),n,e)}),wf=Pr(function(n,t,r,e){Tr(t,Lu(t),n,e)}),mf=ge(vt),Af=lr(function(n){return n.push(F,se),r(jf,F,n)}),kf=lr(function(n){return n.push(F,he),r(Rf,F,n)}),Ef=ne(function(n,t,r){n[t]=r},Fu(Nu)),Of=ne(function(n,t,r){ci.call(n,t)?n[t].push(r):n[t]=[r]},je),Sf=lr(Dt),If=Pr(function(n,t,r){nr(n,t,r)}),Rf=Pr(function(n,t,r,e){nr(n,t,r,e)}),zf=ge(function(n,t){ | |
var r={};if(null==n)return r;var e=false;t=l(t,function(t){return t=Rr(t,n),e||(e=1<t.length),t}),Tr(n,ye(n),r),e&&(r=dt(r,7,pe));for(var u=t.length;u--;)mr(r,t[u]);return r}),Wf=ge(function(n,t){return null==n?{}:er(n,t)}),Bf=ae(Lu),Lf=ae(Uu),Uf=Gr(function(n,t,r){return t=t.toLowerCase(),n+(r?Mu(t):t)}),Cf=Gr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Df=Gr(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Mf=Kr("toLowerCase"),Tf=Gr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase(); | |
}),$f=Gr(function(n,t,r){return n+(r?" ":"")+Nf(t)}),Ff=Gr(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),Nf=Kr("toUpperCase"),Pf=lr(function(n,t){try{return r(n,F,t)}catch(n){return vu(n)?n:new Yu(n)}}),Zf=ge(function(n,t){return u(t,function(t){t=$e(t),_t(n,t,Yo(n[t],n))}),n}),qf=Qr(),Vf=Qr(true),Kf=lr(function(n,t){return function(r){return Dt(r,n,t)}}),Gf=lr(function(n,t){return function(r){return Dt(n,r,t)}}),Hf=re(l),Jf=re(o),Yf=re(_),Qf=ie(),Xf=ie(true),nc=te(function(n,t){return n+t},0),tc=ce("ceil"),rc=te(function(n,t){ | |
return n/t},1),ec=ce("floor"),uc=te(function(n,t){return n*t},1),ic=ce("round"),oc=te(function(n,t){return n-t},0);return On.after=function(n,t){if(typeof t!="function")throw new ei("Expected a function");return n=Ou(n),function(){if(1>--n)return t.apply(this,arguments)}},On.ary=iu,On.assign=bf,On.assignIn=xf,On.assignInWith=jf,On.assignWith=wf,On.at=mf,On.before=ou,On.bind=Yo,On.bindAll=Zf,On.bindKey=Qo,On.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return af(n)?n:[n]}, | |
On.chain=Xe,On.chunk=function(n,t,r){if(t=(r?ze(n,t,r):t===F)?1:Di(Ou(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Hu(Ri(r/t));e<r;)i[u++]=vr(n,e,e+=t);return i},On.compact=function(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){var i=n[t];i&&(u[e++]=i)}return u},On.concat=function(){var n=arguments.length;if(!n)return[];for(var t=Hu(n-1),r=arguments[0];n--;)t[n-1]=arguments[n];return s(af(r)?Mr(r):[r],kt(t,1))},On.cond=function(n){var t=null==n?0:n.length,e=je();return n=t?l(n,function(n){ | |
if("function"!=typeof n[1])throw new ei("Expected a function");return[e(n[0]),n[1]]}):[],lr(function(e){for(var u=-1;++u<t;){var i=n[u];if(r(i[0],this,e))return r(i[1],this,e)}})},On.conforms=function(n){return yt(dt(n,1))},On.constant=Fu,On.countBy=No,On.create=function(n,t){var r=io(n);return null==t?r:ht(r,t)},On.curry=fu,On.curryRight=cu,On.debounce=au,On.defaults=Af,On.defaultsDeep=kf,On.defer=Xo,On.delay=nf,On.difference=Ao,On.differenceBy=ko,On.differenceWith=Eo,On.drop=function(n,t,r){var e=null==n?0:n.length; | |
return e?(t=r||t===F?1:Ou(t),vr(n,0>t?0:t,e)):[]},On.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===F?1:Ou(t),t=e-t,vr(n,0,0>t?0:t)):[]},On.dropRightWhile=function(n,t){return n&&n.length?Ar(n,je(t,3),true,true):[]},On.dropWhile=function(n,t){return n&&n.length?Ar(n,je(t,3),true):[]},On.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&ze(n,t,r)&&(r=0,e=u),u=n.length,r=Ou(r),0>r&&(r=-r>u?0:u+r),e=e===F||e>u?u:Ou(e),0>e&&(e+=u),e=r>e?0:Su(e);r<e;)n[r++]=t; | |
return n},On.filter=function(n,t){return(af(n)?f:At)(n,je(t,3))},On.flatMap=function(n,t){return kt(uu(n,t),1)},On.flatMapDeep=function(n,t){return kt(uu(n,t),N)},On.flatMapDepth=function(n,t,r){return r=r===F?1:Ou(r),kt(uu(n,t),r)},On.flatten=Ve,On.flattenDeep=function(n){return(null==n?0:n.length)?kt(n,N):[]},On.flattenDepth=function(n,t){return null!=n&&n.length?(t=t===F?1:Ou(t),kt(n,t)):[]},On.flip=function(n){return le(n,512)},On.flow=qf,On.flowRight=Vf,On.fromPairs=function(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){ | |
var u=n[t];e[u[0]]=u[1]}return e},On.functions=function(n){return null==n?[]:St(n,Lu(n))},On.functionsIn=function(n){return null==n?[]:St(n,Uu(n))},On.groupBy=qo,On.initial=function(n){return(null==n?0:n.length)?vr(n,0,-1):[]},On.intersection=Oo,On.intersectionBy=So,On.intersectionWith=Io,On.invert=Ef,On.invertBy=Of,On.invokeMap=Vo,On.iteratee=Pu,On.keyBy=Ko,On.keys=Lu,On.keysIn=Uu,On.map=uu,On.mapKeys=function(n,t){var r={};return t=je(t,3),Et(n,function(n,e,u){_t(r,t(n,e,u),n)}),r},On.mapValues=function(n,t){ | |
var r={};return t=je(t,3),Et(n,function(n,e,u){_t(r,e,t(n,e,u))}),r},On.matches=function(n){return Qt(dt(n,1))},On.matchesProperty=function(n,t){return Xt(n,dt(t,1))},On.memoize=lu,On.merge=If,On.mergeWith=Rf,On.method=Kf,On.methodOf=Gf,On.mixin=Zu,On.negate=su,On.nthArg=function(n){return n=Ou(n),lr(function(t){return tr(t,n)})},On.omit=zf,On.omitBy=function(n,t){return Cu(n,su(je(t)))},On.once=function(n){return ou(2,n)},On.orderBy=function(n,t,r,e){return null==n?[]:(af(t)||(t=null==t?[]:[t]), | |
r=e?F:r,af(r)||(r=null==r?[]:[r]),rr(n,t,r))},On.over=Hf,On.overArgs=tf,On.overEvery=Jf,On.overSome=Yf,On.partial=rf,On.partialRight=ef,On.partition=Go,On.pick=Wf,On.pickBy=Cu,On.property=Vu,On.propertyOf=function(n){return function(t){return null==n?F:It(n,t)}},On.pull=Ro,On.pullAll=He,On.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?or(n,t,je(r,2)):n},On.pullAllWith=function(n,t,r){return n&&n.length&&t&&t.length?or(n,t,F,r):n},On.pullAt=zo,On.range=Qf,On.rangeRight=Xf,On.rearg=uf,On.reject=function(n,t){ | |
return(af(n)?f:At)(n,su(je(t,3)))},On.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=je(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),u.push(e))}return fr(n,u),r},On.rest=function(n,t){if(typeof n!="function")throw new ei("Expected a function");return t=t===F?t:Ou(t),lr(n,t)},On.reverse=Je,On.sampleSize=function(n,t,r){return t=(r?ze(n,t,r):t===F)?1:Ou(t),(af(n)?ot:hr)(n,t)},On.set=function(n,t,r){return null==n?n:pr(n,t,r)},On.setWith=function(n,t,r,e){return e=typeof e=="function"?e:F, | |
null==n?n:pr(n,t,r,e)},On.shuffle=function(n){return(af(n)?ft:_r)(n)},On.slice=function(n,t,r){var e=null==n?0:n.length;return e?(r&&typeof r!="number"&&ze(n,t,r)?(t=0,r=e):(t=null==t?0:Ou(t),r=r===F?e:Ou(r)),vr(n,t,r)):[]},On.sortBy=Ho,On.sortedUniq=function(n){return n&&n.length?br(n):[]},On.sortedUniqBy=function(n,t){return n&&n.length?br(n,je(t,2)):[]},On.split=function(n,t,r){return r&&typeof r!="number"&&ze(n,t,r)&&(t=r=F),r=r===F?4294967295:r>>>0,r?(n=zu(n))&&(typeof t=="string"||null!=t&&!_f(t))&&(t=jr(t), | |
!t&&Bn.test(n))?zr($(n),0,r):n.split(t,r):[]},On.spread=function(n,t){if(typeof n!="function")throw new ei("Expected a function");return t=null==t?0:Di(Ou(t),0),lr(function(e){var u=e[t];return e=zr(e,0,t),u&&s(e,u),r(n,this,e)})},On.tail=function(n){var t=null==n?0:n.length;return t?vr(n,1,t):[]},On.take=function(n,t,r){return n&&n.length?(t=r||t===F?1:Ou(t),vr(n,0,0>t?0:t)):[]},On.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===F?1:Ou(t),t=e-t,vr(n,0>t?0:t,e)):[]},On.takeRightWhile=function(n,t){ | |
return n&&n.length?Ar(n,je(t,3),false,true):[]},On.takeWhile=function(n,t){return n&&n.length?Ar(n,je(t,3)):[]},On.tap=function(n,t){return t(n),n},On.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ei("Expected a function");return bu(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),au(n,t,{leading:e,maxWait:t,trailing:u})},On.thru=nu,On.toArray=ku,On.toPairs=Bf,On.toPairsIn=Lf,On.toPath=function(n){return af(n)?l(n,$e):Au(n)?[n]:Mr(mo(zu(n)))},On.toPlainObject=Ru, | |
On.transform=function(n,t,r){var e=af(n),i=e||sf(n)||gf(n);if(t=je(t,4),null==r){var o=n&&n.constructor;r=i?e?new o:[]:bu(n)&&gu(o)?io(bi(n)):{}}return(i?u:Et)(n,function(n,e,u){return t(r,n,e,u)}),r},On.unary=function(n){return iu(n,1)},On.union=Wo,On.unionBy=Bo,On.unionWith=Lo,On.uniq=function(n){return n&&n.length?wr(n):[]},On.uniqBy=function(n,t){return n&&n.length?wr(n,je(t,2)):[]},On.uniqWith=function(n,t){return t=typeof t=="function"?t:F,n&&n.length?wr(n,F,t):[]},On.unset=function(n,t){return null==n||mr(n,t); | |
},On.unzip=Ye,On.unzipWith=Qe,On.update=function(n,t,r){return null==n?n:pr(n,t,Ir(r)(It(n,t)),void 0)},On.updateWith=function(n,t,r,e){return e=typeof e=="function"?e:F,null!=n&&(n=pr(n,t,Ir(r)(It(n,t)),e)),n},On.values=Du,On.valuesIn=function(n){return null==n?[]:I(n,Uu(n))},On.without=Uo,On.words=$u,On.wrap=function(n,t){return rf(Ir(t),n)},On.xor=Co,On.xorBy=Do,On.xorWith=Mo,On.zip=To,On.zipObject=function(n,t){return Or(n||[],t||[],at)},On.zipObjectDeep=function(n,t){return Or(n||[],t||[],pr); | |
},On.zipWith=$o,On.entries=Bf,On.entriesIn=Lf,On.extend=xf,On.extendWith=jf,Zu(On,On),On.add=nc,On.attempt=Pf,On.camelCase=Uf,On.capitalize=Mu,On.ceil=tc,On.clamp=function(n,t,r){return r===F&&(r=t,t=F),r!==F&&(r=Iu(r),r=r===r?r:0),t!==F&&(t=Iu(t),t=t===t?t:0),gt(Iu(n),t,r)},On.clone=function(n){return dt(n,4)},On.cloneDeep=function(n){return dt(n,5)},On.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:F,dt(n,5,t)},On.cloneWith=function(n,t){return t=typeof t=="function"?t:F,dt(n,4,t)}, | |
On.conformsTo=function(n,t){return null==t||bt(n,t,Lu(t))},On.deburr=Tu,On.defaultTo=function(n,t){return null==n||n!==n?t:n},On.divide=rc,On.endsWith=function(n,t,r){n=zu(n),t=jr(t);var e=n.length,e=r=r===F?e:gt(Ou(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},On.eq=hu,On.escape=function(n){return(n=zu(n))&&Y.test(n)?n.replace(H,et):n},On.escapeRegExp=function(n){return(n=zu(n))&&fn.test(n)?n.replace(on,"\\$&"):n},On.every=function(n,t,r){var e=af(n)?o:wt;return r&&ze(n,t,r)&&(t=F),e(n,je(t,3)); | |
},On.find=Po,On.findIndex=Ze,On.findKey=function(n,t){return v(n,je(t,3),Et)},On.findLast=Zo,On.findLastIndex=qe,On.findLastKey=function(n,t){return v(n,je(t,3),Ot)},On.floor=ec,On.forEach=ru,On.forEachRight=eu,On.forIn=function(n,t){return null==n?n:co(n,je(t,3),Uu)},On.forInRight=function(n,t){return null==n?n:ao(n,je(t,3),Uu)},On.forOwn=function(n,t){return n&&Et(n,je(t,3))},On.forOwnRight=function(n,t){return n&&Ot(n,je(t,3))},On.get=Wu,On.gt=of,On.gte=ff,On.has=function(n,t){return null!=n&&ke(n,t,Bt); | |
},On.hasIn=Bu,On.head=Ke,On.identity=Nu,On.includes=function(n,t,r,e){return n=pu(n)?n:Du(n),r=r&&!e?Ou(r):0,e=n.length,0>r&&(r=Di(e+r,0)),mu(n)?r<=e&&-1<n.indexOf(t,r):!!e&&-1<d(n,t,r)},On.indexOf=function(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Ou(r),0>r&&(r=Di(e+r,0)),d(n,t,r)):-1},On.inRange=function(n,t,r){return t=Eu(t),r===F?(r=t,t=0):r=Eu(r),n=Iu(n),n>=Mi(t,r)&&n<Di(t,r)},On.invoke=Sf,On.isArguments=cf,On.isArray=af,On.isArrayBuffer=lf,On.isArrayLike=pu,On.isArrayLikeObject=_u, | |
On.isBoolean=function(n){return true===n||false===n||xu(n)&&"[object Boolean]"==zt(n)},On.isBuffer=sf,On.isDate=hf,On.isElement=function(n){return xu(n)&&1===n.nodeType&&!wu(n)},On.isEmpty=function(n){if(null==n)return true;if(pu(n)&&(af(n)||typeof n=="string"||typeof n.splice=="function"||sf(n)||gf(n)||cf(n)))return!n.length;var t=yo(n);if("[object Map]"==t||"[object Set]"==t)return!n.size;if(Le(n))return!Ht(n).length;for(var r in n)if(ci.call(n,r))return false;return true},On.isEqual=function(n,t){return Ft(n,t); | |
},On.isEqualWith=function(n,t,r){var e=(r=typeof r=="function"?r:F)?r(n,t):F;return e===F?Ft(n,t,F,r):!!e},On.isError=vu,On.isFinite=function(n){return typeof n=="number"&&Li(n)},On.isFunction=gu,On.isInteger=du,On.isLength=yu,On.isMap=pf,On.isMatch=function(n,t){return n===t||Pt(n,t,me(t))},On.isMatchWith=function(n,t,r){return r=typeof r=="function"?r:F,Pt(n,t,me(t),r)},On.isNaN=function(n){return ju(n)&&n!=+n},On.isNative=function(n){if(bo(n))throw new Yu("Unsupported core-js use. Try https://npms.io/search?q=ponyfill."); | |
return Zt(n)},On.isNil=function(n){return null==n},On.isNull=function(n){return null===n},On.isNumber=ju,On.isObject=bu,On.isObjectLike=xu,On.isPlainObject=wu,On.isRegExp=_f,On.isSafeInteger=function(n){return du(n)&&-9007199254740991<=n&&9007199254740991>=n},On.isSet=vf,On.isString=mu,On.isSymbol=Au,On.isTypedArray=gf,On.isUndefined=function(n){return n===F},On.isWeakMap=function(n){return xu(n)&&"[object WeakMap]"==yo(n)},On.isWeakSet=function(n){return xu(n)&&"[object WeakSet]"==zt(n)},On.join=function(n,t){ | |
return null==n?"":Ui.call(n,t)},On.kebabCase=Cf,On.last=Ge,On.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==F&&(u=Ou(r),u=0>u?Di(e+u,0):Mi(u,e-1)),t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=g(n,b,u,true);return n},On.lowerCase=Df,On.lowerFirst=Mf,On.lt=df,On.lte=yf,On.max=function(n){return n&&n.length?mt(n,Nu,Wt):F},On.maxBy=function(n,t){return n&&n.length?mt(n,je(t,2),Wt):F},On.mean=function(n){return x(n,Nu)},On.meanBy=function(n,t){return x(n,je(t,2))},On.min=function(n){ | |
return n&&n.length?mt(n,Nu,Jt):F},On.minBy=function(n,t){return n&&n.length?mt(n,je(t,2),Jt):F},On.stubArray=Ku,On.stubFalse=Gu,On.stubObject=function(){return{}},On.stubString=function(){return""},On.stubTrue=function(){return true},On.multiply=uc,On.nth=function(n,t){return n&&n.length?tr(n,Ou(t)):F},On.noConflict=function(){return Zn._===this&&(Zn._=pi),this},On.noop=qu,On.now=Jo,On.pad=function(n,t,r){n=zu(n);var e=(t=Ou(t))?T(n):0;return!t||e>=t?n:(t=(t-e)/2,ee(zi(t),r)+n+ee(Ri(t),r))},On.padEnd=function(n,t,r){ | |
n=zu(n);var e=(t=Ou(t))?T(n):0;return t&&e<t?n+ee(t-e,r):n},On.padStart=function(n,t,r){n=zu(n);var e=(t=Ou(t))?T(n):0;return t&&e<t?ee(t-e,r)+n:n},On.parseInt=function(n,t,r){return r||null==t?t=0:t&&(t=+t),$i(zu(n).replace(an,""),t||0)},On.random=function(n,t,r){if(r&&typeof r!="boolean"&&ze(n,t,r)&&(t=r=F),r===F&&(typeof t=="boolean"?(r=t,t=F):typeof n=="boolean"&&(r=n,n=F)),n===F&&t===F?(n=0,t=1):(n=Eu(n),t===F?(t=n,n=0):t=Eu(t)),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Fi(),Mi(n+r*(t-n+$n("1e-"+((r+"").length-1))),t)):cr(n,t); | |
},On.reduce=function(n,t,r){var e=af(n)?h:m,u=3>arguments.length;return e(n,je(t,4),r,u,oo)},On.reduceRight=function(n,t,r){var e=af(n)?p:m,u=3>arguments.length;return e(n,je(t,4),r,u,fo)},On.repeat=function(n,t,r){return t=(r?ze(n,t,r):t===F)?1:Ou(t),ar(zu(n),t)},On.replace=function(){var n=arguments,t=zu(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},On.result=function(n,t,r){t=Rr(t,n);var e=-1,u=t.length;for(u||(u=1,n=F);++e<u;){var i=null==n?F:n[$e(t[e])];i===F&&(e=u,i=r),n=gu(i)?i.call(n):i; | |
}return n},On.round=ic,On.runInContext=w,On.sample=function(n){return(af(n)?tt:sr)(n)},On.size=function(n){if(null==n)return 0;if(pu(n))return mu(n)?T(n):n.length;var t=yo(n);return"[object Map]"==t||"[object Set]"==t?n.size:Ht(n).length},On.snakeCase=Tf,On.some=function(n,t,r){var e=af(n)?_:gr;return r&&ze(n,t,r)&&(t=F),e(n,je(t,3))},On.sortedIndex=function(n,t){return dr(n,t)},On.sortedIndexBy=function(n,t,r){return yr(n,t,je(r,2))},On.sortedIndexOf=function(n,t){var r=null==n?0:n.length;if(r){ | |
var e=dr(n,t);if(e<r&&hu(n[e],t))return e}return-1},On.sortedLastIndex=function(n,t){return dr(n,t,true)},On.sortedLastIndexBy=function(n,t,r){return yr(n,t,je(r,2),true)},On.sortedLastIndexOf=function(n,t){if(null==n?0:n.length){var r=dr(n,t,true)-1;if(hu(n[r],t))return r}return-1},On.startCase=$f,On.startsWith=function(n,t,r){return n=zu(n),r=null==r?0:gt(Ou(r),0,n.length),t=jr(t),n.slice(r,r+t.length)==t},On.subtract=oc,On.sum=function(n){return n&&n.length?k(n,Nu):0},On.sumBy=function(n,t){return n&&n.length?k(n,je(t,2)):0; | |
},On.template=function(n,t,r){var e=On.templateSettings;r&&ze(n,t,r)&&(t=F),n=zu(n),t=jf({},t,e,se),r=jf({},t.imports,e.imports,se);var u,i,o=Lu(r),f=I(r,o),c=0;r=t.interpolate||An;var a="__p+='";r=ti((t.escape||An).source+"|"+r.source+"|"+(r===nn?gn:An).source+"|"+(t.evaluate||An).source+"|$","g");var l="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,o,f,l){return e||(e=o),a+=n.slice(c,l).replace(kn,B),r&&(u=true,a+="'+__e("+r+")+'"),f&&(i=true,a+="';"+f+";\n__p+='"), | |
e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=t.variable)||(a="with(obj){"+a+"}"),a=(i?a.replace(q,""):a).replace(V,"$1").replace(K,"$1;"),a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=Pf(function(){return Qu(o,l+"return "+a).apply(F,f)}),t.source=a,vu(t))throw t;return t},On.times=function(n,t){if(n=Ou(n),1>n||9007199254740991<n)return[]; | |
var r=4294967295,e=Mi(n,4294967295);for(t=je(t),n-=4294967295,e=E(e,t);++r<n;)t(r);return e},On.toFinite=Eu,On.toInteger=Ou,On.toLength=Su,On.toLower=function(n){return zu(n).toLowerCase()},On.toNumber=Iu,On.toSafeInteger=function(n){return n?gt(Ou(n),-9007199254740991,9007199254740991):0===n?n:0},On.toString=zu,On.toUpper=function(n){return zu(n).toUpperCase()},On.trim=function(n,t,r){return(n=zu(n))&&(r||t===F)?n.replace(cn,""):n&&(t=jr(t))?(n=$(n),r=$(t),t=z(n,r),r=W(n,r)+1,zr(n,t,r).join("")):n; | |
},On.trimEnd=function(n,t,r){return(n=zu(n))&&(r||t===F)?n.replace(ln,""):n&&(t=jr(t))?(n=$(n),t=W(n,$(t))+1,zr(n,0,t).join("")):n},On.trimStart=function(n,t,r){return(n=zu(n))&&(r||t===F)?n.replace(an,""):n&&(t=jr(t))?(n=$(n),t=z(n,$(t)),zr(n,t).join("")):n},On.truncate=function(n,t){var r=30,e="...";if(bu(t))var u="separator"in t?t.separator:u,r="length"in t?Ou(t.length):r,e="omission"in t?jr(t.omission):e;n=zu(n);var i=n.length;if(Bn.test(n))var o=$(n),i=o.length;if(r>=i)return n;if(i=r-T(e),1>i)return e; | |
if(r=o?zr(o,0,i).join(""):n.slice(0,i),u===F)return r+e;if(o&&(i+=r.length-i),_f(u)){if(n.slice(i).search(u)){var f=r;for(u.global||(u=ti(u.source,zu(dn.exec(u))+"g")),u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===F?i:c)}}else n.indexOf(jr(u),i)!=i&&(u=r.lastIndexOf(u),-1<u&&(r=r.slice(0,u)));return r+e},On.unescape=function(n){return(n=zu(n))&&J.test(n)?n.replace(G,ut):n},On.uniqueId=function(n){var t=++ai;return zu(n)+t},On.upperCase=Ff,On.upperFirst=Nf,On.each=ru,On.eachRight=eu,On.first=Ke, | |
Zu(On,function(){var n={};return Et(On,function(t,r){ci.call(On.prototype,r)||(n[r]=t)}),n}(),{chain:false}),On.VERSION="4.17.4",u("bind bindKey curry curryRight partial partialRight".split(" "),function(n){On[n].placeholder=On}),u(["drop","take"],function(n,t){Mn.prototype[n]=function(r){r=r===F?1:Di(Ou(r),0);var e=this.__filtered__&&!t?new Mn(this):this.clone();return e.__filtered__?e.__takeCount__=Mi(r,e.__takeCount__):e.__views__.push({size:Mi(r,4294967295),type:n+(0>e.__dir__?"Right":"")}),e},Mn.prototype[n+"Right"]=function(t){ | |
return this.reverse()[n](t).reverse()}}),u(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;Mn.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:je(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),u(["head","last"],function(n,t){var r="take"+(t?"Right":"");Mn.prototype[n]=function(){return this[r](1).value()[0]}}),u(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Mn.prototype[n]=function(){return this.__filtered__?new Mn(this):this[r](1); | |
}}),Mn.prototype.compact=function(){return this.filter(Nu)},Mn.prototype.find=function(n){return this.filter(n).head()},Mn.prototype.findLast=function(n){return this.reverse().find(n)},Mn.prototype.invokeMap=lr(function(n,t){return typeof n=="function"?new Mn(this):this.map(function(r){return Dt(r,n,t)})}),Mn.prototype.reject=function(n){return this.filter(su(je(n)))},Mn.prototype.slice=function(n,t){n=Ou(n);var r=this;return r.__filtered__&&(0<n||0>t)?new Mn(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)), | |
t!==F&&(t=Ou(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Mn.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Mn.prototype.toArray=function(){return this.take(4294967295)},Et(Mn.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=On[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(On.prototype[t]=function(){function t(n){return n=u.apply(On,s([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Mn,a=f[0],l=c||af(o); | |
l&&r&&typeof a=="function"&&1!=a.length&&(c=l=false);var h=this.__chain__,p=!!this.__actions__.length,a=i&&!h,c=c&&!p;return!i&&l?(o=c?o:new Mn(this),o=n.apply(o,f),o.__actions__.push({func:nu,args:[t],thisArg:F}),new zn(o,h)):a&&c?n.apply(this,f):(o=this.thru(t),a?e?o.value()[0]:o.value():o)})}),u("pop push shift sort splice unshift".split(" "),function(n){var t=ui[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);On.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){ | |
var u=this.value();return t.apply(af(u)?u:[],n)}return this[r](function(r){return t.apply(af(r)?r:[],n)})}}),Et(Mn.prototype,function(n,t){var r=On[t];if(r){var e=r.name+"";(Ji[e]||(Ji[e]=[])).push({name:t,func:r})}}),Ji[Xr(F,2).name]=[{name:"wrapper",func:F}],Mn.prototype.clone=function(){var n=new Mn(this.__wrapped__);return n.__actions__=Mr(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Mr(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Mr(this.__views__), | |
n},Mn.prototype.reverse=function(){if(this.__filtered__){var n=new Mn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Mn.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=af(t),u=0>r,i=e?t.length:0;n=i;for(var o=this.__views__,f=0,c=-1,a=o.length;++c<a;){var l=o[c],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":n-=s;break;case"take":n=Mi(n,f+s);break;case"takeRight":f=Di(f,n-s)}}if(n={start:f,end:n},o=n.start,f=n.end,n=f-o, | |
o=u?f:o-1,f=this.__iteratees__,c=f.length,a=0,l=Mi(n,this.__takeCount__),!e||!u&&i==n&&l==n)return kr(t,this.__actions__);e=[];n:for(;n--&&a<l;){for(o+=r,u=-1,i=t[o];++u<c;){var h=f[u],s=h.type,h=(0,h.iteratee)(i);if(2==s)i=h;else if(!h){if(1==s)continue n;break n}}e[a++]=i}return e},On.prototype.at=Fo,On.prototype.chain=function(){return Xe(this)},On.prototype.commit=function(){return new zn(this.value(),this.__chain__)},On.prototype.next=function(){this.__values__===F&&(this.__values__=ku(this.value())); | |
var n=this.__index__>=this.__values__.length;return{done:n,value:n?F:this.__values__[this.__index__++]}},On.prototype.plant=function(n){for(var t,r=this;r instanceof Sn;){var e=Pe(r);e.__index__=0,e.__values__=F,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},On.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Mn?(this.__actions__.length&&(n=new Mn(this)),n=n.reverse(),n.__actions__.push({func:nu,args:[Je],thisArg:F}),new zn(n,this.__chain__)):this.thru(Je); | |
},On.prototype.toJSON=On.prototype.valueOf=On.prototype.value=function(){return kr(this.__wrapped__,this.__actions__)},On.prototype.first=On.prototype.head,Ai&&(On.prototype[Ai]=tu),On}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Zn._=it, define(function(){return it})):Vn?((Vn.exports=it)._=it,qn._=it):Zn._=it}).call(this);!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(t.d3=t.d3||{})}(this,function(t){"use strict";function n(t){return function(n,e){return Mf(t(n),e)}}function e(t,n){return[t,n]}function r(t,n,e){var r=(n-t)/Math.max(0,e),i=Math.floor(Math.log(r)/Math.LN10),o=r/Math.pow(10,i);return i>=0?(o>=If?10:o>=Hf?5:o>=Bf?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(o>=If?10:o>=Hf?5:o>=Bf?2:1)}function i(t,n,e){var r=Math.abs(n-t)/Math.max(0,e),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),o=r/i;return o>=If?i*=10:o>=Hf?i*=5:o>=Bf&&(i*=2),n<t?-i:i}function o(t){return t.length}function u(t){return"translate("+(t+.5)+",0)"}function a(t){return"translate(0,"+(t+.5)+")"}function c(t){return function(n){return+t(n)}}function s(t){var n=Math.max(0,t.bandwidth()-1)/2;return t.round()&&(n=Math.round(n)),function(e){return+t(e)+n}}function f(){return!this.__axis}function l(t,n){function e(e){var u=null==i?n.ticks?n.ticks.apply(n,r):n.domain():i,a=null==o?n.tickFormat?n.tickFormat.apply(n,r):cl:o,y=Math.max(l,0)+p,_=n.range(),m=+_[0]+.5,x=+_[_.length-1]+.5,b=(n.bandwidth?s:c)(n.copy()),w=e.selection?e.selection():e,M=w.selectAll(".domain").data([null]),T=w.selectAll(".tick").data(u,n).order(),N=T.exit(),k=T.enter().append("g").attr("class","tick"),S=T.select("line"),A=T.select("text");M=M.merge(M.enter().insert("path",".tick").attr("class","domain").attr("stroke","#000")),T=T.merge(k),S=S.merge(k.append("line").attr("stroke","#000").attr(v+"2",d*l)),A=A.merge(k.append("text").attr("fill","#000").attr(v,d*y).attr("dy",t===sl?"0em":t===ll?"0.71em":"0.32em")),e!==w&&(M=M.transition(e),T=T.transition(e),S=S.transition(e),A=A.transition(e),N=N.transition(e).attr("opacity",pl).attr("transform",function(t){return isFinite(t=b(t))?g(t):this.getAttribute("transform")}),k.attr("opacity",pl).attr("transform",function(t){var n=this.parentNode.__axis;return g(n&&isFinite(n=n(t))?n:b(t))})),N.remove(),M.attr("d",t===hl||t==fl?"M"+d*h+","+m+"H0.5V"+x+"H"+d*h:"M"+m+","+d*h+"V0.5H"+x+"V"+d*h),T.attr("opacity",1).attr("transform",function(t){return g(b(t))}),S.attr(v+"2",d*l),A.attr(v,d*y).text(a),w.filter(f).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===fl?"start":t===hl?"end":"middle"),w.each(function(){this.__axis=b})}var r=[],i=null,o=null,l=6,h=6,p=3,d=t===sl||t===hl?-1:1,v=t===hl||t===fl?"x":"y",g=t===sl||t===ll?u:a;return e.scale=function(t){return arguments.length?(n=t,e):n},e.ticks=function(){return r=al.call(arguments),e},e.tickArguments=function(t){return arguments.length?(r=null==t?[]:al.call(t),e):r.slice()},e.tickValues=function(t){return arguments.length?(i=null==t?null:al.call(t),e):i&&i.slice()},e.tickFormat=function(t){return arguments.length?(o=t,e):o},e.tickSize=function(t){return arguments.length?(l=h=+t,e):l},e.tickSizeInner=function(t){return arguments.length?(l=+t,e):l},e.tickSizeOuter=function(t){return arguments.length?(h=+t,e):h},e.tickPadding=function(t){return arguments.length?(p=+t,e):p},e}function h(t){return l(sl,t)}function p(t){return l(fl,t)}function d(t){return l(ll,t)}function v(t){return l(hl,t)}function g(){for(var t,n=0,e=arguments.length,r={};n<e;++n){if(!(t=arguments[n]+"")||t in r)throw new Error("illegal type: "+t);r[t]=[]}return new y(r)}function y(t){this._=t}function _(t,n){return t.trim().split(/^|\s+/).map(function(t){var e="",r=t.indexOf(".");if(r>=0&&(e=t.slice(r+1),t=t.slice(0,r)),t&&!n.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}})}function m(t,n){for(var e,r=0,i=t.length;r<i;++r)if((e=t[r]).name===n)return e.value}function x(t,n,e){for(var r=0,i=t.length;r<i;++r)if(t[r].name===n){t[r]=dl,t=t.slice(0,r).concat(t.slice(r+1));break}return null!=e&&t.push({name:n,value:e}),t}function b(t){return function(){var n=this.ownerDocument,e=this.namespaceURI;return e===vl&&n.documentElement.namespaceURI===vl?n.createElement(t):n.createElementNS(e,t)}}function w(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function M(){return new T}function T(){this._="@"+(++ml).toString(36)}function N(t,n,e){return t=k(t,n,e),function(n){var e=n.relatedTarget;e&&(e===this||8&e.compareDocumentPosition(this))||t.call(this,n)}}function k(n,e,r){return function(i){var o=t.event;t.event=i;try{n.call(this,this.__data__,e,r)}finally{t.event=o}}}function S(t){return t.trim().split(/^|\s+/).map(function(t){var n="",e=t.indexOf(".");return e>=0&&(n=t.slice(e+1),t=t.slice(0,e)),{type:t,name:n}})}function A(t){return function(){var n=this.__on;if(n){for(var e,r=0,i=-1,o=n.length;r<o;++r)e=n[r],t.type&&e.type!==t.type||e.name!==t.name?n[++i]=e:this.removeEventListener(e.type,e.listener,e.capture);++i?n.length=i:delete this.__on}}}function E(t,n,e){var r=Tl.hasOwnProperty(t.type)?N:k;return function(i,o,u){var a,c=this.__on,s=r(n,o,u);if(c)for(var f=0,l=c.length;f<l;++f)if((a=c[f]).type===t.type&&a.name===t.name)return this.removeEventListener(a.type,a.listener,a.capture),this.addEventListener(a.type,a.listener=s,a.capture=e),void(a.value=n);this.addEventListener(t.type,s,e),a={type:t.type,name:t.name,value:n,listener:s,capture:e},c?c.push(a):this.__on=[a]}}function C(n,e,r,i){var o=t.event;n.sourceEvent=t.event,t.event=n;try{return e.apply(r,i)}finally{t.event=o}}function z(){}function P(){return[]}function R(t,n){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=n}function L(t,n,e,r,i,o){for(var u,a=0,c=n.length,s=o.length;a<s;++a)(u=n[a])?(u.__data__=o[a],r[a]=u):e[a]=new R(t,o[a]);for(;a<c;++a)(u=n[a])&&(i[a]=u)}function D(t,n,e,r,i,o,u){var a,c,s,f={},l=n.length,h=o.length,p=new Array(l);for(a=0;a<l;++a)(c=n[a])&&(p[a]=s=Ul+u.call(c,c.__data__,a,n),s in f?i[a]=c:f[s]=c);for(a=0;a<h;++a)s=Ul+u.call(t,o[a],a,o),(c=f[s])?(r[a]=c,c.__data__=o[a],f[s]=null):e[a]=new R(t,o[a]);for(a=0;a<l;++a)(c=n[a])&&f[p[a]]===c&&(i[a]=c)}function q(t,n){return t<n?-1:t>n?1:t>=n?0:NaN}function U(t){return function(){this.removeAttribute(t)}}function O(t){return function(){this.removeAttributeNS(t.space,t.local)}}function F(t,n){return function(){this.setAttribute(t,n)}}function Y(t,n){return function(){this.setAttributeNS(t.space,t.local,n)}}function I(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttribute(t):this.setAttribute(t,e)}}function H(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,e)}}function B(t){return function(){this.style.removeProperty(t)}}function j(t,n,e){return function(){this.style.setProperty(t,n,e)}}function X(t,n,e){return function(){var r=n.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,e)}}function W(t,n){return t.style.getPropertyValue(n)||Gl(t).getComputedStyle(t,null).getPropertyValue(n)}function V(t){return function(){delete this[t]}}function $(t,n){return function(){this[t]=n}}function Z(t,n){return function(){var e=n.apply(this,arguments);null==e?delete this[t]:this[t]=e}}function G(t){return t.trim().split(/^|\s+/)}function Q(t){return t.classList||new J(t)}function J(t){this._node=t,this._names=G(t.getAttribute("class")||"")}function K(t,n){for(var e=Q(t),r=-1,i=n.length;++r<i;)e.add(n[r])}function tt(t,n){for(var e=Q(t),r=-1,i=n.length;++r<i;)e.remove(n[r])}function nt(t){return function(){K(this,t)}}function et(t){return function(){tt(this,t)}}function rt(t,n){return function(){(n.apply(this,arguments)?K:tt)(this,t)}}function it(){this.textContent=""}function ot(t){return function(){this.textContent=t}}function ut(t){return function(){var n=t.apply(this,arguments);this.textContent=null==n?"":n}}function at(){this.innerHTML=""}function ct(t){return function(){this.innerHTML=t}}function st(t){return function(){var n=t.apply(this,arguments);this.innerHTML=null==n?"":n}}function ft(){this.nextSibling&&this.parentNode.appendChild(this)}function lt(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function ht(){return null}function pt(){var t=this.parentNode;t&&t.removeChild(this)}function dt(t,n,e){var r=Gl(t),i=r.CustomEvent;"function"==typeof i?i=new i(n,e):(i=r.document.createEvent("Event"),e?(i.initEvent(n,e.bubbles,e.cancelable),i.detail=e.detail):i.initEvent(n,!1,!1)),t.dispatchEvent(i)}function vt(t,n){return function(){return dt(this,t,n)}}function gt(t,n){return function(){return dt(this,t,n.apply(this,arguments))}}function yt(t,n){this._groups=t,this._parents=n}function _t(){return new yt([[document.documentElement]],sh)}function mt(){t.event.stopImmediatePropagation()}function xt(t,n){var e=t.document.documentElement,r=fh(t).on("dragstart.drag",null);n&&(r.on("click.drag",dh,!0),setTimeout(function(){r.on("click.drag",null)},0)),"onselectstart"in e?r.on("selectstart.drag",null):(e.style.MozUserSelect=e.__noselect,delete e.__noselect)}function bt(t,n,e,r,i,o,u,a,c,s){this.target=t,this.type=n,this.subject=e,this.identifier=r,this.active=i,this.x=o,this.y=u,this.dx=a,this.dy=c,this._=s}function wt(){return!t.event.button}function Mt(){return this.parentNode}function Tt(n){return null==n?{x:t.event.x,y:t.event.y}:n}function Nt(){return"ontouchstart"in this}function kt(t,n){var e=Object.create(t.prototype);for(var r in n)e[r]=n[r];return e}function St(){}function At(t){var n;return t=(t+"").trim().toLowerCase(),(n=wh.exec(t))?(n=parseInt(n[1],16),new Rt(n>>8&15|n>>4&240,n>>4&15|240&n,(15&n)<<4|15&n,1)):(n=Mh.exec(t))?Et(parseInt(n[1],16)):(n=Th.exec(t))?new Rt(n[1],n[2],n[3],1):(n=Nh.exec(t))?new Rt(255*n[1]/100,255*n[2]/100,255*n[3]/100,1):(n=kh.exec(t))?Ct(n[1],n[2],n[3],n[4]):(n=Sh.exec(t))?Ct(255*n[1]/100,255*n[2]/100,255*n[3]/100,n[4]):(n=Ah.exec(t))?Lt(n[1],n[2]/100,n[3]/100,1):(n=Eh.exec(t))?Lt(n[1],n[2]/100,n[3]/100,n[4]):Ch.hasOwnProperty(t)?Et(Ch[t]):"transparent"===t?new Rt(NaN,NaN,NaN,0):null}function Et(t){return new Rt(t>>16&255,t>>8&255,255&t,1)}function Ct(t,n,e,r){return r<=0&&(t=n=e=NaN),new Rt(t,n,e,r)}function zt(t){return t instanceof St||(t=At(t)),t?(t=t.rgb(),new Rt(t.r,t.g,t.b,t.opacity)):new Rt}function Pt(t,n,e,r){return 1===arguments.length?zt(t):new Rt(t,n,e,null==r?1:r)}function Rt(t,n,e,r){this.r=+t,this.g=+n,this.b=+e,this.opacity=+r}function Lt(t,n,e,r){return r<=0?t=n=e=NaN:e<=0||e>=1?t=n=NaN:n<=0&&(t=NaN),new Ut(t,n,e,r)}function Dt(t){if(t instanceof Ut)return new Ut(t.h,t.s,t.l,t.opacity);if(t instanceof St||(t=At(t)),!t)return new Ut;if(t instanceof Ut)return t;t=t.rgb();var n=t.r/255,e=t.g/255,r=t.b/255,i=Math.min(n,e,r),o=Math.max(n,e,r),u=NaN,a=o-i,c=(o+i)/2;return a?(u=n===o?(e-r)/a+6*(e<r):e===o?(r-n)/a+2:(n-e)/a+4,a/=c<.5?o+i:2-o-i,u*=60):a=c>0&&c<1?0:u,new Ut(u,a,c,t.opacity)}function qt(t,n,e,r){return 1===arguments.length?Dt(t):new Ut(t,n,e,null==r?1:r)}function Ut(t,n,e,r){this.h=+t,this.s=+n,this.l=+e,this.opacity=+r}function Ot(t,n,e){return 255*(t<60?n+(e-n)*t/60:t<180?e:t<240?n+(e-n)*(240-t)/60:n)}function Ft(t){if(t instanceof It)return new It(t.l,t.a,t.b,t.opacity);if(t instanceof $t){var n=t.h*zh;return new It(t.l,Math.cos(n)*t.c,Math.sin(n)*t.c,t.opacity)}t instanceof Rt||(t=zt(t));var e=Xt(t.r),r=Xt(t.g),i=Xt(t.b),o=Ht((.4124564*e+.3575761*r+.1804375*i)/Rh),u=Ht((.2126729*e+.7151522*r+.072175*i)/Lh);return new It(116*u-16,500*(o-u),200*(u-Ht((.0193339*e+.119192*r+.9503041*i)/Dh)),t.opacity)}function Yt(t,n,e,r){return 1===arguments.length?Ft(t):new It(t,n,e,null==r?1:r)}function It(t,n,e,r){this.l=+t,this.a=+n,this.b=+e,this.opacity=+r}function Ht(t){return t>Fh?Math.pow(t,1/3):t/Oh+qh}function Bt(t){return t>Uh?t*t*t:Oh*(t-qh)}function jt(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function Xt(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Wt(t){if(t instanceof $t)return new $t(t.h,t.c,t.l,t.opacity);t instanceof It||(t=Ft(t));var n=Math.atan2(t.b,t.a)*Ph;return new $t(n<0?n+360:n,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function Vt(t,n,e,r){return 1===arguments.length?Wt(t):new $t(t,n,e,null==r?1:r)}function $t(t,n,e,r){this.h=+t,this.c=+n,this.l=+e,this.opacity=+r}function Zt(t){if(t instanceof Qt)return new Qt(t.h,t.s,t.l,t.opacity);t instanceof Rt||(t=zt(t));var n=t.r/255,e=t.g/255,r=t.b/255,i=(Vh*r+Xh*n-Wh*e)/(Vh+Xh-Wh),o=r-i,u=(jh*(e-i)-Hh*o)/Bh,a=Math.sqrt(u*u+o*o)/(jh*i*(1-i)),c=a?Math.atan2(u,o)*Ph-120:NaN;return new Qt(c<0?c+360:c,a,i,t.opacity)}function Gt(t,n,e,r){return 1===arguments.length?Zt(t):new Qt(t,n,e,null==r?1:r)}function Qt(t,n,e,r){this.h=+t,this.s=+n,this.l=+e,this.opacity=+r}function Jt(t,n,e,r,i){var o=t*t,u=o*t;return((1-3*t+3*o-u)*n+(4-6*o+3*u)*e+(1+3*t+3*o-3*u)*r+u*i)/6}function Kt(t,n){return function(e){return t+e*n}}function tn(t,n,e){return t=Math.pow(t,e),n=Math.pow(n,e)-t,e=1/e,function(r){return Math.pow(t+r*n,e)}}function nn(t,n){var e=n-t;return e?Kt(t,e>180||e<-180?e-360*Math.round(e/360):e):ep(isNaN(t)?n:t)}function en(t){return 1==(t=+t)?rn:function(n,e){return e-n?tn(n,e,t):ep(isNaN(n)?e:n)}}function rn(t,n){var e=n-t;return e?Kt(t,e):ep(isNaN(t)?n:t)}function on(t){return function(n){var e,r,i=n.length,o=new Array(i),u=new Array(i),a=new Array(i);for(e=0;e<i;++e)r=Pt(n[e]),o[e]=r.r||0,u[e]=r.g||0,a[e]=r.b||0;return o=t(o),u=t(u),a=t(a),r.opacity=1,function(t){return r.r=o(t),r.g=u(t),r.b=a(t),r+""}}}function un(t){return function(){return t}}function an(t){return function(n){return t(n)+""}}function cn(t){return"none"===t?gp:($h||($h=document.createElement("DIV"),Zh=document.documentElement,Gh=document.defaultView),$h.style.transform=t,t=Gh.getComputedStyle(Zh.appendChild($h),null).getPropertyValue("transform"),Zh.removeChild($h),t=t.slice(7,-1).split(","),yp(+t[0],+t[1],+t[2],+t[3],+t[4],+t[5]))}function sn(t){return null==t?gp:(Qh||(Qh=document.createElementNS("http://www.w3.org/2000/svg","g")),Qh.setAttribute("transform",t),(t=Qh.transform.baseVal.consolidate())?(t=t.matrix,yp(t.a,t.b,t.c,t.d,t.e,t.f)):gp)}function fn(t,n,e,r){function i(t){return t.length?t.pop()+" ":""}function o(t,r,i,o,u,a){if(t!==i||r!==o){var c=u.push("translate(",null,n,null,e);a.push({i:c-4,x:cp(t,i)},{i:c-2,x:cp(r,o)})}else(i||o)&&u.push("translate("+i+n+o+e)}function u(t,n,e,o){t!==n?(t-n>180?n+=360:n-t>180&&(t+=360),o.push({i:e.push(i(e)+"rotate(",null,r)-2,x:cp(t,n)})):n&&e.push(i(e)+"rotate("+n+r)}function a(t,n,e,o){t!==n?o.push({i:e.push(i(e)+"skewX(",null,r)-2,x:cp(t,n)}):n&&e.push(i(e)+"skewX("+n+r)}function c(t,n,e,r,o,u){if(t!==e||n!==r){var a=o.push(i(o)+"scale(",null,",",null,")");u.push({i:a-4,x:cp(t,e)},{i:a-2,x:cp(n,r)})}else 1===e&&1===r||o.push(i(o)+"scale("+e+","+r+")")}return function(n,e){var r=[],i=[];return n=t(n),e=t(e),o(n.translateX,n.translateY,e.translateX,e.translateY,r,i),u(n.rotate,e.rotate,r,i),a(n.skewX,e.skewX,r,i),c(n.scaleX,n.scaleY,e.scaleX,e.scaleY,r,i),n=e=null,function(t){for(var n,e=-1,o=i.length;++e<o;)r[(n=i[e]).i]=n.x(t);return r.join("")}}}function ln(t){return((t=Math.exp(t))+1/t)/2}function hn(t){return((t=Math.exp(t))-1/t)/2}function pn(t){return((t=Math.exp(2*t))-1)/(t+1)}function dn(t){return function(n,e){var r=t((n=qt(n)).h,(e=qt(e)).h),i=rn(n.s,e.s),o=rn(n.l,e.l),u=rn(n.opacity,e.opacity);return function(t){return n.h=r(t),n.s=i(t),n.l=o(t),n.opacity=u(t),n+""}}}function vn(t,n){var e=rn((t=Yt(t)).l,(n=Yt(n)).l),r=rn(t.a,n.a),i=rn(t.b,n.b),o=rn(t.opacity,n.opacity);return function(n){return t.l=e(n),t.a=r(n),t.b=i(n),t.opacity=o(n),t+""}}function gn(t){return function(n,e){var r=t((n=Vt(n)).h,(e=Vt(e)).h),i=rn(n.c,e.c),o=rn(n.l,e.l),u=rn(n.opacity,e.opacity);return function(t){return n.h=r(t),n.c=i(t),n.l=o(t),n.opacity=u(t),n+""}}}function yn(t){return function n(e){function r(n,r){var i=t((n=Gt(n)).h,(r=Gt(r)).h),o=rn(n.s,r.s),u=rn(n.l,r.l),a=rn(n.opacity,r.opacity);return function(t){return n.h=i(t),n.s=o(t),n.l=u(Math.pow(t,e)),n.opacity=a(t),n+""}}return e=+e,r.gamma=n,r}(1)}function _n(){return Lp||(Up(mn),Lp=qp.now()+Dp)}function mn(){Lp=0}function xn(){this._call=this._time=this._next=null}function bn(t,n,e){var r=new xn;return r.restart(t,n,e),r}function wn(){_n(),++Ep;for(var t,n=Jh;n;)(t=Lp-n._time)>=0&&n._call.call(null,t),n=n._next;--Ep}function Mn(){Lp=(Rp=qp.now())+Dp,Ep=Cp=0;try{wn()}finally{Ep=0,Nn(),Lp=0}}function Tn(){var t=qp.now(),n=t-Rp;n>Pp&&(Dp-=n,Rp=t)}function Nn(){for(var t,n,e=Jh,r=1/0;e;)e._call?(r>e._time&&(r=e._time),t=e,e=e._next):(n=e._next,e._next=null,e=t?t._next=n:Jh=n);Kh=t,kn(r)}function kn(t){if(!Ep){Cp&&(Cp=clearTimeout(Cp));t-Lp>24?(t<1/0&&(Cp=setTimeout(Mn,t-qp.now()-Dp)),zp&&(zp=clearInterval(zp))):(zp||(Rp=qp.now(),zp=setInterval(Tn,Pp)),Ep=1,Up(Mn))}}function Sn(t,n){var e=En(t,n);if(e.state>Hp)throw new Error("too late; already scheduled");return e}function An(t,n){var e=En(t,n);if(e.state>jp)throw new Error("too late; already started");return e}function En(t,n){var e=t.__transition;if(!e||!(e=e[n]))throw new Error("transition not found");return e}function Cn(t,n,e){function r(t){e.state=Bp,e.timer.restart(i,e.delay,e.time),e.delay<=t&&i(t-e.delay)}function i(r){var s,f,l,h;if(e.state!==Bp)return u();for(s in c)if(h=c[s],h.name===e.name){if(h.state===Xp)return Op(i);h.state===Wp?(h.state=$p,h.timer.stop(),h.on.call("interrupt",t,t.__data__,h.index,h.group),delete c[s]):+s<n&&(h.state=$p,h.timer.stop(),delete c[s])}if(Op(function(){e.state===Xp&&(e.state=Wp,e.timer.restart(o,e.delay,e.time),o(r))}),e.state=jp,e.on.call("start",t,t.__data__,e.index,e.group),e.state===jp){for(e.state=Xp,a=new Array(l=e.tween.length),s=0,f=-1;s<l;++s)(h=e.tween[s].value.call(t,t.__data__,e.index,e.group))&&(a[++f]=h);a.length=f+1}}function o(n){for(var r=n<e.duration?e.ease.call(null,n/e.duration):(e.timer.restart(u),e.state=Vp,1),i=-1,o=a.length;++i<o;)a[i].call(null,r);e.state===Vp&&(e.on.call("end",t,t.__data__,e.index,e.group),u())}function u(){e.state=$p,e.timer.stop(),delete c[n];for(var r in c)return;delete t.__transition}var a,c=t.__transition;c[n]=e,e.timer=bn(r,0,e.time)}function zn(t,n){var e,r;return function(){var i=An(this,t),o=i.tween;if(o!==e){r=e=o;for(var u=0,a=r.length;u<a;++u)if(r[u].name===n){r=r.slice(),r.splice(u,1);break}}i.tween=r}}function Pn(t,n,e){var r,i;if("function"!=typeof e)throw new Error;return function(){var o=An(this,t),u=o.tween;if(u!==r){i=(r=u).slice();for(var a={name:n,value:e},c=0,s=i.length;c<s;++c)if(i[c].name===n){i[c]=a;break}c===s&&i.push(a)}o.tween=i}}function Rn(t,n,e){var r=t._id;return t.each(function(){var t=An(this,r);(t.value||(t.value={}))[n]=e.apply(this,arguments)}),function(t){return En(t,r).value[n]}}function Ln(t){return function(){this.removeAttribute(t)}}function Dn(t){return function(){this.removeAttributeNS(t.space,t.local)}}function qn(t,n,e){var r,i;return function(){var o=this.getAttribute(t);return o===e?null:o===r?i:i=n(r=o,e)}}function Un(t,n,e){var r,i;return function(){var o=this.getAttributeNS(t.space,t.local);return o===e?null:o===r?i:i=n(r=o,e)}}function On(t,n,e){var r,i,o;return function(){var u,a=e(this);return null==a?void this.removeAttribute(t):(u=this.getAttribute(t),u===a?null:u===r&&a===i?o:o=n(r=u,i=a))}}function Fn(t,n,e){var r,i,o;return function(){var u,a=e(this);return null==a?void this.removeAttributeNS(t.space,t.local):(u=this.getAttributeNS(t.space,t.local),u===a?null:u===r&&a===i?o:o=n(r=u,i=a))}}function Yn(t,n){function e(){var e=this,r=n.apply(e,arguments);return r&&function(n){e.setAttributeNS(t.space,t.local,r(n))}}return e._value=n,e}function In(t,n){function e(){var e=this,r=n.apply(e,arguments);return r&&function(n){e.setAttribute(t,r(n))}}return e._value=n,e}function Hn(t,n){return function(){Sn(this,t).delay=+n.apply(this,arguments)}}function Bn(t,n){return n=+n,function(){Sn(this,t).delay=n}}function jn(t,n){return function(){An(this,t).duration=+n.apply(this,arguments)}}function Xn(t,n){return n=+n,function(){An(this,t).duration=n}}function Wn(t,n){if("function"!=typeof n)throw new Error;return function(){An(this,t).ease=n}}function Vn(t){return(t+"").trim().split(/^|\s+/).every(function(t){var n=t.indexOf(".");return n>=0&&(t=t.slice(0,n)),!t||"start"===t})}function $n(t,n,e){var r,i,o=Vn(n)?Sn:An;return function(){var u=o(this,t),a=u.on;a!==r&&(i=(r=a).copy()).on(n,e),u.on=i}}function Zn(t){return function(){var n=this.parentNode;for(var e in this.__transition)if(+e!==t)return;n&&n.removeChild(this)}}function Gn(t,n){var e,r,i;return function(){var o=W(this,t),u=(this.style.removeProperty(t),W(this,t));return o===u?null:o===e&&u===r?i:i=n(e=o,r=u)}}function Qn(t){return function(){this.style.removeProperty(t)}}function Jn(t,n,e){var r,i;return function(){var o=W(this,t);return o===e?null:o===r?i:i=n(r=o,e)}}function Kn(t,n,e){var r,i,o;return function(){var u=W(this,t),a=e(this);return null==a&&(this.style.removeProperty(t),a=W(this,t)),u===a?null:u===r&&a===i?o:o=n(r=u,i=a)}}function te(t,n,e){function r(){var r=this,i=n.apply(r,arguments);return i&&function(n){r.style.setProperty(t,i(n),e)}}return r._value=n,r}function ne(t){return function(){this.textContent=t}}function ee(t){return function(){var n=t(this);this.textContent=null==n?"":n}}function re(t,n,e,r){this._groups=t,this._parents=n,this._name=e,this._id=r}function ie(t){return _t().transition(t)}function oe(){return++yd}function ue(t){return+t}function ae(t){return t*t}function ce(t){return t*(2-t)}function se(t){return((t*=2)<=1?t*t:--t*(2-t)+1)/2}function fe(t){return t*t*t}function le(t){return--t*t*t+1}function he(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}function pe(t){return 1-Math.cos(t*Md)}function de(t){return Math.sin(t*Md)}function ve(t){return(1-Math.cos(wd*t))/2}function ge(t){return Math.pow(2,10*t-10)}function ye(t){return 1-Math.pow(2,-10*t)}function _e(t){return((t*=2)<=1?Math.pow(2,10*t-10):2-Math.pow(2,10-10*t))/2}function me(t){return 1-Math.sqrt(1-t*t)}function xe(t){return Math.sqrt(1- --t*t)}function be(t){return((t*=2)<=1?1-Math.sqrt(1-t*t):Math.sqrt(1-(t-=2)*t)+1)/2}function we(t){return 1-Me(1-t)}function Me(t){return(t=+t)<Td?Rd*t*t:t<kd?Rd*(t-=Nd)*t+Sd:t<Ed?Rd*(t-=Ad)*t+Cd:Rd*(t-=zd)*t+Pd}function Te(t){return((t*=2)<=1?1-Me(1-t):Me(t-1)+1)/2}function Ne(t,n){for(var e;!(e=t.__transition)||!(e=e[n]);)if(!(t=t.parentNode))return Id.time=_n(),Id;return e}function ke(){t.event.stopImmediatePropagation()}function Se(t){return{type:t}}function Ae(){return!t.event.button}function Ee(){var t=this.ownerSVGElement||this;return[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]}function Ce(t){for(;!t.__brush;)if(!(t=t.parentNode))return;return t.__brush}function ze(t){return t[0][0]===t[1][0]||t[0][1]===t[1][1]}function Pe(t){var n=t.__brush;return n?n.dim.output(n.selection):null}function Re(){return De(Jd)}function Le(){return De(Kd)}function De(n){function e(t){var e=t.property("__brush",a).selectAll(".overlay").data([Se("overlay")]);e.enter().append("rect").attr("class","overlay").attr("pointer-events","all").attr("cursor",nv.overlay).merge(e).each(function(){var t=Ce(this).extent;fh(this).attr("x",t[0][0]).attr("y",t[0][1]).attr("width",t[1][0]-t[0][0]).attr("height",t[1][1]-t[0][1])}),t.selectAll(".selection").data([Se("selection")]).enter().append("rect").attr("class","selection").attr("cursor",nv.selection).attr("fill","#777").attr("fill-opacity",.3).attr("stroke","#fff").attr("shape-rendering","crispEdges");var i=t.selectAll(".handle").data(n.handles,function(t){return t.type});i.exit().remove(),i.enter().append("rect").attr("class",function(t){return"handle handle--"+t.type}).attr("cursor",function(t){return nv[t.type]}),t.each(r).attr("fill","none").attr("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush touchstart.brush",u)}function r(){var t=fh(this),n=Ce(this).selection;n?(t.selectAll(".selection").style("display",null).attr("x",n[0][0]).attr("y",n[0][1]).attr("width",n[1][0]-n[0][0]).attr("height",n[1][1]-n[0][1]),t.selectAll(".handle").style("display",null).attr("x",function(t){return"e"===t.type[t.type.length-1]?n[1][0]-h/2:n[0][0]-h/2}).attr("y",function(t){return"s"===t.type[0]?n[1][1]-h/2:n[0][1]-h/2}).attr("width",function(t){return"n"===t.type||"s"===t.type?n[1][0]-n[0][0]+h:h}).attr("height",function(t){return"e"===t.type||"w"===t.type?n[1][1]-n[0][1]+h:h})):t.selectAll(".selection,.handle").style("display","none").attr("x",null).attr("y",null).attr("width",null).attr("height",null)}function i(t,n){return t.__brush.emitter||new o(t,n)}function o(t,n){this.that=t,this.args=n,this.state=t.__brush,this.active=0}function u(){function e(){var t=Al(T);!q||w||M||(Math.abs(t[0]-O[0])>Math.abs(t[1]-O[1])?M=!0:w=!0),O=t,b=!0,Vd(),o()}function o(){var t;switch(m=O[0]-U[0],x=O[1]-U[1],k){case Zd:case $d:S&&(m=Math.max(P-l,Math.min(L-v,m)),h=l+m,g=v+m),A&&(x=Math.max(R-p,Math.min(D-y,x)),d=p+x,_=y+x);break;case Gd:S<0?(m=Math.max(P-l,Math.min(L-l,m)),h=l+m,g=v):S>0&&(m=Math.max(P-v,Math.min(L-v,m)),h=l,g=v+m),A<0?(x=Math.max(R-p,Math.min(D-p,x)),d=p+x,_=y):A>0&&(x=Math.max(R-y,Math.min(D-y,x)),d=p,_=y+x);break;case Qd:S&&(h=Math.max(P,Math.min(L,l-m*S)),g=Math.max(P,Math.min(L,v+m*S))),A&&(d=Math.max(R,Math.min(D,p-x*A)),_=Math.max(R,Math.min(D,y+x*A)))}g<h&&(S*=-1,t=l,l=v,v=t,t=h,h=g,g=t,N in ev&&I.attr("cursor",nv[N=ev[N]])),_<d&&(A*=-1,t=p,p=y,y=t,t=d,d=_,_=t,N in rv&&I.attr("cursor",nv[N=rv[N]])),E.selection&&(z=E.selection),w&&(h=z[0][0],g=z[1][0]),M&&(d=z[0][1],_=z[1][1]),z[0][0]===h&&z[0][1]===d&&z[1][0]===g&&z[1][1]===_||(E.selection=[[h,d],[g,_]],r.call(T),F.brush())}function u(){if(ke(),t.event.touches){if(t.event.touches.length)return;c&&clearTimeout(c),c=setTimeout(function(){c=null},500),Y.on("touchmove.brush touchend.brush touchcancel.brush",null)}else xt(t.event.view,b),H.on("keydown.brush keyup.brush mousemove.brush mouseup.brush",null);Y.attr("pointer-events","all"),I.attr("cursor",nv.overlay),E.selection&&(z=E.selection),ze(z)&&(E.selection=null,r.call(T)),F.end()}function a(){switch(t.event.keyCode){case 16:q=S&&A;break;case 18:k===Gd&&(S&&(v=g-m*S,l=h+m*S),A&&(y=_-x*A,p=d+x*A),k=Qd,o());break;case 32:k!==Gd&&k!==Qd||(S<0?v=g-m:S>0&&(l=h-m),A<0?y=_-x:A>0&&(p=d-x),k=Zd,I.attr("cursor",nv.selection),o());break;default:return}Vd()}function s(){switch(t.event.keyCode){case 16:q&&(w=M=q=!1,o());break;case 18:k===Qd&&(S<0?v=g:S>0&&(l=h),A<0?y=_:A>0&&(p=d),k=Gd,o());break;case 32:k===Zd&&(t.event.altKey?(S&&(v=g-m*S,l=h+m*S),A&&(y=_-x*A,p=d+x*A),k=Qd):(S<0?v=g:S>0&&(l=h),A<0?y=_:A>0&&(p=d),k=Gd),I.attr("cursor",nv[N]),o());break;default:return}Vd()}if(t.event.touches){if(t.event.changedTouches.length<t.event.touches.length)return Vd()}else if(c)return;if(f.apply(this,arguments)){var l,h,p,d,v,g,y,_,m,x,b,w,M,T=this,N=t.event.target.__data__.type,k="selection"===(t.event.metaKey?N="overlay":N)?$d:t.event.altKey?Qd:Gd,S=n===Kd?null:iv[N],A=n===Jd?null:ov[N],E=Ce(T),C=E.extent,z=E.selection,P=C[0][0],R=C[0][1],L=C[1][0],D=C[1][1],q=S&&A&&t.event.shiftKey,U=Al(T),O=U,F=i(T,arguments).beforestart();"overlay"===N?E.selection=z=[[l=n===Kd?P:U[0],p=n===Jd?R:U[1]],[v=n===Kd?L:l,y=n===Jd?D:p]]:(l=z[0][0],p=z[0][1],v=z[1][0],y=z[1][1]),h=l,d=p,g=v,_=y;var Y=fh(T).attr("pointer-events","none"),I=Y.selectAll(".overlay").attr("cursor",nv[N]);if(t.event.touches)Y.on("touchmove.brush",e,!0).on("touchend.brush touchcancel.brush",u,!0);else{var H=fh(t.event.view).on("keydown.brush",a,!0).on("keyup.brush",s,!0).on("mousemove.brush",e,!0).on("mouseup.brush",u,!0);vh(t.event.view)}ke(),Gp(T),r.call(T),F.start()}}function a(){var t=this.__brush||{selection:null};return t.extent=s.apply(this,arguments),t.dim=n,t}var c,s=Ee,f=Ae,l=g(e,"start","brush","end"),h=6;return e.move=function(t,e){t.selection?t.on("start.brush",function(){i(this,arguments).beforestart().start()}).on("interrupt.brush end.brush",function(){i(this,arguments).end()}).tween("brush",function(){function t(t){u.selection=1===t&&ze(s)?null:f(t),r.call(o),a.brush()}var o=this,u=o.__brush,a=i(o,arguments),c=u.selection,s=n.input("function"==typeof e?e.apply(this,arguments):e,u.extent),f=pp(c,s);return c&&s?t:t(1)}):t.each(function(){var t=this,o=arguments,u=t.__brush,a=n.input("function"==typeof e?e.apply(t,o):e,u.extent),c=i(t,o).beforestart();Gp(t),u.selection=null==a||ze(a)?null:a,r.call(t),c.start().brush().end()})},o.prototype={beforestart:function(){return 1==++this.active&&(this.state.emitter=this,this.starting=!0),this},start:function(){return this.starting&&(this.starting=!1,this.emit("start")),this},brush:function(){return this.emit("brush"),this},end:function(){return 0==--this.active&&(delete this.state.emitter,this.emit("end")),this},emit:function(t){C(new Wd(e,t,n.output(this.state.selection)),l.apply,l,[t,this.that,this.args])}},e.extent=function(t){return arguments.length?(s="function"==typeof t?t:Xd([[+t[0][0],+t[0][1]],[+t[1][0],+t[1][1]]]),e):s},e.filter=function(t){return arguments.length?(f="function"==typeof t?t:Xd(!!t),e):f},e.handleSize=function(t){return arguments.length?(h=+t,e):h},e.on=function(){var t=l.on.apply(l,arguments);return t===l?e:t},e}function qe(t){return function(n,e){return t(n.source.value+n.target.value,e.source.value+e.target.value)}}function Ue(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function Oe(){return new Ue}function Fe(t){return t.source}function Ye(t){return t.target}function Ie(t){return t.radius}function He(t){return t.startAngle}function Be(t){return t.endAngle}function je(){}function Xe(t,n){var e=new je;if(t instanceof je)t.each(function(t,n){e.set(n,t)});else if(Array.isArray(t)){var r,i=-1,o=t.length;if(null==n)for(;++i<o;)e.set(i,t[i]);else for(;++i<o;)e.set(n(r=t[i],i,t),r)}else if(t)for(var u in t)e.set(u,t[u]);return e}function We(){return{}}function Ve(t,n,e){t[n]=e}function $e(){return Xe()}function Ze(t,n,e){t.set(n,e)}function Ge(){}function Qe(t,n){var e=new Ge;if(t instanceof Ge)t.each(function(t){e.add(t)});else if(t){var r=-1,i=t.length;if(null==n)for(;++r<i;)e.add(t[r]);else for(;++r<i;)e.add(n(t[r],r,t))}return e}function Je(t){return new Function("d","return {"+t.map(function(t,n){return JSON.stringify(t)+": d["+n+"]"}).join(",")+"}")}function Ke(t,n){var e=Je(t);return function(r,i){return n(e(r),i,t)}}function tr(t){var n=Object.create(null),e=[];return t.forEach(function(t){for(var r in t)r in n||e.push(n[r]=r)}),e}function nr(t,n,e,r){if(isNaN(n)||isNaN(e))return t;var i,o,u,a,c,s,f,l,h,p=t._root,d={data:r},v=t._x0,g=t._y0,y=t._x1,_=t._y1;if(!p)return t._root=d,t;for(;p.length;)if((s=n>=(o=(v+y)/2))?v=o:y=o,(f=e>=(u=(g+_)/2))?g=u:_=u,i=p,!(p=p[l=f<<1|s]))return i[l]=d,t;if(a=+t._x.call(null,p.data),c=+t._y.call(null,p.data),n===a&&e===c)return d.next=p,i?i[l]=d:t._root=d,t;do{i=i?i[l]=new Array(4):t._root=new Array(4),(s=n>=(o=(v+y)/2))?v=o:y=o,(f=e>=(u=(g+_)/2))?g=u:_=u}while((l=f<<1|s)==(h=(c>=u)<<1|a>=o));return i[h]=p,i[l]=d,t}function er(t){var n,e,r,i,o=t.length,u=new Array(o),a=new Array(o),c=1/0,s=1/0,f=-1/0,l=-1/0;for(e=0;e<o;++e)isNaN(r=+this._x.call(null,n=t[e]))||isNaN(i=+this._y.call(null,n))||(u[e]=r,a[e]=i,r<c&&(c=r),r>f&&(f=r),i<s&&(s=i),i>l&&(l=i));for(f<c&&(c=this._x0,f=this._x1),l<s&&(s=this._y0,l=this._y1),this.cover(c,s).cover(f,l),e=0;e<o;++e)nr(this,u[e],a[e],t[e]);return this}function rr(t){for(var n=0,e=t.length;n<e;++n)this.remove(t[n]);return this}function ir(t){return t[0]}function or(t){return t[1]}function ur(t,n,e){var r=new ar(null==n?ir:n,null==e?or:e,NaN,NaN,NaN,NaN);return null==t?r:r.addAll(t)}function ar(t,n,e,r,i,o){this._x=t,this._y=n,this._x0=e,this._y0=r,this._x1=i,this._y1=o,this._root=void 0}function cr(t){for(var n={data:t.data},e=n;t=t.next;)e=e.next={data:t.data};return n}function sr(t){return t.x+t.vx}function fr(t){return t.y+t.vy}function lr(t){return t.index}function hr(t,n){var e=t.get(n);if(!e)throw new Error("missing: "+n);return e}function pr(t){return t.x}function dr(t){return t.y}function vr(t){return new gr(t)}function gr(t){if(!(n=wg.exec(t)))throw new Error("invalid format: "+t);var n,e=n[1]||" ",r=n[2]||">",i=n[3]||"-",o=n[4]||"",u=!!n[5],a=n[6]&&+n[6],c=!!n[7],s=n[8]&&+n[8].slice(1),f=n[9]||"" | |
;"n"===f?(c=!0,f="g"):bg[f]||(f=""),(u||"0"===e&&"="===r)&&(u=!0,e="0",r="="),this.fill=e,this.align=r,this.sign=i,this.symbol=o,this.zero=u,this.width=a,this.comma=c,this.precision=s,this.type=f}function yr(n){return Mg=kg(n),t.format=Mg.format,t.formatPrefix=Mg.formatPrefix,Mg}function _r(){this.reset()}function mr(t,n,e){var r=t.s=n+e,i=r-n,o=r-i;t.t=n-o+(e-i)}function xr(t){return t>1?0:t<-1?fy:Math.acos(t)}function br(t){return t>1?ly:t<-1?-ly:Math.asin(t)}function wr(t){return(t=Ty(t/2))*t}function Mr(){}function Tr(t,n){t&&Ey.hasOwnProperty(t.type)&&Ey[t.type](t,n)}function Nr(t,n,e){var r,i=-1,o=t.length-e;for(n.lineStart();++i<o;)r=t[i],n.point(r[0],r[1],r[2]);n.lineEnd()}function kr(t,n){var e=-1,r=t.length;for(n.polygonStart();++e<r;)Nr(t[e],n,1);n.polygonEnd()}function Sr(){Ry.point=Er}function Ar(){Cr(zg,Pg)}function Er(t,n){Ry.point=Cr,zg=t,Pg=n,t*=vy,n*=vy,Rg=t,Lg=my(n=n/2+hy),Dg=Ty(n)}function Cr(t,n){t*=vy,n*=vy,n=n/2+hy;var e=t-Rg,r=e>=0?1:-1,i=r*e,o=my(n),u=Ty(n),a=Dg*u,c=Lg*o+a*my(i),s=a*r*Ty(i);zy.add(_y(s,c)),Rg=t,Lg=o,Dg=u}function zr(t){return[_y(t[1],t[0]),br(t[2])]}function Pr(t){var n=t[0],e=t[1],r=my(e);return[r*my(n),r*Ty(n),Ty(e)]}function Rr(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]}function Lr(t,n){return[t[1]*n[2]-t[2]*n[1],t[2]*n[0]-t[0]*n[2],t[0]*n[1]-t[1]*n[0]]}function Dr(t,n){t[0]+=n[0],t[1]+=n[1],t[2]+=n[2]}function qr(t,n){return[t[0]*n,t[1]*n,t[2]*n]}function Ur(t){var n=ky(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=n,t[1]/=n,t[2]/=n}function Or(t,n){jg.push(Xg=[qg=t,Og=t]),n<Ug&&(Ug=n),n>Fg&&(Fg=n)}function Fr(t,n){var e=Pr([t*vy,n*vy]);if(Bg){var r=Lr(Bg,e),i=[r[1],-r[0],0],o=Lr(i,r);Ur(o),o=zr(o);var u,a=t-Yg,c=a>0?1:-1,s=o[0]*dy*c,f=gy(a)>180;f^(c*Yg<s&&s<c*t)?(u=o[1]*dy)>Fg&&(Fg=u):(s=(s+360)%360-180,f^(c*Yg<s&&s<c*t)?(u=-o[1]*dy)<Ug&&(Ug=u):(n<Ug&&(Ug=n),n>Fg&&(Fg=n))),f?t<Yg?Xr(qg,t)>Xr(qg,Og)&&(Og=t):Xr(t,Og)>Xr(qg,Og)&&(qg=t):Og>=qg?(t<qg&&(qg=t),t>Og&&(Og=t)):t>Yg?Xr(qg,t)>Xr(qg,Og)&&(Og=t):Xr(t,Og)>Xr(qg,Og)&&(qg=t)}else jg.push(Xg=[qg=t,Og=t]);n<Ug&&(Ug=n),n>Fg&&(Fg=n),Bg=e,Yg=t}function Yr(){qy.point=Fr}function Ir(){Xg[0]=qg,Xg[1]=Og,qy.point=Or,Bg=null}function Hr(t,n){if(Bg){var e=t-Yg;Dy.add(gy(e)>180?e+(e>0?360:-360):e)}else Ig=t,Hg=n;Ry.point(t,n),Fr(t,n)}function Br(){Ry.lineStart()}function jr(){Hr(Ig,Hg),Ry.lineEnd(),gy(Dy)>sy&&(qg=-(Og=180)),Xg[0]=qg,Xg[1]=Og,Bg=null}function Xr(t,n){return(n-=t)<0?n+360:n}function Wr(t,n){return t[0]-n[0]}function Vr(t,n){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}function $r(t,n){t*=vy,n*=vy;var e=my(n);Zr(e*my(t),e*Ty(t),Ty(n))}function Zr(t,n,e){++Wg,$g+=(t-$g)/Wg,Zg+=(n-Zg)/Wg,Gg+=(e-Gg)/Wg}function Gr(){Oy.point=Qr}function Qr(t,n){t*=vy,n*=vy;var e=my(n);oy=e*my(t),uy=e*Ty(t),ay=Ty(n),Oy.point=Jr,Zr(oy,uy,ay)}function Jr(t,n){t*=vy,n*=vy;var e=my(n),r=e*my(t),i=e*Ty(t),o=Ty(n),u=_y(ky((u=uy*o-ay*i)*u+(u=ay*r-oy*o)*u+(u=oy*i-uy*r)*u),oy*r+uy*i+ay*o);Vg+=u,Qg+=u*(oy+(oy=r)),Jg+=u*(uy+(uy=i)),Kg+=u*(ay+(ay=o)),Zr(oy,uy,ay)}function Kr(){Oy.point=$r}function ti(){Oy.point=ei}function ni(){ri(ry,iy),Oy.point=$r}function ei(t,n){ry=t,iy=n,t*=vy,n*=vy,Oy.point=ri;var e=my(n);oy=e*my(t),uy=e*Ty(t),ay=Ty(n),Zr(oy,uy,ay)}function ri(t,n){t*=vy,n*=vy;var e=my(n),r=e*my(t),i=e*Ty(t),o=Ty(n),u=uy*o-ay*i,a=ay*r-oy*o,c=oy*i-uy*r,s=ky(u*u+a*a+c*c),f=br(s),l=s&&-f/s;ty+=l*u,ny+=l*a,ey+=l*c,Vg+=f,Qg+=f*(oy+(oy=r)),Jg+=f*(uy+(uy=i)),Kg+=f*(ay+(ay=o)),Zr(oy,uy,ay)}function ii(t,n){return[t>fy?t-py:t<-fy?t+py:t,n]}function oi(t,n,e){return(t%=py)?n||e?Iy(ai(t),ci(n,e)):ai(t):n||e?ci(n,e):ii}function ui(t){return function(n,e){return n+=t,[n>fy?n-py:n<-fy?n+py:n,e]}}function ai(t){var n=ui(t);return n.invert=ui(-t),n}function ci(t,n){function e(t,n){var e=my(n),a=my(t)*e,c=Ty(t)*e,s=Ty(n),f=s*r+a*i;return[_y(c*o-f*u,a*r-s*i),br(f*o+c*u)]}var r=my(t),i=Ty(t),o=my(n),u=Ty(n);return e.invert=function(t,n){var e=my(n),a=my(t)*e,c=Ty(t)*e,s=Ty(n),f=s*o-c*u;return[_y(c*o+s*u,a*r+f*i),br(f*r-a*i)]},e}function si(t,n,e,r,i,o){if(e){var u=my(n),a=Ty(n),c=r*e;null==i?(i=n+r*py,o=n-c/2):(i=fi(u,i),o=fi(u,o),(r>0?i<o:i>o)&&(i+=r*py));for(var s,f=i;r>0?f>o:f<o;f-=c)s=zr([u,-a*my(f),-a*Ty(f)]),t.point(s[0],s[1])}}function fi(t,n){n=Pr(n),n[0]-=t,Ur(n);var e=xr(-n[1]);return((-n[2]<0?-e:e)+py-sy)%py}function li(t,n,e,r){this.x=t,this.z=n,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function hi(t){if(n=t.length){for(var n,e,r=0,i=t[0];++r<n;)i.n=e=t[r],e.p=i,i=e;i.n=e=t[0],e.p=i}}function pi(t){return t.length>1}function di(t,n){return((t=t.x)[0]<0?t[1]-ly-sy:ly-t[1])-((n=n.x)[0]<0?n[1]-ly-sy:ly-n[1])}function vi(t){var n,e=NaN,r=NaN,i=NaN;return{lineStart:function(){t.lineStart(),n=1},point:function(o,u){var a=o>0?fy:-fy,c=gy(o-e);gy(c-fy)<sy?(t.point(e,r=(r+u)/2>0?ly:-ly),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(a,r),t.point(o,r),n=0):i!==a&&c>=fy&&(gy(e-i)<sy&&(e-=i*sy),gy(o-a)<sy&&(o-=a*sy),r=gi(e,r,o,u),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(a,r),n=0),t.point(e=o,r=u),i=a},lineEnd:function(){t.lineEnd(),e=r=NaN},clean:function(){return 2-n}}}function gi(t,n,e,r){var i,o,u=Ty(t-e);return gy(u)>sy?yy((Ty(n)*(o=my(r))*Ty(e)-Ty(r)*(i=my(n))*Ty(t))/(i*o*u)):(n+r)/2}function yi(t,n,e,r){var i;if(null==t)i=e*ly,r.point(-fy,i),r.point(0,i),r.point(fy,i),r.point(fy,0),r.point(fy,-i),r.point(0,-i),r.point(-fy,-i),r.point(-fy,0),r.point(-fy,i);else if(gy(t[0]-n[0])>sy){var o=t[0]<n[0]?fy:-fy;i=e*o/2,r.point(-o,i),r.point(0,i),r.point(o,i)}else r.point(n[0],n[1])}function _i(t,n,e,r){function i(i,o){return t<=i&&i<=e&&n<=o&&o<=r}function o(i,o,a,s){var f=0,l=0;if(null==i||(f=u(i,a))!==(l=u(o,a))||c(i,o)<0^a>0)do{s.point(0===f||3===f?t:e,f>1?r:n)}while((f=(f+a+4)%4)!==l);else s.point(o[0],o[1])}function u(r,i){return gy(r[0]-t)<sy?i>0?0:3:gy(r[0]-e)<sy?i>0?2:1:gy(r[1]-n)<sy?i>0?1:0:i>0?3:2}function a(t,n){return c(t.x,n.x)}function c(t,n){var e=u(t,1),r=u(n,1);return e!==r?e-r:0===e?n[1]-t[1]:1===e?t[0]-n[0]:2===e?t[1]-n[1]:n[0]-t[0]}return function(u){function c(t,n){i(t,n)&&k.point(t,n)}function s(){for(var n=0,e=0,i=g.length;e<i;++e)for(var o,u,a=g[e],c=1,s=a.length,f=a[0],l=f[0],h=f[1];c<s;++c)o=l,u=h,f=a[c],l=f[0],h=f[1],u<=r?h>r&&(l-o)*(r-u)>(h-u)*(t-o)&&++n:h<=r&&(l-o)*(r-u)<(h-u)*(t-o)&&--n;return n}function f(){k=S,v=[],g=[],N=!0}function l(){var t=s(),n=N&&t,e=(v=Kf(v)).length;(n||e)&&(u.polygonStart(),n&&(u.lineStart(),o(null,null,1,u),u.lineEnd()),e&&r_(v,a,t,o,u),u.polygonEnd()),k=u,v=g=y=null}function h(){A.point=d,g&&g.push(y=[]),T=!0,M=!1,b=w=NaN}function p(){v&&(d(_,m),x&&M&&S.rejoin(),v.push(S.result())),A.point=c,M&&k.lineEnd()}function d(o,u){var a=i(o,u);if(g&&y.push([o,u]),T)_=o,m=u,x=a,T=!1,a&&(k.lineStart(),k.point(o,u));else if(a&&M)k.point(o,u);else{var c=[b=Math.max(l_,Math.min(f_,b)),w=Math.max(l_,Math.min(f_,w))],s=[o=Math.max(l_,Math.min(f_,o)),u=Math.max(l_,Math.min(f_,u))];s_(c,s,t,n,e,r)?(M||(k.lineStart(),k.point(c[0],c[1])),k.point(s[0],s[1]),a||k.lineEnd(),N=!1):a&&(k.lineStart(),k.point(o,u),N=!1)}b=o,w=u,M=a}var v,g,y,_,m,x,b,w,M,T,N,k=u,S=n_(),A={point:c,lineStart:h,lineEnd:p,polygonStart:f,polygonEnd:l};return A}}function mi(){d_.point=bi,d_.lineEnd=xi}function xi(){d_.point=d_.lineEnd=Mr}function bi(t,n){t*=vy,n*=vy,Hy=t,By=Ty(n),jy=my(n),d_.point=wi}function wi(t,n){t*=vy,n*=vy;var e=Ty(n),r=my(n),i=gy(t-Hy),o=my(i),u=Ty(i),a=r*u,c=jy*e-By*r*o,s=By*e+jy*r*o;p_.add(_y(ky(a*a+c*c),s)),Hy=t,By=e,jy=r}function Mi(t,n){return!(!t||!x_.hasOwnProperty(t.type))&&x_[t.type](t,n)}function Ti(t,n){return 0===__(t,n)}function Ni(t,n){var e=__(t[0],t[1]);return __(t[0],n)+__(n,t[1])<=e+sy}function ki(t,n){return!!o_(t.map(Si),Ai(n))}function Si(t){return t=t.map(Ai),t.pop(),t}function Ai(t){return[t[0]*vy,t[1]*vy]}function Ei(t,n,e){var r=Yf(t,n-sy,e).concat(n);return function(t){return r.map(function(n){return[t,n]})}}function Ci(t,n,e){var r=Yf(t,n-sy,e).concat(n);return function(t){return r.map(function(n){return[n,t]})}}function zi(){function t(){return{type:"MultiLineString",coordinates:n()}}function n(){return Yf(xy(o/g)*g,i,g).map(h).concat(Yf(xy(s/y)*y,c,y).map(p)).concat(Yf(xy(r/d)*d,e,d).filter(function(t){return gy(t%g)>sy}).map(f)).concat(Yf(xy(a/v)*v,u,v).filter(function(t){return gy(t%y)>sy}).map(l))}var e,r,i,o,u,a,c,s,f,l,h,p,d=10,v=d,g=90,y=360,_=2.5;return t.lines=function(){return n().map(function(t){return{type:"LineString",coordinates:t}})},t.outline=function(){return{type:"Polygon",coordinates:[h(o).concat(p(c).slice(1),h(i).reverse().slice(1),p(s).reverse().slice(1))]}},t.extent=function(n){return arguments.length?t.extentMajor(n).extentMinor(n):t.extentMinor()},t.extentMajor=function(n){return arguments.length?(o=+n[0][0],i=+n[1][0],s=+n[0][1],c=+n[1][1],o>i&&(n=o,o=i,i=n),s>c&&(n=s,s=c,c=n),t.precision(_)):[[o,s],[i,c]]},t.extentMinor=function(n){return arguments.length?(r=+n[0][0],e=+n[1][0],a=+n[0][1],u=+n[1][1],r>e&&(n=r,r=e,e=n),a>u&&(n=a,a=u,u=n),t.precision(_)):[[r,a],[e,u]]},t.step=function(n){return arguments.length?t.stepMajor(n).stepMinor(n):t.stepMinor()},t.stepMajor=function(n){return arguments.length?(g=+n[0],y=+n[1],t):[g,y]},t.stepMinor=function(n){return arguments.length?(d=+n[0],v=+n[1],t):[d,v]},t.precision=function(n){return arguments.length?(_=+n,f=Ei(a,u,90),l=Ci(r,e,_),h=Ei(s,c,90),p=Ci(o,i,_),t):_},t.extentMajor([[-180,-90+sy],[180,90-sy]]).extentMinor([[-180,-80-sy],[180,80+sy]])}function Pi(){return zi()()}function Ri(){k_.point=Li}function Li(t,n){k_.point=Di,Xy=Vy=t,Wy=$y=n}function Di(t,n){N_.add($y*t-Vy*n),Vy=t,$y=n}function qi(){Di(Xy,Wy)}function Ui(t,n){t<S_&&(S_=t),t>E_&&(E_=t),n<A_&&(A_=n),n>C_&&(C_=n)}function Oi(t,n){P_+=t,R_+=n,++L_}function Fi(){I_.point=Yi}function Yi(t,n){I_.point=Ii,Oi(Qy=t,Jy=n)}function Ii(t,n){var e=t-Qy,r=n-Jy,i=ky(e*e+r*r);D_+=i*(Qy+t)/2,q_+=i*(Jy+n)/2,U_+=i,Oi(Qy=t,Jy=n)}function Hi(){I_.point=Oi}function Bi(){I_.point=Xi}function ji(){Wi(Zy,Gy)}function Xi(t,n){I_.point=Wi,Oi(Zy=Qy=t,Gy=Jy=n)}function Wi(t,n){var e=t-Qy,r=n-Jy,i=ky(e*e+r*r);D_+=i*(Qy+t)/2,q_+=i*(Jy+n)/2,U_+=i,i=Jy*t-Qy*n,O_+=i*(Qy+t),F_+=i*(Jy+n),Y_+=3*i,Oi(Qy=t,Jy=n)}function Vi(t){this._context=t}function $i(t,n){$_.point=Zi,B_=X_=t,j_=W_=n}function Zi(t,n){X_-=t,W_-=n,V_.add(ky(X_*X_+W_*W_)),X_=t,W_=n}function Gi(){this._string=[]}function Qi(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}function Ji(t){return function(n){var e=new Ki;for(var r in t)e[r]=t[r];return e.stream=n,e}}function Ki(){}function to(t,n,e){var r=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),null!=r&&t.clipExtent(null),Cy(e,t.stream(z_)),n(z_.result()),null!=r&&t.clipExtent(r),t}function no(t,n,e){return to(t,function(e){var r=n[1][0]-n[0][0],i=n[1][1]-n[0][1],o=Math.min(r/(e[1][0]-e[0][0]),i/(e[1][1]-e[0][1])),u=+n[0][0]+(r-o*(e[1][0]+e[0][0]))/2,a=+n[0][1]+(i-o*(e[1][1]+e[0][1]))/2;t.scale(150*o).translate([u,a])},e)}function eo(t,n,e){return no(t,[[0,0],n],e)}function ro(t,n,e){return to(t,function(e){var r=+n,i=r/(e[1][0]-e[0][0]),o=(r-i*(e[1][0]+e[0][0]))/2,u=-i*e[0][1];t.scale(150*i).translate([o,u])},e)}function io(t,n,e){return to(t,function(e){var r=+n,i=r/(e[1][1]-e[0][1]),o=-i*e[0][0],u=(r-i*(e[1][1]+e[0][1]))/2;t.scale(150*i).translate([o,u])},e)}function oo(t){return Ji({point:function(n,e){n=t(n,e),this.stream.point(n[0],n[1])}})}function uo(t,n){function e(r,i,o,u,a,c,s,f,l,h,p,d,v,g){var y=s-r,_=f-i,m=y*y+_*_;if(m>4*n&&v--){var x=u+h,b=a+p,w=c+d,M=ky(x*x+b*b+w*w),T=br(w/=M),N=gy(gy(w)-1)<sy||gy(o-l)<sy?(o+l)/2:_y(b,x),k=t(N,T),S=k[0],A=k[1],E=S-r,C=A-i,z=_*E-y*C;(z*z/m>n||gy((y*E+_*C)/m-.5)>.3||u*h+a*p+c*d<J_)&&(e(r,i,o,u,a,c,S,A,N,x/=M,b/=M,w,v,g),g.point(S,A),e(S,A,N,x,b,w,s,f,l,h,p,d,v,g))}}return function(n){function r(e,r){e=t(e,r),n.point(e[0],e[1])}function i(){y=NaN,w.point=o,n.lineStart()}function o(r,i){var o=Pr([r,i]),u=t(r,i);e(y,_,g,m,x,b,y=u[0],_=u[1],g=r,m=o[0],x=o[1],b=o[2],Q_,n),n.point(y,_)}function u(){w.point=r,n.lineEnd()}function a(){i(),w.point=c,w.lineEnd=s}function c(t,n){o(f=t,n),l=y,h=_,p=m,d=x,v=b,w.point=o}function s(){e(y,_,g,m,x,b,l,h,f,p,d,v,Q_,n),w.lineEnd=u,u()}var f,l,h,p,d,v,g,y,_,m,x,b,w={point:r,lineStart:i,lineEnd:u,polygonStart:function(){n.polygonStart(),w.lineStart=a},polygonEnd:function(){n.polygonEnd(),w.lineStart=i}};return w}}function ao(t){return Ji({point:function(n,e){var r=t(n,e);return this.stream.point(r[0],r[1])}})}function co(t){return so(function(){return t})()}function so(t){function n(t){return t=f(t[0]*vy,t[1]*vy),[t[0]*g+a,c-t[1]*g]}function e(t){return(t=f.invert((t[0]-a)/g,(c-t[1])/g))&&[t[0]*dy,t[1]*dy]}function r(t,n){return t=u(t,n),[t[0]*g+a,c-t[1]*g]}function i(){f=Iy(s=oi(b,w,M),u);var t=u(m,x);return a=y-t[0]*g,c=_+t[1]*g,o()}function o(){return d=v=null,n}var u,a,c,s,f,l,h,p,d,v,g=150,y=480,_=250,m=0,x=0,b=0,w=0,M=0,T=null,N=a_,k=null,S=M_,A=.5,E=K_(r,A);return n.stream=function(t){return d&&v===t?d:d=tm(ao(s)(N(E(S(v=t)))))},n.preclip=function(t){return arguments.length?(N=t,T=void 0,o()):N},n.postclip=function(t){return arguments.length?(S=t,k=l=h=p=null,o()):S},n.clipAngle=function(t){return arguments.length?(N=+t?c_(T=t*vy):(T=null,a_),o()):T*dy},n.clipExtent=function(t){return arguments.length?(S=null==t?(k=l=h=p=null,M_):_i(k=+t[0][0],l=+t[0][1],h=+t[1][0],p=+t[1][1]),o()):null==k?null:[[k,l],[h,p]]},n.scale=function(t){return arguments.length?(g=+t,i()):g},n.translate=function(t){return arguments.length?(y=+t[0],_=+t[1],i()):[y,_]},n.center=function(t){return arguments.length?(m=t[0]%360*vy,x=t[1]%360*vy,i()):[m*dy,x*dy]},n.rotate=function(t){return arguments.length?(b=t[0]%360*vy,w=t[1]%360*vy,M=t.length>2?t[2]%360*vy:0,i()):[b*dy,w*dy,M*dy]},n.precision=function(t){return arguments.length?(E=K_(r,A=t*t),o()):ky(A)},n.fitExtent=function(t,e){return no(n,t,e)},n.fitSize=function(t,e){return eo(n,t,e)},n.fitWidth=function(t,e){return ro(n,t,e)},n.fitHeight=function(t,e){return io(n,t,e)},function(){return u=t.apply(this,arguments),n.invert=u.invert&&e,i()}}function fo(t){var n=0,e=fy/3,r=so(t),i=r(n,e);return i.parallels=function(t){return arguments.length?r(n=t[0]*vy,e=t[1]*vy):[n*dy,e*dy]},i}function lo(t){function n(t,n){return[t*e,Ty(n)/e]}var e=my(t);return n.invert=function(t,n){return[t/e,br(n*e)]},n}function ho(t,n){function e(t,n){var e=ky(o-2*i*Ty(n))/i;return[e*Ty(t*=i),u-e*my(t)]}var r=Ty(t),i=(r+Ty(n))/2;if(gy(i)<sy)return lo(t);var o=1+r*(2*i-r),u=ky(o)/i;return e.invert=function(t,n){var e=u-n;return[_y(t,gy(e))/i*Ny(e),br((o-(t*t+e*e)*i*i)/(2*i))]},e}function po(t){var n=t.length;return{point:function(e,r){for(var i=-1;++i<n;)t[i].point(e,r)},sphere:function(){for(var e=-1;++e<n;)t[e].sphere()},lineStart:function(){for(var e=-1;++e<n;)t[e].lineStart()},lineEnd:function(){for(var e=-1;++e<n;)t[e].lineEnd()},polygonStart:function(){for(var e=-1;++e<n;)t[e].polygonStart()},polygonEnd:function(){for(var e=-1;++e<n;)t[e].polygonEnd()}}}function vo(t){return function(n,e){var r=my(n),i=my(e),o=t(r*i);return[o*i*Ty(n),o*Ty(e)]}}function go(t){return function(n,e){var r=ky(n*n+e*e),i=t(r),o=Ty(i),u=my(i);return[_y(n*o,r*u),br(r&&e*o/r)]}}function yo(t,n){return[t,wy(Sy((ly+n)/2))]}function _o(t){function n(){var n=fy*a(),u=o(Ky(o.rotate()).invert([0,0]));return s(null==f?[[u[0]-n,u[1]-n],[u[0]+n,u[1]+n]]:t===yo?[[Math.max(u[0]-n,f),e],[Math.min(u[0]+n,r),i]]:[[f,Math.max(u[1]-n,e)],[r,Math.min(u[1]+n,i)]])}var e,r,i,o=co(t),u=o.center,a=o.scale,c=o.translate,s=o.clipExtent,f=null;return o.scale=function(t){return arguments.length?(a(t),n()):a()},o.translate=function(t){return arguments.length?(c(t),n()):c()},o.center=function(t){return arguments.length?(u(t),n()):u()},o.clipExtent=function(t){return arguments.length?(null==t?f=e=r=i=null:(f=+t[0][0],e=+t[0][1],r=+t[1][0],i=+t[1][1]),n()):null==f?null:[[f,e],[r,i]]},n()}function mo(t){return Sy((ly+t)/2)}function xo(t,n){function e(t,n){o>0?n<-ly+sy&&(n=-ly+sy):n>ly-sy&&(n=ly-sy);var e=o/My(mo(n),i);return[e*Ty(i*t),o-e*my(i*t)]}var r=my(t),i=t===n?Ty(t):wy(r/my(n))/wy(mo(n)/mo(t)),o=r*My(mo(t),i)/i;return i?(e.invert=function(t,n){var e=o-n,r=Ny(i)*ky(t*t+e*e);return[_y(t,gy(e))/i*Ny(e),2*yy(My(o/r,1/i))-ly]},e):yo}function bo(t,n){return[t,n]}function wo(t,n){function e(t,n){var e=o-n,r=i*t;return[e*Ty(r),o-e*my(r)]}var r=my(t),i=t===n?Ty(t):(r-my(n))/(n-t),o=r/i+t;return gy(i)<sy?bo:(e.invert=function(t,n){var e=o-n;return[_y(t,gy(e))/i*Ny(e),o-Ny(i)*ky(t*t+e*e)]},e)}function Mo(t,n){var e=my(n),r=my(t)*e;return[e*Ty(t)/r,Ty(n)/r]}function To(t,n,e,r){return 1===t&&1===n&&0===e&&0===r?M_:Ji({point:function(i,o){this.stream.point(i*t+e,o*n+r)}})}function No(t,n){var e=n*n,r=e*e;return[t*(.8707-.131979*e+r*(r*(.003971*e-.001529*r)-.013791)),n*(1.007226+e*(.015085+r*(.028874*e-.044475-.005916*r)))]}function ko(t,n){return[my(n)*Ty(t),Ty(n)]}function So(t,n){var e=my(n),r=1+my(t)*e;return[e*Ty(t)/r,Ty(n)/r]}function Ao(t,n){return[wy(Sy((ly+n)/2)),-t]}function Eo(t,n){return t.parent===n.parent?1:2}function Co(t){return t.reduce(zo,0)/t.length}function zo(t,n){return t+n.x}function Po(t){return 1+t.reduce(Ro,0)}function Ro(t,n){return Math.max(t,n.y)}function Lo(t){for(var n;n=t.children;)t=n[0];return t}function Do(t){for(var n;n=t.children;)t=n[n.length-1];return t}function qo(t){var n=0,e=t.children,r=e&&e.length;if(r)for(;--r>=0;)n+=e[r].value;else n=1;t.value=n}function Uo(t,n){if(t===n)return t;var e=t.ancestors(),r=n.ancestors(),i=null;for(t=e.pop(),n=r.pop();t===n;)i=t,t=e.pop(),n=r.pop();return i}function Oo(t,n){var e,r,i,o,u,a=new Bo(t),c=+t.value&&(a.value=t.value),s=[a];for(null==n&&(n=Yo);e=s.pop();)if(c&&(e.value=+e.data.value),(i=n(e.data))&&(u=i.length))for(e.children=new Array(u),o=u-1;o>=0;--o)s.push(r=e.children[o]=new Bo(i[o])),r.parent=e,r.depth=e.depth+1;return a.eachBefore(Ho)}function Fo(){return Oo(this).eachBefore(Io)}function Yo(t){return t.children}function Io(t){t.data=t.data.data}function Ho(t){var n=0;do{t.height=n}while((t=t.parent)&&t.height<++n)}function Bo(t){this.data=t,this.depth=this.height=0,this.parent=null}function jo(t){for(var n,e,r=t.length;r;)e=Math.random()*r--|0,n=t[r],t[r]=t[e],t[e]=n;return t}function Xo(t,n){var e,r;if($o(n,t))return[n];for(e=0;e<t.length;++e)if(Wo(n,t[e])&&$o(Qo(t[e],n),t))return[t[e],n];for(e=0;e<t.length-1;++e)for(r=e+1;r<t.length;++r)if(Wo(Qo(t[e],t[r]),n)&&Wo(Qo(t[e],n),t[r])&&Wo(Qo(t[r],n),t[e])&&$o(Jo(t[e],t[r],n),t))return[t[e],t[r],n];throw new Error}function Wo(t,n){var e=t.r-n.r,r=n.x-t.x,i=n.y-t.y;return e<0||e*e<r*r+i*i}function Vo(t,n){var e=t.r-n.r+1e-6,r=n.x-t.x,i=n.y-t.y;return e>0&&e*e>r*r+i*i}function $o(t,n){for(var e=0;e<n.length;++e)if(!Vo(t,n[e]))return!1;return!0}function Zo(t){switch(t.length){case 1:return Go(t[0]);case 2:return Qo(t[0],t[1]);case 3:return Jo(t[0],t[1],t[2])}}function Go(t){return{x:t.x,y:t.y,r:t.r}}function Qo(t,n){var e=t.x,r=t.y,i=t.r,o=n.x,u=n.y,a=n.r,c=o-e,s=u-r,f=a-i,l=Math.sqrt(c*c+s*s);return{x:(e+o+c/l*f)/2,y:(r+u+s/l*f)/2,r:(l+i+a)/2}}function Jo(t,n,e){var r=t.x,i=t.y,o=t.r,u=n.x,a=n.y,c=n.r,s=e.x,f=e.y,l=e.r,h=r-u,p=r-s,d=i-a,v=i-f,g=c-o,y=l-o,_=r*r+i*i-o*o,m=_-u*u-a*a+c*c,x=_-s*s-f*f+l*l,b=p*d-h*v,w=(d*x-v*m)/(2*b)-r,M=(v*g-d*y)/b,T=(p*m-h*x)/(2*b)-i,N=(h*y-p*g)/b,k=M*M+N*N-1,S=2*(o+w*M+T*N),A=w*w+T*T-o*o,E=-(k?(S+Math.sqrt(S*S-4*k*A))/(2*k):A/S);return{x:r+w+M*E,y:i+T+N*E,r:E}}function Ko(t,n,e){var r=t.x,i=t.y,o=n.r+e.r,u=t.r+e.r,a=n.x-r,c=n.y-i,s=a*a+c*c;if(s){var f=.5+((u*=u)-(o*=o))/(2*s),l=Math.sqrt(Math.max(0,2*o*(u+s)-(u-=s)*u-o*o))/(2*s);e.x=r+f*a+l*c,e.y=i+f*c-l*a}else e.x=r+u,e.y=i}function tu(t,n){var e=n.x-t.x,r=n.y-t.y,i=t.r+n.r;return i*i-1e-6>e*e+r*r}function nu(t){var n=t._,e=t.next._,r=n.r+e.r,i=(n.x*e.r+e.x*n.r)/r,o=(n.y*e.r+e.y*n.r)/r;return i*i+o*o}function eu(t){this._=t,this.next=null,this.previous=null}function ru(t){if(!(i=t.length))return 0;var n,e,r,i,o,u,a,c,s,f,l;if(n=t[0],n.x=0,n.y=0,!(i>1))return n.r;if(e=t[1],n.x=-e.r,e.x=n.r,e.y=0,!(i>2))return n.r+e.r;Ko(e,n,r=t[2]),n=new eu(n),e=new eu(e),r=new eu(r),n.next=r.previous=e,e.next=n.previous=r,r.next=e.previous=n;t:for(a=3;a<i;++a){Ko(n._,e._,r=t[a]),r=new eu(r),c=e.next,s=n.previous,f=e._.r,l=n._.r;do{if(f<=l){if(tu(c._,r._)){e=c,n.next=e,e.previous=n,--a;continue t}f+=c._.r,c=c.next}else{if(tu(s._,r._)){n=s,n.next=e,e.previous=n,--a;continue t}l+=s._.r,s=s.previous}}while(c!==s.next);for(r.previous=n,r.next=e,n.next=e.previous=e=r,o=nu(n);(r=r.next)!==e;)(u=nu(r))<o&&(n=r,o=u);e=n.next}for(n=[e._],r=e;(r=r.next)!==e;)n.push(r._);for(r=zm(n),a=0;a<i;++a)n=t[a],n.x-=r.x,n.y-=r.y;return r.r}function iu(t){return null==t?null:ou(t)}function ou(t){if("function"!=typeof t)throw new Error;return t}function uu(){return 0}function au(t){return Math.sqrt(t.value)}function cu(t){return function(n){n.children||(n.r=Math.max(0,+t(n)||0))}}function su(t,n){return function(e){if(r=e.children){var r,i,o,u=r.length,a=t(e)*n||0;if(a)for(i=0;i<u;++i)r[i].r+=a;if(o=ru(r),a)for(i=0;i<u;++i)r[i].r-=a;e.r=o+a}}}function fu(t){return function(n){var e=n.parent;n.r*=t,e&&(n.x=e.x+t*n.x,n.y=e.y+t*n.y)}}function lu(t){return t.id}function hu(t){return t.parentId}function pu(t,n){return t.parent===n.parent?1:2}function du(t){var n=t.children;return n?n[0]:t.t}function vu(t){var n=t.children;return n?n[n.length-1]:t.t}function gu(t,n,e){var r=e/(n.i-t.i);n.c-=r,n.s+=e,t.c+=r,n.z+=e,n.m+=e}function yu(t){for(var n,e=0,r=0,i=t.children,o=i.length;--o>=0;)n=i[o],n.z+=e,n.m+=e,e+=n.s+(r+=n.c)}function _u(t,n,e){return t.a.parent===n.parent?t.a:e}function mu(t,n){this._=t,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=n}function xu(t){for(var n,e,r,i,o,u=new mu(t,0),a=[u];n=a.pop();)if(r=n._.children)for(n.children=new Array(o=r.length),i=o-1;i>=0;--i)a.push(e=n.children[i]=new mu(r[i],i)),e.parent=n;return(u.parent=new mu(null,0)).children=[u],u}function bu(t,n,e,r,i,o){for(var u,a,c,s,f,l,h,p,d,v,g,y=[],_=n.children,m=0,x=0,b=_.length,w=n.value;m<b;){c=i-e,s=o-r;do{f=_[x++].value}while(!f&&x<b);for(l=h=f,v=Math.max(s/c,c/s)/(w*t),g=f*f*v,d=Math.max(h/g,g/l);x<b;++x){if(f+=a=_[x].value,a<l&&(l=a),a>h&&(h=a),g=f*f*v,(p=Math.max(h/g,g/l))>d){f-=a;break}d=p}y.push(u={value:f,dice:c<s,children:_.slice(m,x)}),u.dice?qm(u,e,r,i,w?r+=s*f/w:o):Bm(u,e,r,w?e+=c*f/w:i,o),w-=f,m=x}return y}function wu(t,n){return t[0]-n[0]||t[1]-n[1]}function Mu(t){for(var n=t.length,e=[0,1],r=2,i=2;i<n;++i){for(;r>1&&Jm(t[e[r-2]],t[e[r-1]],t[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function Tu(t){this._size=t,this._call=this._error=null,this._tasks=[],this._data=[],this._waiting=this._active=this._ended=this._start=0}function Nu(t){if(!t._start)try{ku(t)}catch(n){if(t._tasks[t._ended+t._active-1])Au(t,n);else if(!t._data)throw n}}function ku(t){for(;t._start=t._waiting&&t._active<t._size;){var n=t._ended+t._active,e=t._tasks[n],r=e.length-1,i=e[r];e[r]=Su(t,n),--t._waiting,++t._active,e=i.apply(null,e),t._tasks[n]&&(t._tasks[n]=e||rx)}}function Su(t,n){return function(e,r){t._tasks[n]&&(--t._active,++t._ended,t._tasks[n]=null,null==t._error&&(null!=e?Au(t,e):(t._data[n]=r,t._waiting?Nu(t):Eu(t))))}}function Au(t,n){var e,r=t._tasks.length;for(t._error=n,t._data=void 0,t._waiting=NaN;--r>=0;)if((e=t._tasks[r])&&(t._tasks[r]=null,e.abort))try{e.abort()}catch(n){}t._active=NaN,Eu(t)}function Eu(t){if(!t._active&&t._call){var n=t._data;t._data=void 0,t._call(t._error,n)}}function Cu(t){if(null==t)t=1/0;else if(!((t=+t)>=1))throw new Error("invalid concurrency");return new Tu(t)}function zu(t){return function(n,e){t(null==n?e:null)}}function Pu(t){var n=t.responseType;return n&&"text"!==n?t.response:t.responseText}function Ru(t,n){return function(e){return t(e.responseText,n)}}function Lu(t){function n(n){var o=n+"",u=e.get(o);if(!u){if(i!==Mx)return i;e.set(o,u=r.push(n))}return t[(u-1)%t.length]}var e=Xe(),r=[],i=Mx;return t=null==t?[]:wx.call(t),n.domain=function(t){if(!arguments.length)return r.slice();r=[],e=Xe();for(var i,o,u=-1,a=t.length;++u<a;)e.has(o=(i=t[u])+"")||e.set(o,r.push(i));return n},n.range=function(e){return arguments.length?(t=wx.call(e),n):t.slice()},n.unknown=function(t){return arguments.length?(i=t,n):i},n.copy=function(){return Lu().domain(r).range(t).unknown(i)},n}function Du(){function t(){var t=i().length,r=u[1]<u[0],l=u[r-0],h=u[1-r];n=(h-l)/Math.max(1,t-c+2*s),a&&(n=Math.floor(n)),l+=(h-l-n*(t-c))*f,e=n*(1-c),a&&(l=Math.round(l),e=Math.round(e));var p=Yf(t).map(function(t){return l+n*t});return o(r?p.reverse():p)}var n,e,r=Lu().unknown(void 0),i=r.domain,o=r.range,u=[0,1],a=!1,c=0,s=0,f=.5;return delete r.unknown,r.domain=function(n){return arguments.length?(i(n),t()):i()},r.range=function(n){return arguments.length?(u=[+n[0],+n[1]],t()):u.slice()},r.rangeRound=function(n){return u=[+n[0],+n[1]],a=!0,t()},r.bandwidth=function(){return e},r.step=function(){return n},r.round=function(n){return arguments.length?(a=!!n,t()):a},r.padding=function(n){return arguments.length?(c=s=Math.max(0,Math.min(1,n)),t()):c},r.paddingInner=function(n){return arguments.length?(c=Math.max(0,Math.min(1,n)),t()):c},r.paddingOuter=function(n){return arguments.length?(s=Math.max(0,Math.min(1,n)),t()):s},r.align=function(n){return arguments.length?(f=Math.max(0,Math.min(1,n)),t()):f},r.copy=function(){return Du().domain(i()).range(u).round(a).paddingInner(c).paddingOuter(s).align(f)},t()}function qu(t){var n=t.copy;return t.padding=t.paddingOuter,delete t.paddingInner,delete t.paddingOuter,t.copy=function(){return qu(n())},t}function Uu(){return qu(Du().paddingInner(1))}function Ou(t,n){return(n-=t=+t)?function(e){return(e-t)/n}:Tx(n)}function Fu(t){return function(n,e){var r=t(n=+n,e=+e);return function(t){return t<=n?0:t>=e?1:r(t)}}}function Yu(t){return function(n,e){var r=t(n=+n,e=+e);return function(t){return t<=0?n:t>=1?e:r(t)}}}function Iu(t,n,e,r){var i=t[0],o=t[1],u=n[0],a=n[1];return o<i?(i=e(o,i),u=r(a,u)):(i=e(i,o),u=r(u,a)),function(t){return u(i(t))}}function Hu(t,n,e,r){var i=Math.min(t.length,n.length)-1,o=new Array(i),u=new Array(i),a=-1;for(t[i]<t[0]&&(t=t.slice().reverse(),n=n.slice().reverse());++a<i;)o[a]=e(t[a],t[a+1]),u[a]=r(n[a],n[a+1]);return function(n){var e=kf(t,n,1,i)-1;return u[e](o[e](n))}}function Bu(t,n){return n.domain(t.domain()).range(t.range()).interpolate(t.interpolate()).clamp(t.clamp())}function ju(t,n){function e(){return i=Math.min(a.length,c.length)>2?Hu:Iu,o=u=null,r}function r(n){return(o||(o=i(a,c,f?Fu(t):t,s)))(+n)}var i,o,u,a=kx,c=kx,s=pp,f=!1;return r.invert=function(t){return(u||(u=i(c,a,Ou,f?Yu(n):n)))(+t)},r.domain=function(t){return arguments.length?(a=bx.call(t,Nx),e()):a.slice()},r.range=function(t){return arguments.length?(c=wx.call(t),e()):c.slice()},r.rangeRound=function(t){return c=wx.call(t),s=dp,e()},r.clamp=function(t){return arguments.length?(f=!!t,e()):f},r.interpolate=function(t){return arguments.length?(s=t,e()):s},e()}function Xu(t){var n=t.domain;return t.ticks=function(t){var e=n();return jf(e[0],e[e.length-1],null==t?10:t)},t.tickFormat=function(t,e){return Sx(n(),t,e)},t.nice=function(e){null==e&&(e=10);var i,o=n(),u=0,a=o.length-1,c=o[u],s=o[a];return s<c&&(i=c,c=s,s=i,i=u,u=a,a=i),i=r(c,s,e),i>0?(c=Math.floor(c/i)*i,s=Math.ceil(s/i)*i,i=r(c,s,e)):i<0&&(c=Math.ceil(c*i)/i,s=Math.floor(s*i)/i,i=r(c,s,e)),i>0?(o[u]=Math.floor(c/i)*i,o[a]=Math.ceil(s/i)*i,n(o)):i<0&&(o[u]=Math.ceil(c*i)/i,o[a]=Math.floor(s*i)/i,n(o)),t},t}function Wu(){var t=ju(Ou,cp);return t.copy=function(){return Bu(t,Wu())},Xu(t)}function Vu(){function t(t){return+t}var n=[0,1];return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=bx.call(e,Nx),t):n.slice()},t.copy=function(){return Vu().domain(n)},Xu(t)}function $u(t,n){return(n=Math.log(n/t))?function(e){return Math.log(e/t)/n}:Tx(n)}function Zu(t,n){return t<0?function(e){return-Math.pow(-n,e)*Math.pow(-t,1-e)}:function(e){return Math.pow(n,e)*Math.pow(t,1-e)}}function Gu(t){return isFinite(t)?+("1e"+t):t<0?0:t}function Qu(t){return 10===t?Gu:t===Math.E?Math.exp:function(n){return Math.pow(t,n)}}function Ju(t){return t===Math.E?Math.log:10===t&&Math.log10||2===t&&Math.log2||(t=Math.log(t),function(n){return Math.log(n)/t})}function Ku(t){return function(n){return-t(-n)}}function ta(){function n(){return o=Ju(i),u=Qu(i),r()[0]<0&&(o=Ku(o),u=Ku(u)),e}var e=ju($u,Zu).domain([1,10]),r=e.domain,i=10,o=Ju(10),u=Qu(10);return e.base=function(t){return arguments.length?(i=+t,n()):i},e.domain=function(t){return arguments.length?(r(t),n()):r()},e.ticks=function(t){var n,e=r(),a=e[0],c=e[e.length-1];(n=c<a)&&(h=a,a=c,c=h);var s,f,l,h=o(a),p=o(c),d=null==t?10:+t,v=[];if(!(i%1)&&p-h<d){if(h=Math.round(h)-1,p=Math.round(p)+1,a>0){for(;h<p;++h)for(f=1,s=u(h);f<i;++f)if(!((l=s*f)<a)){if(l>c)break;v.push(l)}}else for(;h<p;++h)for(f=i-1,s=u(h);f>=1;--f)if(!((l=s*f)<a)){if(l>c)break;v.push(l)}}else v=jf(h,p,Math.min(p-h,d)).map(u);return n?v.reverse():v},e.tickFormat=function(n,r){if(null==r&&(r=10===i?".0e":","),"function"!=typeof r&&(r=t.format(r)),n===1/0)return r;null==n&&(n=10);var a=Math.max(1,i*n/e.ticks().length);return function(t){var n=t/u(Math.round(o(t)));return n*i<i-.5&&(n*=i),n<=a?r(t):""}},e.nice=function(){return r(Ax(r(),{floor:function(t){return u(Math.floor(o(t)))},ceil:function(t){return u(Math.ceil(o(t)))}}))},e.copy=function(){return Bu(e,ta().base(i))},e}function na(t,n){return t<0?-Math.pow(-t,n):Math.pow(t,n)}function ea(){function t(t,n){return(n=na(n,e)-(t=na(t,e)))?function(r){return(na(r,e)-t)/n}:Tx(n)}function n(t,n){return n=na(n,e)-(t=na(t,e)),function(r){return na(t+n*r,1/e)}}var e=1,r=ju(t,n),i=r.domain;return r.exponent=function(t){return arguments.length?(e=+t,i(i())):e},r.copy=function(){return Bu(r,ea().exponent(e))},Xu(r)}function ra(){return ea().exponent(.5)}function ia(){function t(){var t=0,o=Math.max(1,r.length);for(i=new Array(o-1);++t<o;)i[t-1]=Vf(e,t/o);return n}function n(t){if(!isNaN(t=+t))return r[kf(i,t)]}var e=[],r=[],i=[];return n.invertExtent=function(t){var n=r.indexOf(t);return n<0?[NaN,NaN]:[n>0?i[n-1]:e[0],n<i.length?i[n]:e[e.length-1]]},n.domain=function(n){if(!arguments.length)return e.slice();e=[];for(var r,i=0,o=n.length;i<o;++i)null==(r=n[i])||isNaN(r=+r)||e.push(r);return e.sort(Mf),t()},n.range=function(n){return arguments.length?(r=wx.call(n),t()):r.slice()},n.quantiles=function(){return i.slice()},n.copy=function(){return ia().domain(e).range(r)},n}function oa(){function t(t){if(t<=t)return u[kf(o,t,0,i)]}function n(){var n=-1;for(o=new Array(i);++n<i;)o[n]=((n+1)*r-(n-i)*e)/(i+1);return t}var e=0,r=1,i=1,o=[.5],u=[0,1];return t.domain=function(t){return arguments.length?(e=+t[0],r=+t[1],n()):[e,r]},t.range=function(t){return arguments.length?(i=(u=wx.call(t)).length-1,n()):u.slice()},t.invertExtent=function(t){var n=u.indexOf(t);return n<0?[NaN,NaN]:n<1?[e,o[0]]:n>=i?[o[i-1],r]:[o[n-1],o[n]]},t.copy=function(){return oa().domain([e,r]).range(u)},Xu(t)}function ua(){function t(t){if(t<=t)return e[kf(n,t,0,r)]}var n=[.5],e=[0,1],r=1;return t.domain=function(i){return arguments.length?(n=wx.call(i),r=Math.min(n.length,e.length-1),t):n.slice()},t.range=function(i){return arguments.length?(e=wx.call(i),r=Math.min(n.length,e.length-1),t):e.slice()},t.invertExtent=function(t){var r=e.indexOf(t);return[n[r-1],n[r]]},t.copy=function(){return ua().domain(n).range(e)},t}function aa(t,n,e,r){function i(n){return t(n=new Date(+n)),n}return i.floor=i,i.ceil=function(e){return t(e=new Date(e-1)),n(e,1),t(e),e},i.round=function(t){var n=i(t),e=i.ceil(t);return t-n<e-t?n:e},i.offset=function(t,e){return n(t=new Date(+t),null==e?1:Math.floor(e)),t},i.range=function(e,r,o){var u,a=[];if(e=i.ceil(e),o=null==o?1:Math.floor(o),!(e<r&&o>0))return a;do{a.push(u=new Date(+e)),n(e,o),t(e)}while(u<e&&e<r);return a},i.filter=function(e){return aa(function(n){if(n>=n)for(;t(n),!e(n);)n.setTime(n-1)},function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;n(t,-1),!e(t););else for(;--r>=0;)for(;n(t,1),!e(t););})},e&&(i.count=function(n,r){return Ex.setTime(+n),Cx.setTime(+r),t(Ex),t(Cx),Math.floor(e(Ex,Cx))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(n){return r(n)%t==0 | |
}:function(n){return i.count(0,n)%t==0}):i:null}),i}function ca(t){return aa(function(n){n.setDate(n.getDate()-(n.getDay()+7-t)%7),n.setHours(0,0,0,0)},function(t,n){t.setDate(t.getDate()+7*n)},function(t,n){return(n-t-(n.getTimezoneOffset()-t.getTimezoneOffset())*Rx)/Lx})}function sa(t){return aa(function(n){n.setUTCDate(n.getUTCDate()-(n.getUTCDay()+7-t)%7),n.setUTCHours(0,0,0,0)},function(t,n){t.setUTCDate(t.getUTCDate()+7*n)},function(t,n){return(n-t)/Lx})}function fa(t){if(0<=t.y&&t.y<100){var n=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return n.setFullYear(t.y),n}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function la(t){if(0<=t.y&&t.y<100){var n=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return n.setUTCFullYear(t.y),n}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function ha(t){return{y:t,m:0,d:1,H:0,M:0,S:0,L:0}}function pa(t){function n(t,n){return function(e){var r,i,o,u=[],a=-1,c=0,s=t.length;for(e instanceof Date||(e=new Date(+e));++a<s;)37===t.charCodeAt(a)&&(u.push(t.slice(c,a)),null!=(i=Pb[r=t.charAt(++a)])?r=t.charAt(++a):i="e"===r?" ":"0",(o=n[r])&&(r=o(e,i)),u.push(r),c=a+1);return u.push(t.slice(c,a)),u.join("")}}function e(t,n){return function(e){var i,o,u=ha(1900),a=r(u,t,e+="",0);if(a!=e.length)return null;if("Q"in u)return new Date(u.Q);if("p"in u&&(u.H=u.H%12+12*u.p),"V"in u){if(u.V<1||u.V>53)return null;"w"in u||(u.w=1),"Z"in u?(i=la(ha(u.y)),o=i.getUTCDay(),i=o>4||0===o?db.ceil(i):db(i),i=lb.offset(i,7*(u.V-1)),u.y=i.getUTCFullYear(),u.m=i.getUTCMonth(),u.d=i.getUTCDate()+(u.w+6)%7):(i=n(ha(u.y)),o=i.getDay(),i=o>4||0===o?jx.ceil(i):jx(i),i=Ix.offset(i,7*(u.V-1)),u.y=i.getFullYear(),u.m=i.getMonth(),u.d=i.getDate()+(u.w+6)%7)}else("W"in u||"U"in u)&&("w"in u||(u.w="u"in u?u.u%7:"W"in u?1:0),o="Z"in u?la(ha(u.y)).getUTCDay():n(ha(u.y)).getDay(),u.m=0,u.d="W"in u?(u.w+6)%7+7*u.W-(o+5)%7:u.w+7*u.U-(o+6)%7);return"Z"in u?(u.H+=u.Z/100|0,u.M+=u.Z%100,la(u)):n(u)}}function r(t,n,e,r){for(var i,o,u=0,a=n.length,c=e.length;u<a;){if(r>=c)return-1;if(37===(i=n.charCodeAt(u++))){if(i=n.charAt(u++),!(o=H[i in Pb?n.charAt(u++):i])||(r=o(t,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function i(t,n,e){var r=C.exec(n.slice(e));return r?(t.p=z[r[0].toLowerCase()],e+r[0].length):-1}function o(t,n,e){var r=L.exec(n.slice(e));return r?(t.w=D[r[0].toLowerCase()],e+r[0].length):-1}function u(t,n,e){var r=P.exec(n.slice(e));return r?(t.w=R[r[0].toLowerCase()],e+r[0].length):-1}function a(t,n,e){var r=O.exec(n.slice(e));return r?(t.m=F[r[0].toLowerCase()],e+r[0].length):-1}function c(t,n,e){var r=q.exec(n.slice(e));return r?(t.m=U[r[0].toLowerCase()],e+r[0].length):-1}function s(t,n,e){return r(t,w,n,e)}function f(t,n,e){return r(t,M,n,e)}function l(t,n,e){return r(t,T,n,e)}function h(t){return S[t.getDay()]}function p(t){return k[t.getDay()]}function d(t){return E[t.getMonth()]}function v(t){return A[t.getMonth()]}function g(t){return N[+(t.getHours()>=12)]}function y(t){return S[t.getUTCDay()]}function _(t){return k[t.getUTCDay()]}function m(t){return E[t.getUTCMonth()]}function x(t){return A[t.getUTCMonth()]}function b(t){return N[+(t.getUTCHours()>=12)]}var w=t.dateTime,M=t.date,T=t.time,N=t.periods,k=t.days,S=t.shortDays,A=t.months,E=t.shortMonths,C=ga(N),z=ya(N),P=ga(k),R=ya(k),L=ga(S),D=ya(S),q=ga(A),U=ya(A),O=ga(E),F=ya(E),Y={a:h,A:p,b:d,B:v,c:null,d:Ua,e:Ua,f:Ha,H:Oa,I:Fa,j:Ya,L:Ia,m:Ba,M:ja,p:g,Q:_c,s:mc,S:Xa,u:Wa,U:Va,V:$a,w:Za,W:Ga,x:null,X:null,y:Qa,Y:Ja,Z:Ka,"%":yc},I={a:y,A:_,b:m,B:x,c:null,d:tc,e:tc,f:oc,H:nc,I:ec,j:rc,L:ic,m:uc,M:ac,p:b,Q:_c,s:mc,S:cc,u:sc,U:fc,V:lc,w:hc,W:pc,x:null,X:null,y:dc,Y:vc,Z:gc,"%":yc},H={a:o,A:u,b:a,B:c,c:s,d:Sa,e:Sa,f:Ra,H:Ea,I:Ea,j:Aa,L:Pa,m:ka,M:Ca,p:i,Q:Da,s:qa,S:za,u:ma,U:xa,V:ba,w:_a,W:wa,x:f,X:l,y:Ta,Y:Ma,Z:Na,"%":La};return Y.x=n(M,Y),Y.X=n(T,Y),Y.c=n(w,Y),I.x=n(M,I),I.X=n(T,I),I.c=n(w,I),{format:function(t){var e=n(t+="",Y);return e.toString=function(){return t},e},parse:function(t){var n=e(t+="",fa);return n.toString=function(){return t},n},utcFormat:function(t){var e=n(t+="",I);return e.toString=function(){return t},e},utcParse:function(t){var n=e(t,la);return n.toString=function(){return t},n}}}function da(t,n,e){var r=t<0?"-":"",i=(r?-t:t)+"",o=i.length;return r+(o<e?new Array(e-o+1).join(n)+i:i)}function va(t){return t.replace(Db,"\\$&")}function ga(t){return new RegExp("^(?:"+t.map(va).join("|")+")","i")}function ya(t){for(var n={},e=-1,r=t.length;++e<r;)n[t[e].toLowerCase()]=e;return n}function _a(t,n,e){var r=Rb.exec(n.slice(e,e+1));return r?(t.w=+r[0],e+r[0].length):-1}function ma(t,n,e){var r=Rb.exec(n.slice(e,e+1));return r?(t.u=+r[0],e+r[0].length):-1}function xa(t,n,e){var r=Rb.exec(n.slice(e,e+2));return r?(t.U=+r[0],e+r[0].length):-1}function ba(t,n,e){var r=Rb.exec(n.slice(e,e+2));return r?(t.V=+r[0],e+r[0].length):-1}function wa(t,n,e){var r=Rb.exec(n.slice(e,e+2));return r?(t.W=+r[0],e+r[0].length):-1}function Ma(t,n,e){var r=Rb.exec(n.slice(e,e+4));return r?(t.y=+r[0],e+r[0].length):-1}function Ta(t,n,e){var r=Rb.exec(n.slice(e,e+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),e+r[0].length):-1}function Na(t,n,e){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(n.slice(e,e+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),e+r[0].length):-1}function ka(t,n,e){var r=Rb.exec(n.slice(e,e+2));return r?(t.m=r[0]-1,e+r[0].length):-1}function Sa(t,n,e){var r=Rb.exec(n.slice(e,e+2));return r?(t.d=+r[0],e+r[0].length):-1}function Aa(t,n,e){var r=Rb.exec(n.slice(e,e+3));return r?(t.m=0,t.d=+r[0],e+r[0].length):-1}function Ea(t,n,e){var r=Rb.exec(n.slice(e,e+2));return r?(t.H=+r[0],e+r[0].length):-1}function Ca(t,n,e){var r=Rb.exec(n.slice(e,e+2));return r?(t.M=+r[0],e+r[0].length):-1}function za(t,n,e){var r=Rb.exec(n.slice(e,e+2));return r?(t.S=+r[0],e+r[0].length):-1}function Pa(t,n,e){var r=Rb.exec(n.slice(e,e+3));return r?(t.L=+r[0],e+r[0].length):-1}function Ra(t,n,e){var r=Rb.exec(n.slice(e,e+6));return r?(t.L=Math.floor(r[0]/1e3),e+r[0].length):-1}function La(t,n,e){var r=Lb.exec(n.slice(e,e+1));return r?e+r[0].length:-1}function Da(t,n,e){var r=Rb.exec(n.slice(e));return r?(t.Q=+r[0],e+r[0].length):-1}function qa(t,n,e){var r=Rb.exec(n.slice(e));return r?(t.Q=1e3*+r[0],e+r[0].length):-1}function Ua(t,n){return da(t.getDate(),n,2)}function Oa(t,n){return da(t.getHours(),n,2)}function Fa(t,n){return da(t.getHours()%12||12,n,2)}function Ya(t,n){return da(1+Ix.count(ob(t),t),n,3)}function Ia(t,n){return da(t.getMilliseconds(),n,3)}function Ha(t,n){return Ia(t,n)+"000"}function Ba(t,n){return da(t.getMonth()+1,n,2)}function ja(t,n){return da(t.getMinutes(),n,2)}function Xa(t,n){return da(t.getSeconds(),n,2)}function Wa(t){var n=t.getDay();return 0===n?7:n}function Va(t,n){return da(Bx.count(ob(t),t),n,2)}function $a(t,n){var e=t.getDay();return t=e>=4||0===e?Vx(t):Vx.ceil(t),da(Vx.count(ob(t),t)+(4===ob(t).getDay()),n,2)}function Za(t){return t.getDay()}function Ga(t,n){return da(jx.count(ob(t),t),n,2)}function Qa(t,n){return da(t.getFullYear()%100,n,2)}function Ja(t,n){return da(t.getFullYear()%1e4,n,4)}function Ka(t){var n=t.getTimezoneOffset();return(n>0?"-":(n*=-1,"+"))+da(n/60|0,"0",2)+da(n%60,"0",2)}function tc(t,n){return da(t.getUTCDate(),n,2)}function nc(t,n){return da(t.getUTCHours(),n,2)}function ec(t,n){return da(t.getUTCHours()%12||12,n,2)}function rc(t,n){return da(1+lb.count(Eb(t),t),n,3)}function ic(t,n){return da(t.getUTCMilliseconds(),n,3)}function oc(t,n){return ic(t,n)+"000"}function uc(t,n){return da(t.getUTCMonth()+1,n,2)}function ac(t,n){return da(t.getUTCMinutes(),n,2)}function cc(t,n){return da(t.getUTCSeconds(),n,2)}function sc(t){var n=t.getUTCDay();return 0===n?7:n}function fc(t,n){return da(pb.count(Eb(t),t),n,2)}function lc(t,n){var e=t.getUTCDay();return t=e>=4||0===e?yb(t):yb.ceil(t),da(yb.count(Eb(t),t)+(4===Eb(t).getUTCDay()),n,2)}function hc(t){return t.getUTCDay()}function pc(t,n){return da(db.count(Eb(t),t),n,2)}function dc(t,n){return da(t.getUTCFullYear()%100,n,2)}function vc(t,n){return da(t.getUTCFullYear()%1e4,n,4)}function gc(){return"+0000"}function yc(){return"%"}function _c(t){return+t}function mc(t){return Math.floor(+t/1e3)}function xc(n){return Cb=pa(n),t.timeFormat=Cb.format,t.timeParse=Cb.parse,t.utcFormat=Cb.utcFormat,t.utcParse=Cb.utcParse,Cb}function bc(t){return t.toISOString()}function wc(t){var n=new Date(t);return isNaN(n)?null:n}function Mc(t){return new Date(t)}function Tc(t){return t instanceof Date?+t:+new Date(+t)}function Nc(t,n,e,r,o,u,a,c,s){function f(i){return(a(i)<i?v:u(i)<i?g:o(i)<i?y:r(i)<i?_:n(i)<i?e(i)<i?m:x:t(i)<i?b:w)(i)}function l(n,e,r,o){if(null==n&&(n=10),"number"==typeof n){var u=Math.abs(r-e)/n,a=Tf(function(t){return t[2]}).right(M,u);a===M.length?(o=i(e/jb,r/jb,n),n=t):a?(a=M[u/M[a-1][2]<M[a][2]/u?a-1:a],o=a[1],n=a[0]):(o=Math.max(i(e,r,n),1),n=c)}return null==o?n:n.every(o)}var h=ju(Ou,cp),p=h.invert,d=h.domain,v=s(".%L"),g=s(":%S"),y=s("%I:%M"),_=s("%I %p"),m=s("%a %d"),x=s("%b %d"),b=s("%B"),w=s("%Y"),M=[[a,1,Ob],[a,5,5*Ob],[a,15,15*Ob],[a,30,30*Ob],[u,1,Fb],[u,5,5*Fb],[u,15,15*Fb],[u,30,30*Fb],[o,1,Yb],[o,3,3*Yb],[o,6,6*Yb],[o,12,12*Yb],[r,1,Ib],[r,2,2*Ib],[e,1,Hb],[n,1,Bb],[n,3,3*Bb],[t,1,jb]];return h.invert=function(t){return new Date(p(t))},h.domain=function(t){return arguments.length?d(bx.call(t,Tc)):d().map(Mc)},h.ticks=function(t,n){var e,r=d(),i=r[0],o=r[r.length-1],u=o<i;return u&&(e=i,i=o,o=e),e=l(t,i,o,n),e=e?e.range(i,o+1):[],u?e.reverse():e},h.tickFormat=function(t,n){return null==n?f:s(n)},h.nice=function(t,n){var e=d();return(t=l(t,e[0],e[e.length-1],n))?d(Ax(e,t)):h},h.copy=function(){return Bu(h,Nc(t,n,e,r,o,u,a,c,s))},h}function kc(t){var n=t.length;return function(e){return t[Math.max(0,Math.min(n-1,Math.floor(e*n)))]}}function Sc(t){function n(n){var o=(n-e)/(r-e);return t(i?Math.max(0,Math.min(1,o)):o)}var e=0,r=1,i=!1;return n.domain=function(t){return arguments.length?(e=+t[0],r=+t[1],n):[e,r]},n.clamp=function(t){return arguments.length?(i=!!t,n):i},n.interpolator=function(e){return arguments.length?(t=e,n):t},n.copy=function(){return Sc(t).domain([e,r]).clamp(i)},Xu(n)}function Ac(t){return t>1?0:t<-1?gw:Math.acos(t)}function Ec(t){return t>=1?yw:t<=-1?-yw:Math.asin(t)}function Cc(t){return t.innerRadius}function zc(t){return t.outerRadius}function Pc(t){return t.startAngle}function Rc(t){return t.endAngle}function Lc(t){return t&&t.padAngle}function Dc(t,n,e,r,i,o,u,a){var c=e-t,s=r-n,f=u-i,l=a-o,h=(f*(n-o)-l*(t-i))/(l*c-f*s);return[t+h*c,n+h*s]}function qc(t,n,e,r,i,o,u){var a=t-e,c=n-r,s=(u?o:-o)/dw(a*a+c*c),f=s*c,l=-s*a,h=t+f,p=n+l,d=e+f,v=r+l,g=(h+d)/2,y=(p+v)/2,_=d-h,m=v-p,x=_*_+m*m,b=i-o,w=h*v-d*p,M=(m<0?-1:1)*dw(lw(0,b*b*x-w*w)),T=(w*m-_*M)/x,N=(-w*_-m*M)/x,k=(w*m+_*M)/x,S=(-w*_+m*M)/x,A=T-g,E=N-y,C=k-g,z=S-y;return A*A+E*E>C*C+z*z&&(T=k,N=S),{cx:T,cy:N,x01:-f,y01:-l,x11:T*(i/b-1),y11:N*(i/b-1)}}function Uc(t){this._context=t}function Oc(t){return t[0]}function Fc(t){return t[1]}function Yc(t){this._curve=t}function Ic(t){function n(n){return new Yc(t(n))}return n._curve=t,n}function Hc(t){var n=t.curve;return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t.curve=function(t){return arguments.length?n(Ic(t)):n()._curve},t}function Bc(t){return t.source}function jc(t){return t.target}function Xc(t){function n(){var n,a=Cw.call(arguments),c=e.apply(this,a),s=r.apply(this,a);if(u||(u=n=Oe()),t(u,+i.apply(this,(a[0]=c,a)),+o.apply(this,a),+i.apply(this,(a[0]=s,a)),+o.apply(this,a)),n)return u=null,n+""||null}var e=Bc,r=jc,i=Oc,o=Fc,u=null;return n.source=function(t){return arguments.length?(e=t,n):e},n.target=function(t){return arguments.length?(r=t,n):r},n.x=function(t){return arguments.length?(i="function"==typeof t?t:aw(+t),n):i},n.y=function(t){return arguments.length?(o="function"==typeof t?t:aw(+t),n):o},n.context=function(t){return arguments.length?(u=null==t?null:t,n):u},n}function Wc(t,n,e,r,i){t.moveTo(n,e),t.bezierCurveTo(n=(n+r)/2,e,n,i,r,i)}function Vc(t,n,e,r,i){t.moveTo(n,e),t.bezierCurveTo(n,e=(e+i)/2,r,e,r,i)}function $c(t,n,e,r,i){var o=Ew(n,e),u=Ew(n,e=(e+i)/2),a=Ew(r,e),c=Ew(r,i);t.moveTo(o[0],o[1]),t.bezierCurveTo(u[0],u[1],a[0],a[1],c[0],c[1])}function Zc(){return Xc(Wc)}function Gc(){return Xc(Vc)}function Qc(){var t=Xc($c);return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t}function Jc(t,n,e){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+n)/6,(t._y0+4*t._y1+e)/6)}function Kc(t){this._context=t}function ts(t){this._context=t}function ns(t){this._context=t}function es(t,n){this._basis=new Kc(t),this._beta=n}function rs(t,n,e){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-n),t._y2+t._k*(t._y1-e),t._x2,t._y2)}function is(t,n){this._context=t,this._k=(1-n)/6}function os(t,n){this._context=t,this._k=(1-n)/6}function us(t,n){this._context=t,this._k=(1-n)/6}function as(t,n,e){var r=t._x1,i=t._y1,o=t._x2,u=t._y2;if(t._l01_a>vw){var a=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,c=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*a-t._x0*t._l12_2a+t._x2*t._l01_2a)/c,i=(i*a-t._y0*t._l12_2a+t._y2*t._l01_2a)/c}if(t._l23_a>vw){var s=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,f=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*s+t._x1*t._l23_2a-n*t._l12_2a)/f,u=(u*s+t._y1*t._l23_2a-e*t._l12_2a)/f}t._context.bezierCurveTo(r,i,o,u,t._x2,t._y2)}function cs(t,n){this._context=t,this._alpha=n}function ss(t,n){this._context=t,this._alpha=n}function fs(t,n){this._context=t,this._alpha=n}function ls(t){this._context=t}function hs(t){return t<0?-1:1}function ps(t,n,e){var r=t._x1-t._x0,i=n-t._x1,o=(t._y1-t._y0)/(r||i<0&&-0),u=(e-t._y1)/(i||r<0&&-0),a=(o*i+u*r)/(r+i);return(hs(o)+hs(u))*Math.min(Math.abs(o),Math.abs(u),.5*Math.abs(a))||0}function ds(t,n){var e=t._x1-t._x0;return e?(3*(t._y1-t._y0)/e-n)/2:n}function vs(t,n,e){var r=t._x0,i=t._y0,o=t._x1,u=t._y1,a=(o-r)/3;t._context.bezierCurveTo(r+a,i+a*n,o-a,u-a*e,o,u)}function gs(t){this._context=t}function ys(t){this._context=new _s(t)}function _s(t){this._context=t}function ms(t){return new gs(t)}function xs(t){return new ys(t)}function bs(t){this._context=t}function ws(t){var n,e,r=t.length-1,i=new Array(r),o=new Array(r),u=new Array(r);for(i[0]=0,o[0]=2,u[0]=t[0]+2*t[1],n=1;n<r-1;++n)i[n]=1,o[n]=4,u[n]=4*t[n]+2*t[n+1];for(i[r-1]=2,o[r-1]=7,u[r-1]=8*t[r-1]+t[r],n=1;n<r;++n)e=i[n]/o[n-1],o[n]-=e,u[n]-=e*u[n-1];for(i[r-1]=u[r-1]/o[r-1],n=r-2;n>=0;--n)i[n]=(u[n]-i[n+1])/o[n];for(o[r-1]=(t[r]+i[r-1])/2,n=0;n<r-1;++n)o[n]=2*t[n+1]-i[n+1];return[i,o]}function Ms(t,n){this._context=t,this._t=n}function Ts(t){return new Ms(t,0)}function Ns(t){return new Ms(t,1)}function ks(t,n){return t[n]}function Ss(t){for(var n,e=0,r=-1,i=t.length;++r<i;)(n=+t[r][1])&&(e+=n);return e}function As(t){return t[0]}function Es(t){return t[1]}function Cs(){this._=null}function zs(t){t.U=t.C=t.L=t.R=t.P=t.N=null}function Ps(t,n){var e=n,r=n.R,i=e.U;i?i.L===e?i.L=r:i.R=r:t._=r,r.U=i,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Rs(t,n){var e=n,r=n.L,i=e.U;i?i.L===e?i.L=r:i.R=r:t._=r,r.U=i,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Ls(t){for(;t.L;)t=t.L;return t}function Ds(t,n,e,r){var i=[null,null],o=kM.push(i)-1;return i.left=t,i.right=n,e&&Us(i,t,n,e),r&&Us(i,n,t,r),TM[t.index].halfedges.push(o),TM[n.index].halfedges.push(o),i}function qs(t,n,e){var r=[n,e];return r.left=t,r}function Us(t,n,e,r){t[0]||t[1]?t.left===e?t[1]=r:t[0]=r:(t[0]=r,t.left=n,t.right=e)}function Os(t,n,e,r,i){var o,u=t[0],a=t[1],c=u[0],s=u[1],f=a[0],l=a[1],h=0,p=1,d=f-c,v=l-s;if(o=n-c,d||!(o>0)){if(o/=d,d<0){if(o<h)return;o<p&&(p=o)}else if(d>0){if(o>p)return;o>h&&(h=o)}if(o=r-c,d||!(o<0)){if(o/=d,d<0){if(o>p)return;o>h&&(h=o)}else if(d>0){if(o<h)return;o<p&&(p=o)}if(o=e-s,v||!(o>0)){if(o/=v,v<0){if(o<h)return;o<p&&(p=o)}else if(v>0){if(o>p)return;o>h&&(h=o)}if(o=i-s,v||!(o<0)){if(o/=v,v<0){if(o>p)return;o>h&&(h=o)}else if(v>0){if(o<h)return;o<p&&(p=o)}return!(h>0||p<1)||(h>0&&(t[0]=[c+h*d,s+h*v]),p<1&&(t[1]=[c+p*d,s+p*v]),!0)}}}}}function Fs(t,n,e,r,i){var o=t[1];if(o)return!0;var u,a,c=t[0],s=t.left,f=t.right,l=s[0],h=s[1],p=f[0],d=f[1],v=(l+p)/2,g=(h+d)/2;if(d===h){if(v<n||v>=r)return;if(l>p){if(c){if(c[1]>=i)return}else c=[v,e];o=[v,i]}else{if(c){if(c[1]<e)return}else c=[v,i];o=[v,e]}}else if(u=(l-p)/(d-h),a=g-u*v,u<-1||u>1)if(l>p){if(c){if(c[1]>=i)return}else c=[(e-a)/u,e];o=[(i-a)/u,i]}else{if(c){if(c[1]<e)return}else c=[(i-a)/u,i];o=[(e-a)/u,e]}else if(h<d){if(c){if(c[0]>=r)return}else c=[n,u*n+a];o=[r,u*r+a]}else{if(c){if(c[0]<n)return}else c=[r,u*r+a];o=[n,u*n+a]}return t[0]=c,t[1]=o,!0}function Ys(t,n,e,r){for(var i,o=kM.length;o--;)Fs(i=kM[o],t,n,e,r)&&Os(i,t,n,e,r)&&(Math.abs(i[0][0]-i[1][0])>EM||Math.abs(i[0][1]-i[1][1])>EM)||delete kM[o]}function Is(t){return TM[t.index]={site:t,halfedges:[]}}function Hs(t,n){var e=t.site,r=n.left,i=n.right;return e===i&&(i=r,r=e),i?Math.atan2(i[1]-r[1],i[0]-r[0]):(e===r?(r=n[1],i=n[0]):(r=n[0],i=n[1]),Math.atan2(r[0]-i[0],i[1]-r[1]))}function Bs(t,n){return n[+(n.left!==t.site)]}function js(t,n){return n[+(n.left===t.site)]}function Xs(){for(var t,n,e,r,i=0,o=TM.length;i<o;++i)if((t=TM[i])&&(r=(n=t.halfedges).length)){var u=new Array(r),a=new Array(r);for(e=0;e<r;++e)u[e]=e,a[e]=Hs(t,kM[n[e]]);for(u.sort(function(t,n){return a[n]-a[t]}),e=0;e<r;++e)a[e]=n[u[e]];for(e=0;e<r;++e)n[e]=a[e]}}function Ws(t,n,e,r){var i,o,u,a,c,s,f,l,h,p,d,v,g=TM.length,y=!0;for(i=0;i<g;++i)if(o=TM[i]){for(u=o.site,c=o.halfedges,a=c.length;a--;)kM[c[a]]||c.splice(a,1);for(a=0,s=c.length;a<s;)p=js(o,kM[c[a]]),d=p[0],v=p[1],f=Bs(o,kM[c[++a%s]]),l=f[0],h=f[1],(Math.abs(d-l)>EM||Math.abs(v-h)>EM)&&(c.splice(a,0,kM.push(qs(u,p,Math.abs(d-t)<EM&&r-v>EM?[t,Math.abs(l-t)<EM?h:r]:Math.abs(v-r)<EM&&e-d>EM?[Math.abs(h-r)<EM?l:e,r]:Math.abs(d-e)<EM&&v-n>EM?[e,Math.abs(l-e)<EM?h:n]:Math.abs(v-n)<EM&&d-t>EM?[Math.abs(h-n)<EM?l:t,n]:null))-1),++s);s&&(y=!1)}if(y){var _,m,x,b=1/0;for(i=0,y=null;i<g;++i)(o=TM[i])&&(u=o.site,_=u[0]-t,m=u[1]-n,(x=_*_+m*m)<b&&(b=x,y=o));if(y){var w=[t,n],M=[t,r],T=[e,r],N=[e,n];y.halfedges.push(kM.push(qs(u=y.site,w,M))-1,kM.push(qs(u,M,T))-1,kM.push(qs(u,T,N))-1,kM.push(qs(u,N,w))-1)}}for(i=0;i<g;++i)(o=TM[i])&&(o.halfedges.length||delete TM[i])}function Vs(){zs(this),this.x=this.y=this.arc=this.site=this.cy=null}function $s(t){var n=t.P,e=t.N;if(n&&e){var r=n.site,i=t.site,o=e.site;if(r!==o){var u=i[0],a=i[1],c=r[0]-u,s=r[1]-a,f=o[0]-u,l=o[1]-a,h=2*(c*l-s*f);if(!(h>=-CM)){var p=c*c+s*s,d=f*f+l*l,v=(l*p-s*d)/h,g=(c*d-f*p)/h,y=SM.pop()||new Vs;y.arc=t,y.site=i,y.x=v+u,y.y=(y.cy=g+a)+Math.sqrt(v*v+g*g),t.circle=y;for(var _=null,m=NM._;m;)if(y.y<m.y||y.y===m.y&&y.x<=m.x){if(!m.L){_=m.P;break}m=m.L}else{if(!m.R){_=m;break}m=m.R}NM.insert(_,y),_||(wM=y)}}}}function Zs(t){var n=t.circle;n&&(n.P||(wM=n.N),NM.remove(n),SM.push(n),zs(n),t.circle=null)}function Gs(){zs(this),this.edge=this.site=this.circle=null}function Qs(t){var n=AM.pop()||new Gs;return n.site=t,n}function Js(t){Zs(t),MM.remove(t),AM.push(t),zs(t)}function Ks(t){var n=t.circle,e=n.x,r=n.cy,i=[e,r],o=t.P,u=t.N,a=[t];Js(t);for(var c=o;c.circle&&Math.abs(e-c.circle.x)<EM&&Math.abs(r-c.circle.cy)<EM;)o=c.P,a.unshift(c),Js(c),c=o;a.unshift(c),Zs(c);for(var s=u;s.circle&&Math.abs(e-s.circle.x)<EM&&Math.abs(r-s.circle.cy)<EM;)u=s.N,a.push(s),Js(s),s=u;a.push(s),Zs(s);var f,l=a.length;for(f=1;f<l;++f)s=a[f],c=a[f-1],Us(s.edge,c.site,s.site,i);c=a[0],s=a[l-1],s.edge=Ds(c.site,s.site,null,i),$s(c),$s(s)}function tf(t){for(var n,e,r,i,o=t[0],u=t[1],a=MM._;a;)if((r=nf(a,u)-o)>EM)a=a.L;else{if(!((i=o-ef(a,u))>EM)){r>-EM?(n=a.P,e=a):i>-EM?(n=a,e=a.N):n=e=a;break}if(!a.R){n=a;break}a=a.R}Is(t);var c=Qs(t);if(MM.insert(n,c),n||e){if(n===e)return Zs(n),e=Qs(n.site),MM.insert(c,e),c.edge=e.edge=Ds(n.site,c.site),$s(n),void $s(e);if(!e)return void(c.edge=Ds(n.site,c.site));Zs(n),Zs(e);var s=n.site,f=s[0],l=s[1],h=t[0]-f,p=t[1]-l,d=e.site,v=d[0]-f,g=d[1]-l,y=2*(h*g-p*v),_=h*h+p*p,m=v*v+g*g,x=[(g*_-p*m)/y+f,(h*m-v*_)/y+l];Us(e.edge,s,d,x),c.edge=Ds(s,t,null,x),e.edge=Ds(t,d,null,x),$s(n),$s(e)}}function nf(t,n){var e=t.site,r=e[0],i=e[1],o=i-n;if(!o)return r;var u=t.P;if(!u)return-1/0;e=u.site;var a=e[0],c=e[1],s=c-n;if(!s)return a;var f=a-r,l=1/o-1/s,h=f/s;return l?(-h+Math.sqrt(h*h-2*l*(f*f/(-2*s)-c+s/2+i-o/2)))/l+r:(r+a)/2}function ef(t,n){var e=t.N;if(e)return nf(e,n);var r=t.site;return r[1]===n?r[0]:1/0}function rf(t,n,e){return(t[0]-e[0])*(n[1]-t[1])-(t[0]-n[0])*(e[1]-t[1])}function of(t,n){return n[1]-t[1]||n[0]-t[0]}function uf(t,n){var e,r,i,o=t.sort(of).pop();for(kM=[],TM=new Array(t.length),MM=new Cs,NM=new Cs;;)if(i=wM,o&&(!i||o[1]<i.y||o[1]===i.y&&o[0]<i.x))o[0]===e&&o[1]===r||(tf(o),e=o[0],r=o[1]),o=t.pop();else{if(!i)break;Ks(i.arc)}if(Xs(),n){var u=+n[0][0],a=+n[0][1],c=+n[1][0],s=+n[1][1];Ys(u,a,c,s),Ws(u,a,c,s)}this.edges=kM,this.cells=TM,MM=NM=kM=TM=null}function af(t,n,e){this.target=t,this.type=n,this.transform=e}function cf(t,n,e){this.k=t,this.x=n,this.y=e}function sf(t){return t.__zoom||RM}function ff(){t.event.stopImmediatePropagation()}function lf(){return!t.event.button}function hf(){var t,n,e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,t=e.width.baseVal.value,n=e.height.baseVal.value):(t=e.clientWidth,n=e.clientHeight),[[0,0],[t,n]]}function pf(){return this.__zoom||RM}function df(){return-t.event.deltaY*(t.event.deltaMode?120:1)/500}function vf(){return"ontouchstart"in this}function gf(t,n,e){var r=t.invertX(n[0][0])-e[0][0],i=t.invertX(n[1][0])-e[1][0],o=t.invertY(n[0][1])-e[0][1],u=t.invertY(n[1][1])-e[1][1];return t.translate(i>r?(r+i)/2:Math.min(0,r)||Math.max(0,i),u>o?(o+u)/2:Math.min(0,o)||Math.max(0,u))}function yf(){return null}function _f(){for(var t=arguments,n=0,e=t.length;n<e;)"string"!=typeof t[n]&&"number"!=typeof t[n]||(t[n]=function(t){return function(n){return n[t]}}(t[n])),n++;return function(n){for(var e=0,r=t.length;e++<r;)n=t[e-1].call(this,n);return n}}function mf(t,n,e){return(e[0]-n[0])*(t[1]-n[1])<(e[1]-n[1])*(t[0]-n[0])}function xf(t,n,e,r){var i=t[0],o=e[0],u=n[0]-i,a=r[0]-o,c=t[1],s=e[1],f=n[1]-c,l=r[1]-s,h=(a*(c-s)-l*(i-o))/(l*u-a*f);return[i+h*u,c+h*f]}function bf(t){var n=t[0],e=t[t.length-1];return!(n[0]-e[0]||n[1]-e[1])}function wf(){function n(){var t=0;s.forEach(function(n,e){n<pageYOffset-d+y&&(t=e)}),t=Math.min(i-1,t);var n=pageYOffset>o;h!=n&&(h=n,p.classed("graph-scroll-below",h));var e=!h&&pageYOffset>d;l!=e&&(l=e,p.classed("graph-scroll-fixed",l)),h&&(t=i-1),c!=t&&(a.classed("graph-scroll-active",function(n,e){return e===t}),u.call("active",null,t),c=t)}function e(){s=[];var t;a.each(function(n,e){e||(t=this.getBoundingClientRect().top),s.push(this.getBoundingClientRect().top-t)});var n=p.node().getBoundingClientRect(),e=f.node()?f.node().getBoundingClientRect().height:0;d=n.top+pageYOffset,o=n.bottom-e+pageYOffset}function r(){if(l){var n;switch(t.event.keyCode){case 39:if(t.event.metaKey)return;case 40:case 34:n=t.event.metaKey?1/0:1;break;case 37:if(t.event.metaKey)return;case 38:case 33:n=t.event.metaKey?-1/0:-1;break;case 32:n=t.event.shiftKey?-1:1;break;default:return}var e=Math.max(0,Math.min(c+n,i-1));e!=c&&(fh(document.documentElement).interrupt().transition().duration(500).tween("scroll",function(){var t=cp(pageYOffset,s[e]+d);return function(n){scrollTo(0,t(n))}}),t.event.preventDefault())}}var i,o,u=g("scroll","active"),a=fh("null"),c=NaN,s=[],f=fh("null"),l=null,h=null,p=fh("body"),d=0,v=Math.random(),y=200,_={};return _.container=function(t){return t?(p=t,_):p},_.graph=function(t){return t?(f=t,_):f},_.eventId=function(t){return t?(v=t,_):v},_.sections=function(t){return t?(a=t,i=a.size(),fh(window).on("scroll.gscroll"+v,n).on("resize.gscroll"+v,e).on("keydown.gscroll"+v,r),e(),window["gscrollTimer"+v]&&window["gscrollTimer"+v].stop(),window["gscrollTimer"+v]=bn(n),_):a},_.on=function(){var t=u.on.apply(u,arguments);return t===u?_:t},_.offset=function(t){return t?(y=t,_):y},_}var Mf=function(t,n){return t<n?-1:t>n?1:t>=n?0:NaN},Tf=function(t){return 1===t.length&&(t=n(t)),{left:function(n,e,r,i){for(null==r&&(r=0),null==i&&(i=n.length);r<i;){var o=r+i>>>1;t(n[o],e)<0?r=o+1:i=o}return r},right:function(n,e,r,i){for(null==r&&(r=0),null==i&&(i=n.length);r<i;){var o=r+i>>>1;t(n[o],e)>0?i=o:r=o+1}return r}}},Nf=Tf(Mf),kf=Nf.right,Sf=Nf.left,Af=function(t,n){null==n&&(n=e);for(var r=0,i=t.length-1,o=t[0],u=new Array(i<0?0:i);r<i;)u[r]=n(o,o=t[++r]);return u},Ef=function(t,n,r){var i,o,u,a,c=t.length,s=n.length,f=new Array(c*s);for(null==r&&(r=e),i=u=0;i<c;++i)for(a=t[i],o=0;o<s;++o,++u)f[u]=r(a,n[o]);return f},Cf=function(t,n){return n<t?-1:n>t?1:n>=t?0:NaN},zf=function(t){return null===t?NaN:+t},Pf=function(t,n){var e,r,i=t.length,o=0,u=-1,a=0,c=0;if(null==n)for(;++u<i;)isNaN(e=zf(t[u]))||(r=e-a,a+=r/++o,c+=r*(e-a));else for(;++u<i;)isNaN(e=zf(n(t[u],u,t)))||(r=e-a,a+=r/++o,c+=r*(e-a));if(o>1)return c/(o-1)},Rf=function(t,n){var e=Pf(t,n);return e?Math.sqrt(e):e},Lf=function(t,n){var e,r,i,o=t.length,u=-1;if(null==n){for(;++u<o;)if(null!=(e=t[u])&&e>=e)for(r=i=e;++u<o;)null!=(e=t[u])&&(r>e&&(r=e),i<e&&(i=e))}else for(;++u<o;)if(null!=(e=n(t[u],u,t))&&e>=e)for(r=i=e;++u<o;)null!=(e=n(t[u],u,t))&&(r>e&&(r=e),i<e&&(i=e));return[r,i]},Df=Array.prototype,qf=Df.slice,Uf=Df.map,Of=function(t){return function(){return t}},Ff=function(t){return t},Yf=function(t,n,e){t=+t,n=+n,e=(i=arguments.length)<2?(n=t,t=0,1):i<3?1:+e;for(var r=-1,i=0|Math.max(0,Math.ceil((n-t)/e)),o=new Array(i);++r<i;)o[r]=t+r*e;return o},If=Math.sqrt(50),Hf=Math.sqrt(10),Bf=Math.sqrt(2),jf=function(t,n,e){var i,o,u,a,c=-1;if(n=+n,t=+t,e=+e,t===n&&e>0)return[t];if((i=n<t)&&(o=t,t=n,n=o),0===(a=r(t,n,e))||!isFinite(a))return[];if(a>0)for(t=Math.ceil(t/a),n=Math.floor(n/a),u=new Array(o=Math.ceil(n-t+1));++c<o;)u[c]=(t+c)*a;else for(t=Math.floor(t*a),n=Math.ceil(n*a),u=new Array(o=Math.ceil(t-n+1));++c<o;)u[c]=(t-c)/a;return i&&u.reverse(),u},Xf=function(t){return Math.ceil(Math.log(t.length)/Math.LN2)+1},Wf=function(){function t(t){var o,u,a=t.length,c=new Array(a);for(o=0;o<a;++o)c[o]=n(t[o],o,t);var s=e(c),f=s[0],l=s[1],h=r(c,f,l);Array.isArray(h)||(h=i(f,l,h),h=Yf(Math.ceil(f/h)*h,Math.floor(l/h)*h,h));for(var p=h.length;h[0]<=f;)h.shift(),--p;for(;h[p-1]>l;)h.pop(),--p;var d,v=new Array(p+1);for(o=0;o<=p;++o)d=v[o]=[],d.x0=o>0?h[o-1]:f,d.x1=o<p?h[o]:l;for(o=0;o<a;++o)u=c[o],f<=u&&u<=l&&v[kf(h,u,0,p)].push(t[o]);return v}var n=Ff,e=Lf,r=Xf;return t.value=function(e){return arguments.length?(n="function"==typeof e?e:Of(e),t):n},t.domain=function(n){return arguments.length?(e="function"==typeof n?n:Of([n[0],n[1]]),t):e},t.thresholds=function(n){return arguments.length?(r="function"==typeof n?n:Of(Array.isArray(n)?qf.call(n):n),t):r},t},Vf=function(t,n,e){if(null==e&&(e=zf),r=t.length){if((n=+n)<=0||r<2)return+e(t[0],0,t);if(n>=1)return+e(t[r-1],r-1,t);var r,i=(r-1)*n,o=Math.floor(i),u=+e(t[o],o,t);return u+(+e(t[o+1],o+1,t)-u)*(i-o)}},$f=function(t,n,e){return t=Uf.call(t,zf).sort(Mf),Math.ceil((e-n)/(2*(Vf(t,.75)-Vf(t,.25))*Math.pow(t.length,-1/3)))},Zf=function(t,n,e){return Math.ceil((e-n)/(3.5*Rf(t)*Math.pow(t.length,-1/3)))},Gf=function(t,n){var e,r,i=t.length,o=-1;if(null==n){for(;++o<i;)if(null!=(e=t[o])&&e>=e)for(r=e;++o<i;)null!=(e=t[o])&&e>r&&(r=e)}else for(;++o<i;)if(null!=(e=n(t[o],o,t))&&e>=e)for(r=e;++o<i;)null!=(e=n(t[o],o,t))&&e>r&&(r=e);return r},Qf=function(t,n){var e,r=t.length,i=r,o=-1,u=0;if(null==n)for(;++o<r;)isNaN(e=zf(t[o]))?--i:u+=e;else for(;++o<r;)isNaN(e=zf(n(t[o],o,t)))?--i:u+=e;if(i)return u/i},Jf=function(t,n){var e,r=t.length,i=-1,o=[];if(null==n)for(;++i<r;)isNaN(e=zf(t[i]))||o.push(e);else for(;++i<r;)isNaN(e=zf(n(t[i],i,t)))||o.push(e);return Vf(o.sort(Mf),.5)},Kf=function(t){for(var n,e,r,i=t.length,o=-1,u=0;++o<i;)u+=t[o].length;for(e=new Array(u);--i>=0;)for(r=t[i],n=r.length;--n>=0;)e[--u]=r[n];return e},tl=function(t,n){var e,r,i=t.length,o=-1;if(null==n){for(;++o<i;)if(null!=(e=t[o])&&e>=e)for(r=e;++o<i;)null!=(e=t[o])&&r>e&&(r=e)}else for(;++o<i;)if(null!=(e=n(t[o],o,t))&&e>=e)for(r=e;++o<i;)null!=(e=n(t[o],o,t))&&r>e&&(r=e);return r},nl=function(t,n){for(var e=n.length,r=new Array(e);e--;)r[e]=t[n[e]];return r},el=function(t,n){if(e=t.length){var e,r,i=0,o=0,u=t[o];for(null==n&&(n=Mf);++i<e;)(n(r=t[i],u)<0||0!==n(u,u))&&(u=r,o=i);return 0===n(u,u)?o:void 0}},rl=function(t,n,e){for(var r,i,o=(null==e?t.length:e)-(n=null==n?0:+n);o;)i=Math.random()*o--|0,r=t[o+n],t[o+n]=t[i+n],t[i+n]=r;return t},il=function(t,n){var e,r=t.length,i=-1,o=0;if(null==n)for(;++i<r;)(e=+t[i])&&(o+=e);else for(;++i<r;)(e=+n(t[i],i,t))&&(o+=e);return o},ol=function(t){if(!(i=t.length))return[];for(var n=-1,e=tl(t,o),r=new Array(e);++n<e;)for(var i,u=-1,a=r[n]=new Array(i);++u<i;)a[u]=t[u][n];return r},ul=function(){return ol(arguments)},al=Array.prototype.slice,cl=function(t){return t},sl=1,fl=2,ll=3,hl=4,pl=1e-6,dl={value:function(){}};y.prototype=g.prototype={constructor:y,on:function(t,n){var e,r=this._,i=_(t+"",r),o=-1,u=i.length;{if(!(arguments.length<2)){if(null!=n&&"function"!=typeof n)throw new Error("invalid callback: "+n);for(;++o<u;)if(e=(t=i[o]).type)r[e]=x(r[e],t.name,n);else if(null==n)for(e in r)r[e]=x(r[e],t.name,null);return this}for(;++o<u;)if((e=(t=i[o]).type)&&(e=m(r[e],t.name)))return e}},copy:function(){var t={},n=this._;for(var e in n)t[e]=n[e].slice();return new y(t)},call:function(t,n){if((e=arguments.length-2)>0)for(var e,r,i=new Array(e),o=0;o<e;++o)i[o]=arguments[o+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(r=this._[t],o=0,e=r.length;o<e;++o)r[o].value.apply(n,i)},apply:function(t,n,e){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var r=this._[t],i=0,o=r.length;i<o;++i)r[i].value.apply(n,e)}};var vl="http://www.w3.org/1999/xhtml",gl={svg:"http://www.w3.org/2000/svg",xhtml:vl,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},yl=function(t){var n=t+="",e=n.indexOf(":");return e>=0&&"xmlns"!==(n=t.slice(0,e))&&(t=t.slice(e+1)),gl.hasOwnProperty(n)?{space:gl[n],local:t}:t},_l=function(t){var n=yl(t);return(n.local?w:b)(n)},ml=0;T.prototype=M.prototype={constructor:T,get:function(t){for(var n=this._;!(n in t);)if(!(t=t.parentNode))return;return t[n]},set:function(t,n){return t[this._]=n},remove:function(t){return this._ in t&&delete t[this._]},toString:function(){return this._}};var xl=function(t){return function(){return this.matches(t)}};if("undefined"!=typeof document){var bl=document.documentElement;if(!bl.matches){var wl=bl.webkitMatchesSelector||bl.msMatchesSelector||bl.mozMatchesSelector||bl.oMatchesSelector;xl=function(t){return function(){return wl.call(this,t)}}}}var Ml=xl,Tl={};if(t.event=null,"undefined"!=typeof document){"onmouseenter"in document.documentElement||(Tl={mouseenter:"mouseover",mouseleave:"mouseout"})}var Nl=function(t,n,e){var r,i,o=S(t+""),u=o.length;{if(!(arguments.length<2)){for(a=n?E:A,null==e&&(e=!1),r=0;r<u;++r)this.each(a(o[r],n,e));return this}var a=this.node().__on;if(a)for(var c,s=0,f=a.length;s<f;++s)for(r=0,c=a[s];r<u;++r)if((i=o[r]).type===c.type&&i.name===c.name)return c.value}},kl=function(){for(var n,e=t.event;n=e.sourceEvent;)e=n;return e},Sl=function(t,n){var e=t.ownerSVGElement||t;if(e.createSVGPoint){var r=e.createSVGPoint();return r.x=n.clientX,r.y=n.clientY,r=r.matrixTransform(t.getScreenCTM().inverse()),[r.x,r.y]}var i=t.getBoundingClientRect();return[n.clientX-i.left-t.clientLeft,n.clientY-i.top-t.clientTop]},Al=function(t){var n=kl();return n.changedTouches&&(n=n.changedTouches[0]),Sl(t,n)},El=function(t){return null==t?z:function(){return this.querySelector(t)}},Cl=function(t){"function"!=typeof t&&(t=El(t));for(var n=this._groups,e=n.length,r=new Array(e),i=0;i<e;++i)for(var o,u,a=n[i],c=a.length,s=r[i]=new Array(c),f=0;f<c;++f)(o=a[f])&&(u=t.call(o,o.__data__,f,a))&&("__data__"in o&&(u.__data__=o.__data__),s[f]=u);return new yt(r,this._parents)},zl=function(t){return null==t?P:function(){return this.querySelectorAll(t)}},Pl=function(t){"function"!=typeof t&&(t=zl(t)) | |
;for(var n=this._groups,e=n.length,r=[],i=[],o=0;o<e;++o)for(var u,a=n[o],c=a.length,s=0;s<c;++s)(u=a[s])&&(r.push(t.call(u,u.__data__,s,a)),i.push(u));return new yt(r,i)},Rl=function(t){"function"!=typeof t&&(t=Ml(t));for(var n=this._groups,e=n.length,r=new Array(e),i=0;i<e;++i)for(var o,u=n[i],a=u.length,c=r[i]=[],s=0;s<a;++s)(o=u[s])&&t.call(o,o.__data__,s,u)&&c.push(o);return new yt(r,this._parents)},Ll=function(t){return new Array(t.length)},Dl=function(){return new yt(this._enter||this._groups.map(Ll),this._parents)};R.prototype={constructor:R,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,n){return this._parent.insertBefore(t,n)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var ql=function(t){return function(){return t}},Ul="$",Ol=function(t,n){if(!t)return p=new Array(this.size()),s=-1,this.each(function(t){p[++s]=t}),p;var e=n?D:L,r=this._parents,i=this._groups;"function"!=typeof t&&(t=ql(t));for(var o=i.length,u=new Array(o),a=new Array(o),c=new Array(o),s=0;s<o;++s){var f=r[s],l=i[s],h=l.length,p=t.call(f,f&&f.__data__,s,r),d=p.length,v=a[s]=new Array(d),g=u[s]=new Array(d);e(f,l,v,g,c[s]=new Array(h),p,n);for(var y,_,m=0,x=0;m<d;++m)if(y=v[m]){for(m>=x&&(x=m+1);!(_=g[x])&&++x<d;);y._next=_||null}}return u=new yt(u,r),u._enter=a,u._exit=c,u},Fl=function(){return new yt(this._exit||this._groups.map(Ll),this._parents)},Yl=function(t){for(var n=this._groups,e=t._groups,r=n.length,i=e.length,o=Math.min(r,i),u=new Array(r),a=0;a<o;++a)for(var c,s=n[a],f=e[a],l=s.length,h=u[a]=new Array(l),p=0;p<l;++p)(c=s[p]||f[p])&&(h[p]=c);for(;a<r;++a)u[a]=n[a];return new yt(u,this._parents)},Il=function(){for(var t=this._groups,n=-1,e=t.length;++n<e;)for(var r,i=t[n],o=i.length-1,u=i[o];--o>=0;)(r=i[o])&&(u&&u!==r.nextSibling&&u.parentNode.insertBefore(r,u),u=r);return this},Hl=function(t){function n(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}t||(t=q);for(var e=this._groups,r=e.length,i=new Array(r),o=0;o<r;++o){for(var u,a=e[o],c=a.length,s=i[o]=new Array(c),f=0;f<c;++f)(u=a[f])&&(s[f]=u);s.sort(n)}return new yt(i,this._parents).order()},Bl=function(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this},jl=function(){var t=new Array(this.size()),n=-1;return this.each(function(){t[++n]=this}),t},Xl=function(){for(var t=this._groups,n=0,e=t.length;n<e;++n)for(var r=t[n],i=0,o=r.length;i<o;++i){var u=r[i];if(u)return u}return null},Wl=function(){var t=0;return this.each(function(){++t}),t},Vl=function(){return!this.node()},$l=function(t){for(var n=this._groups,e=0,r=n.length;e<r;++e)for(var i,o=n[e],u=0,a=o.length;u<a;++u)(i=o[u])&&t.call(i,i.__data__,u,o);return this},Zl=function(t,n){var e=yl(t);if(arguments.length<2){var r=this.node();return e.local?r.getAttributeNS(e.space,e.local):r.getAttribute(e)}return this.each((null==n?e.local?O:U:"function"==typeof n?e.local?H:I:e.local?Y:F)(e,n))},Gl=function(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView},Ql=function(t,n,e){return arguments.length>1?this.each((null==n?B:"function"==typeof n?X:j)(t,n,null==e?"":e)):W(this.node(),t)},Jl=function(t,n){return arguments.length>1?this.each((null==n?V:"function"==typeof n?Z:$)(t,n)):this.node()[t]};J.prototype={add:function(t){this._names.indexOf(t)<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var n=this._names.indexOf(t);n>=0&&(this._names.splice(n,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var Kl=function(t,n){var e=G(t+"");if(arguments.length<2){for(var r=Q(this.node()),i=-1,o=e.length;++i<o;)if(!r.contains(e[i]))return!1;return!0}return this.each(("function"==typeof n?rt:n?nt:et)(e,n))},th=function(t){return arguments.length?this.each(null==t?it:("function"==typeof t?ut:ot)(t)):this.node().textContent},nh=function(t){return arguments.length?this.each(null==t?at:("function"==typeof t?st:ct)(t)):this.node().innerHTML},eh=function(){return this.each(ft)},rh=function(){return this.each(lt)},ih=function(t){var n="function"==typeof t?t:_l(t);return this.select(function(){return this.appendChild(n.apply(this,arguments))})},oh=function(t,n){var e="function"==typeof t?t:_l(t),r=null==n?ht:"function"==typeof n?n:El(n);return this.select(function(){return this.insertBefore(e.apply(this,arguments),r.apply(this,arguments)||null)})},uh=function(){return this.each(pt)},ah=function(t){return arguments.length?this.property("__data__",t):this.node().__data__},ch=function(t,n){return this.each(("function"==typeof n?gt:vt)(t,n))},sh=[null];yt.prototype=_t.prototype={constructor:yt,select:Cl,selectAll:Pl,filter:Rl,data:Ol,enter:Dl,exit:Fl,merge:Yl,order:Il,sort:Hl,call:Bl,nodes:jl,node:Xl,size:Wl,empty:Vl,each:$l,attr:Zl,style:Ql,property:Jl,classed:Kl,text:th,html:nh,raise:eh,lower:rh,append:ih,insert:oh,remove:uh,datum:ah,on:Nl,dispatch:ch};var fh=function(t){return"string"==typeof t?new yt([[document.querySelector(t)]],[document.documentElement]):new yt([[t]],sh)},lh=function(t){return"string"==typeof t?new yt([document.querySelectorAll(t)],[document.documentElement]):new yt([null==t?[]:t],sh)},hh=function(t,n,e){arguments.length<3&&(e=n,n=kl().changedTouches);for(var r,i=0,o=n?n.length:0;i<o;++i)if((r=n[i]).identifier===e)return Sl(t,r);return null},ph=function(t,n){null==n&&(n=kl().touches);for(var e=0,r=n?n.length:0,i=new Array(r);e<r;++e)i[e]=Sl(t,n[e]);return i},dh=function(){t.event.preventDefault(),t.event.stopImmediatePropagation()},vh=function(t){var n=t.document.documentElement,e=fh(t).on("dragstart.drag",dh,!0);"onselectstart"in n?e.on("selectstart.drag",dh,!0):(n.__noselect=n.style.MozUserSelect,n.style.MozUserSelect="none")},gh=function(t){return function(){return t}};bt.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};var yh=function(){function n(t){t.on("mousedown.drag",e).filter(y).on("touchstart.drag",o).on("touchmove.drag",u).on("touchend.drag touchcancel.drag",a).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function e(){if(!h&&p.apply(this,arguments)){var n=c("mouse",d.apply(this,arguments),Al,this,arguments);n&&(fh(t.event.view).on("mousemove.drag",r,!0).on("mouseup.drag",i,!0),vh(t.event.view),mt(),l=!1,s=t.event.clientX,f=t.event.clientY,n("start"))}}function r(){if(dh(),!l){var n=t.event.clientX-s,e=t.event.clientY-f;l=n*n+e*e>b}_.mouse("drag")}function i(){fh(t.event.view).on("mousemove.drag mouseup.drag",null),xt(t.event.view,l),dh(),_.mouse("end")}function o(){if(p.apply(this,arguments)){var n,e,r=t.event.changedTouches,i=d.apply(this,arguments),o=r.length;for(n=0;n<o;++n)(e=c(r[n].identifier,i,hh,this,arguments))&&(mt(),e("start"))}}function u(){var n,e,r=t.event.changedTouches,i=r.length;for(n=0;n<i;++n)(e=_[r[n].identifier])&&(dh(),e("drag"))}function a(){var n,e,r=t.event.changedTouches,i=r.length;for(h&&clearTimeout(h),h=setTimeout(function(){h=null},500),n=0;n<i;++n)(e=_[r[n].identifier])&&(mt(),e("end"))}function c(e,r,i,o,u){var a,c,s,f=i(r,e),l=m.copy();if(C(new bt(n,"beforestart",a,e,x,f[0],f[1],0,0,l),function(){return null!=(t.event.subject=a=v.apply(o,u))&&(c=a.x-f[0]||0,s=a.y-f[1]||0,!0)}))return function t(h){var p,d=f;switch(h){case"start":_[e]=t,p=x++;break;case"end":delete _[e],--x;case"drag":f=i(r,e),p=x}C(new bt(n,h,a,e,p,f[0]+c,f[1]+s,f[0]-d[0],f[1]-d[1],l),l.apply,l,[h,o,u])}}var s,f,l,h,p=wt,d=Mt,v=Tt,y=Nt,_={},m=g("start","drag","end"),x=0,b=0;return n.filter=function(t){return arguments.length?(p="function"==typeof t?t:gh(!!t),n):p},n.container=function(t){return arguments.length?(d="function"==typeof t?t:gh(t),n):d},n.subject=function(t){return arguments.length?(v="function"==typeof t?t:gh(t),n):v},n.touchable=function(t){return arguments.length?(y="function"==typeof t?t:gh(!!t),n):y},n.on=function(){var t=m.on.apply(m,arguments);return t===m?n:t},n.clickDistance=function(t){return arguments.length?(b=(t=+t)*t,n):Math.sqrt(b)},n},_h=function(t,n,e){t.prototype=n.prototype=e,e.constructor=t},mh="\\s*([+-]?\\d+)\\s*",xh="\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*",bh="\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*",wh=/^#([0-9a-f]{3})$/,Mh=/^#([0-9a-f]{6})$/,Th=new RegExp("^rgb\\("+[mh,mh,mh]+"\\)$"),Nh=new RegExp("^rgb\\("+[bh,bh,bh]+"\\)$"),kh=new RegExp("^rgba\\("+[mh,mh,mh,xh]+"\\)$"),Sh=new RegExp("^rgba\\("+[bh,bh,bh,xh]+"\\)$"),Ah=new RegExp("^hsl\\("+[xh,bh,bh]+"\\)$"),Eh=new RegExp("^hsla\\("+[xh,bh,bh,xh]+"\\)$"),Ch={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};_h(St,At,{displayable:function(){return this.rgb().displayable()},toString:function(){return this.rgb()+""}}),_h(Rt,Pt,kt(St,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new Rt(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new Rt(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return 0<=this.r&&this.r<=255&&0<=this.g&&this.g<=255&&0<=this.b&&this.b<=255&&0<=this.opacity&&this.opacity<=1},toString:function(){var t=this.opacity;return t=isNaN(t)?1:Math.max(0,Math.min(1,t)),(1===t?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}})),_h(Ut,qt,kt(St,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new Ut(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new Ut(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),n=isNaN(t)||isNaN(this.s)?0:this.s,e=this.l,r=e+(e<.5?e:1-e)*n,i=2*e-r;return new Rt(Ot(t>=240?t-240:t+120,i,r),Ot(t,i,r),Ot(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1}}));var zh=Math.PI/180,Ph=180/Math.PI,Rh=.95047,Lh=1,Dh=1.08883,qh=4/29,Uh=6/29,Oh=3*Uh*Uh,Fh=Uh*Uh*Uh;_h(It,Yt,kt(St,{brighter:function(t){return new It(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker:function(t){return new It(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb:function(){var t=(this.l+16)/116,n=isNaN(this.a)?t:t+this.a/500,e=isNaN(this.b)?t:t-this.b/200;return t=Lh*Bt(t),n=Rh*Bt(n),e=Dh*Bt(e),new Rt(jt(3.2404542*n-1.5371385*t-.4985314*e),jt(-.969266*n+1.8760108*t+.041556*e),jt(.0556434*n-.2040259*t+1.0572252*e),this.opacity)}})),_h($t,Vt,kt(St,{brighter:function(t){return new $t(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker:function(t){return new $t(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb:function(){return Ft(this).rgb()}}));var Yh=-.14861,Ih=1.78277,Hh=-.29227,Bh=-.90649,jh=1.97294,Xh=jh*Bh,Wh=jh*Ih,Vh=Ih*Hh-Bh*Yh;_h(Qt,Gt,kt(St,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new Qt(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new Qt(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=isNaN(this.h)?0:(this.h+120)*zh,n=+this.l,e=isNaN(this.s)?0:this.s*n*(1-n),r=Math.cos(t),i=Math.sin(t);return new Rt(255*(n+e*(Yh*r+Ih*i)),255*(n+e*(Hh*r+Bh*i)),255*(n+e*(jh*r)),this.opacity)}}));var $h,Zh,Gh,Qh,Jh,Kh,tp=function(t){var n=t.length-1;return function(e){var r=e<=0?e=0:e>=1?(e=1,n-1):Math.floor(e*n),i=t[r],o=t[r+1],u=r>0?t[r-1]:2*i-o,a=r<n-1?t[r+2]:2*o-i;return Jt((e-r/n)*n,u,i,o,a)}},np=function(t){var n=t.length;return function(e){var r=Math.floor(((e%=1)<0?++e:e)*n),i=t[(r+n-1)%n],o=t[r%n],u=t[(r+1)%n],a=t[(r+2)%n];return Jt((e-r/n)*n,i,o,u,a)}},ep=function(t){return function(){return t}},rp=function t(n){function e(t,n){var e=r((t=Pt(t)).r,(n=Pt(n)).r),i=r(t.g,n.g),o=r(t.b,n.b),u=rn(t.opacity,n.opacity);return function(n){return t.r=e(n),t.g=i(n),t.b=o(n),t.opacity=u(n),t+""}}var r=en(n);return e.gamma=t,e}(1),ip=on(tp),op=on(np),up=function(t,n){var e,r=n?n.length:0,i=t?Math.min(r,t.length):0,o=new Array(i),u=new Array(r);for(e=0;e<i;++e)o[e]=pp(t[e],n[e]);for(;e<r;++e)u[e]=n[e];return function(t){for(e=0;e<i;++e)u[e]=o[e](t);return u}},ap=function(t,n){var e=new Date;return t=+t,n-=t,function(r){return e.setTime(t+n*r),e}},cp=function(t,n){return t=+t,n-=t,function(e){return t+n*e}},sp=function(t,n){var e,r={},i={};null!==t&&"object"==typeof t||(t={}),null!==n&&"object"==typeof n||(n={});for(e in n)e in t?r[e]=pp(t[e],n[e]):i[e]=n[e];return function(t){for(e in r)i[e]=r[e](t);return i}},fp=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,lp=new RegExp(fp.source,"g"),hp=function(t,n){var e,r,i,o=fp.lastIndex=lp.lastIndex=0,u=-1,a=[],c=[];for(t+="",n+="";(e=fp.exec(t))&&(r=lp.exec(n));)(i=r.index)>o&&(i=n.slice(o,i),a[u]?a[u]+=i:a[++u]=i),(e=e[0])===(r=r[0])?a[u]?a[u]+=r:a[++u]=r:(a[++u]=null,c.push({i:u,x:cp(e,r)})),o=lp.lastIndex;return o<n.length&&(i=n.slice(o),a[u]?a[u]+=i:a[++u]=i),a.length<2?c[0]?an(c[0].x):un(n):(n=c.length,function(t){for(var e,r=0;r<n;++r)a[(e=c[r]).i]=e.x(t);return a.join("")})},pp=function(t,n){var e,r=typeof n;return null==n||"boolean"===r?ep(n):("number"===r?cp:"string"===r?(e=At(n))?(n=e,rp):hp:n instanceof At?rp:n instanceof Date?ap:Array.isArray(n)?up:"function"!=typeof n.valueOf&&"function"!=typeof n.toString||isNaN(n)?sp:cp)(t,n)},dp=function(t,n){return t=+t,n-=t,function(e){return Math.round(t+n*e)}},vp=180/Math.PI,gp={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1},yp=function(t,n,e,r,i,o){var u,a,c;return(u=Math.sqrt(t*t+n*n))&&(t/=u,n/=u),(c=t*e+n*r)&&(e-=t*c,r-=n*c),(a=Math.sqrt(e*e+r*r))&&(e/=a,r/=a,c/=a),t*r<n*e&&(t=-t,n=-n,c=-c,u=-u),{translateX:i,translateY:o,rotate:Math.atan2(n,t)*vp,skewX:Math.atan(c)*vp,scaleX:u,scaleY:a}},_p=fn(cn,"px, ","px)","deg)"),mp=fn(sn,", ",")",")"),xp=Math.SQRT2,bp=function(t,n){var e,r,i=t[0],o=t[1],u=t[2],a=n[0],c=n[1],s=n[2],f=a-i,l=c-o,h=f*f+l*l;if(h<1e-12)r=Math.log(s/u)/xp,e=function(t){return[i+t*f,o+t*l,u*Math.exp(xp*t*r)]};else{var p=Math.sqrt(h),d=(s*s-u*u+4*h)/(2*u*2*p),v=(s*s-u*u-4*h)/(2*s*2*p),g=Math.log(Math.sqrt(d*d+1)-d),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-g)/xp,e=function(t){var n=t*r,e=ln(g),a=u/(2*p)*(e*pn(xp*n+g)-hn(g));return[i+a*f,o+a*l,u*e/ln(xp*n+g)]}}return e.duration=1e3*r,e},wp=dn(nn),Mp=dn(rn),Tp=gn(nn),Np=gn(rn),kp=yn(nn),Sp=yn(rn),Ap=function(t,n){for(var e=new Array(n),r=0;r<n;++r)e[r]=t(r/(n-1));return e},Ep=0,Cp=0,zp=0,Pp=1e3,Rp=0,Lp=0,Dp=0,qp="object"==typeof performance&&performance.now?performance:Date,Up="object"==typeof window&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};xn.prototype=bn.prototype={constructor:xn,restart:function(t,n,e){if("function"!=typeof t)throw new TypeError("callback is not a function");e=(null==e?_n():+e)+(null==n?0:+n),this._next||Kh===this||(Kh?Kh._next=this:Jh=this,Kh=this),this._call=t,this._time=e,kn()},stop:function(){this._call&&(this._call=null,this._time=1/0,kn())}};var Op=function(t,n,e){var r=new xn;return n=null==n?0:+n,r.restart(function(e){r.stop(),t(e+n)},n,e),r},Fp=function(t,n,e){var r=new xn,i=n;return null==n?(r.restart(t,n,e),r):(n=+n,e=null==e?_n():+e,r.restart(function o(u){u+=i,r.restart(o,i+=n,e),t(u)},n,e),r)},Yp=g("start","end","interrupt"),Ip=[],Hp=0,Bp=1,jp=2,Xp=3,Wp=4,Vp=5,$p=6,Zp=function(t,n,e,r,i,o){var u=t.__transition;if(u){if(e in u)return}else t.__transition={};Cn(t,e,{name:n,index:r,group:i,on:Yp,tween:Ip,time:o.time,delay:o.delay,duration:o.duration,ease:o.ease,timer:null,state:Hp})},Gp=function(t,n){var e,r,i,o=t.__transition,u=!0;if(o){n=null==n?null:n+"";for(i in o)(e=o[i]).name===n?(r=e.state>jp&&e.state<Vp,e.state=$p,e.timer.stop(),r&&e.on.call("interrupt",t,t.__data__,e.index,e.group),delete o[i]):u=!1;u&&delete t.__transition}},Qp=function(t){return this.each(function(){Gp(this,t)})},Jp=function(t,n){var e=this._id;if(t+="",arguments.length<2){for(var r,i=En(this.node(),e).tween,o=0,u=i.length;o<u;++o)if((r=i[o]).name===t)return r.value;return null}return this.each((null==n?zn:Pn)(e,t,n))},Kp=function(t,n){var e;return("number"==typeof n?cp:n instanceof At?rp:(e=At(n))?(n=e,rp):hp)(t,n)},td=function(t,n){var e=yl(t),r="transform"===e?mp:Kp;return this.attrTween(t,"function"==typeof n?(e.local?Fn:On)(e,r,Rn(this,"attr."+t,n)):null==n?(e.local?Dn:Ln)(e):(e.local?Un:qn)(e,r,n+""))},nd=function(t,n){var e="attr."+t;if(arguments.length<2)return(e=this.tween(e))&&e._value;if(null==n)return this.tween(e,null);if("function"!=typeof n)throw new Error;var r=yl(t);return this.tween(e,(r.local?Yn:In)(r,n))},ed=function(t){var n=this._id;return arguments.length?this.each(("function"==typeof t?Hn:Bn)(n,t)):En(this.node(),n).delay},rd=function(t){var n=this._id;return arguments.length?this.each(("function"==typeof t?jn:Xn)(n,t)):En(this.node(),n).duration},id=function(t){var n=this._id;return arguments.length?this.each(Wn(n,t)):En(this.node(),n).ease},od=function(t){"function"!=typeof t&&(t=Ml(t));for(var n=this._groups,e=n.length,r=new Array(e),i=0;i<e;++i)for(var o,u=n[i],a=u.length,c=r[i]=[],s=0;s<a;++s)(o=u[s])&&t.call(o,o.__data__,s,u)&&c.push(o);return new re(r,this._parents,this._name,this._id)},ud=function(t){if(t._id!==this._id)throw new Error;for(var n=this._groups,e=t._groups,r=n.length,i=e.length,o=Math.min(r,i),u=new Array(r),a=0;a<o;++a)for(var c,s=n[a],f=e[a],l=s.length,h=u[a]=new Array(l),p=0;p<l;++p)(c=s[p]||f[p])&&(h[p]=c);for(;a<r;++a)u[a]=n[a];return new re(u,this._parents,this._name,this._id)},ad=function(t,n){var e=this._id;return arguments.length<2?En(this.node(),e).on.on(t):this.each($n(e,t,n))},cd=function(){return this.on("end.remove",Zn(this._id))},sd=function(t){var n=this._name,e=this._id;"function"!=typeof t&&(t=El(t));for(var r=this._groups,i=r.length,o=new Array(i),u=0;u<i;++u)for(var a,c,s=r[u],f=s.length,l=o[u]=new Array(f),h=0;h<f;++h)(a=s[h])&&(c=t.call(a,a.__data__,h,s))&&("__data__"in a&&(c.__data__=a.__data__),l[h]=c,Zp(l[h],n,e,h,l,En(a,e)));return new re(o,this._parents,n,e)},fd=function(t){var n=this._name,e=this._id;"function"!=typeof t&&(t=zl(t));for(var r=this._groups,i=r.length,o=[],u=[],a=0;a<i;++a)for(var c,s=r[a],f=s.length,l=0;l<f;++l)if(c=s[l]){for(var h,p=t.call(c,c.__data__,l,s),d=En(c,e),v=0,g=p.length;v<g;++v)(h=p[v])&&Zp(h,n,e,v,p,d);o.push(p),u.push(c)}return new re(o,u,n,e)},ld=_t.prototype.constructor,hd=function(){return new ld(this._groups,this._parents)},pd=function(t,n,e){var r="transform"==(t+="")?_p:Kp;return null==n?this.styleTween(t,Gn(t,r)).on("end.style."+t,Qn(t)):this.styleTween(t,"function"==typeof n?Kn(t,r,Rn(this,"style."+t,n)):Jn(t,r,n+""),e)},dd=function(t,n,e){var r="style."+(t+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==n)return this.tween(r,null);if("function"!=typeof n)throw new Error;return this.tween(r,te(t,n,null==e?"":e))},vd=function(t){return this.tween("text","function"==typeof t?ee(Rn(this,"text",t)):ne(null==t?"":t+""))},gd=function(){for(var t=this._name,n=this._id,e=oe(),r=this._groups,i=r.length,o=0;o<i;++o)for(var u,a=r[o],c=a.length,s=0;s<c;++s)if(u=a[s]){var f=En(u,n);Zp(u,t,e,s,a,{time:f.time+f.delay+f.duration,delay:0,duration:f.duration,ease:f.ease})}return new re(r,this._parents,t,e)},yd=0,_d=_t.prototype;re.prototype=ie.prototype={constructor:re,select:sd,selectAll:fd,filter:od,merge:ud,selection:hd,transition:gd,call:_d.call,nodes:_d.nodes,node:_d.node,size:_d.size,empty:_d.empty,each:_d.each,on:ad,attr:td,attrTween:nd,style:pd,styleTween:dd,text:vd,remove:cd,tween:Jp,delay:ed,duration:rd,ease:id};var md=function t(n){function e(t){return Math.pow(t,n)}return n=+n,e.exponent=t,e}(3),xd=function t(n){function e(t){return 1-Math.pow(1-t,n)}return n=+n,e.exponent=t,e}(3),bd=function t(n){function e(t){return((t*=2)<=1?Math.pow(t,n):2-Math.pow(2-t,n))/2}return n=+n,e.exponent=t,e}(3),wd=Math.PI,Md=wd/2,Td=4/11,Nd=6/11,kd=8/11,Sd=.75,Ad=9/11,Ed=10/11,Cd=.9375,zd=21/22,Pd=63/64,Rd=1/Td/Td,Ld=function t(n){function e(t){return t*t*((n+1)*t-n)}return n=+n,e.overshoot=t,e}(1.70158),Dd=function t(n){function e(t){return--t*t*((n+1)*t+n)+1}return n=+n,e.overshoot=t,e}(1.70158),qd=function t(n){function e(t){return((t*=2)<1?t*t*((n+1)*t-n):(t-=2)*t*((n+1)*t+n)+2)/2}return n=+n,e.overshoot=t,e}(1.70158),Ud=2*Math.PI,Od=function t(n,e){function r(t){return n*Math.pow(2,10*--t)*Math.sin((i-t)/e)}var i=Math.asin(1/(n=Math.max(1,n)))*(e/=Ud);return r.amplitude=function(n){return t(n,e*Ud)},r.period=function(e){return t(n,e)},r}(1,.3),Fd=function t(n,e){function r(t){return 1-n*Math.pow(2,-10*(t=+t))*Math.sin((t+i)/e)}var i=Math.asin(1/(n=Math.max(1,n)))*(e/=Ud);return r.amplitude=function(n){return t(n,e*Ud)},r.period=function(e){return t(n,e)},r}(1,.3),Yd=function t(n,e){function r(t){return((t=2*t-1)<0?n*Math.pow(2,10*t)*Math.sin((i-t)/e):2-n*Math.pow(2,-10*t)*Math.sin((i+t)/e))/2}var i=Math.asin(1/(n=Math.max(1,n)))*(e/=Ud);return r.amplitude=function(n){return t(n,e*Ud)},r.period=function(e){return t(n,e)},r}(1,.3),Id={time:null,delay:0,duration:250,ease:he},Hd=function(t){var n,e;t instanceof re?(n=t._id,t=t._name):(n=oe(),(e=Id).time=_n(),t=null==t?null:t+"");for(var r=this._groups,i=r.length,o=0;o<i;++o)for(var u,a=r[o],c=a.length,s=0;s<c;++s)(u=a[s])&&Zp(u,t,n,s,a,e||Ne(u,n));return new re(r,this._parents,t,n)};_t.prototype.interrupt=Qp,_t.prototype.transition=Hd;var Bd=[null],jd=function(t,n){var e,r,i=t.__transition;if(i){n=null==n?null:n+"";for(r in i)if((e=i[r]).state>Bp&&e.name===n)return new re([[t]],Bd,n,+r)}return null},Xd=function(t){return function(){return t}},Wd=function(t,n,e){this.target=t,this.type=n,this.selection=e},Vd=function(){t.event.preventDefault(),t.event.stopImmediatePropagation()},$d={name:"drag"},Zd={name:"space"},Gd={name:"handle"},Qd={name:"center"},Jd={name:"x",handles:["e","w"].map(Se),input:function(t,n){return t&&[[t[0],n[0][1]],[t[1],n[1][1]]]},output:function(t){return t&&[t[0][0],t[1][0]]}},Kd={name:"y",handles:["n","s"].map(Se),input:function(t,n){return t&&[[n[0][0],t[0]],[n[1][0],t[1]]]},output:function(t){return t&&[t[0][1],t[1][1]]}},tv={name:"xy",handles:["n","e","s","w","nw","ne","se","sw"].map(Se),input:function(t){return t},output:function(t){return t}},nv={overlay:"crosshair",selection:"move",n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},ev={e:"w",w:"e",nw:"ne",ne:"nw",se:"sw",sw:"se"},rv={n:"s",s:"n",nw:"sw",ne:"se",se:"ne",sw:"nw"},iv={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},ov={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1},uv=function(){return De(tv)},av=Math.cos,cv=Math.sin,sv=Math.PI,fv=sv/2,lv=2*sv,hv=Math.max,pv=function(){function t(t){var o,u,a,c,s,f,l=t.length,h=[],p=Yf(l),d=[],v=[],g=v.groups=new Array(l),y=new Array(l*l);for(o=0,s=-1;++s<l;){for(u=0,f=-1;++f<l;)u+=t[s][f];h.push(u),d.push(Yf(l)),o+=u}for(e&&p.sort(function(t,n){return e(h[t],h[n])}),r&&d.forEach(function(n,e){n.sort(function(n,i){return r(t[e][n],t[e][i])})}),o=hv(0,lv-n*l)/o,c=o?n:lv/l,u=0,s=-1;++s<l;){for(a=u,f=-1;++f<l;){var _=p[s],m=d[_][f],x=t[_][m],b=u,w=u+=x*o;y[m*l+_]={index:_,subindex:m,startAngle:b,endAngle:w,value:x}}g[_]={index:_,startAngle:a,endAngle:u,value:h[_]},u+=c}for(s=-1;++s<l;)for(f=s-1;++f<l;){var M=y[f*l+s],T=y[s*l+f];(M.value||T.value)&&v.push(M.value<T.value?{source:T,target:M}:{source:M,target:T})}return i?v.sort(i):v}var n=0,e=null,r=null,i=null;return t.padAngle=function(e){return arguments.length?(n=hv(0,e),t):n},t.sortGroups=function(n){return arguments.length?(e=n,t):e},t.sortSubgroups=function(n){return arguments.length?(r=n,t):r},t.sortChords=function(n){return arguments.length?(null==n?i=null:(i=qe(n))._=n,t):i&&i._},t},dv=Array.prototype.slice,vv=function(t){return function(){return t}},gv=Math.PI,yv=2*gv,_v=yv-1e-6;Ue.prototype=Oe.prototype={constructor:Ue,moveTo:function(t,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,n){this._+="L"+(this._x1=+t)+","+(this._y1=+n)},quadraticCurveTo:function(t,n,e,r){this._+="Q"+ +t+","+ +n+","+(this._x1=+e)+","+(this._y1=+r)},bezierCurveTo:function(t,n,e,r,i,o){this._+="C"+ +t+","+ +n+","+ +e+","+ +r+","+(this._x1=+i)+","+(this._y1=+o)},arcTo:function(t,n,e,r,i){t=+t,n=+n,e=+e,r=+r,i=+i;var o=this._x1,u=this._y1,a=e-t,c=r-n,s=o-t,f=u-n,l=s*s+f*f;if(i<0)throw new Error("negative radius: "+i);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=n);else if(l>1e-6)if(Math.abs(f*a-c*s)>1e-6&&i){var h=e-o,p=r-u,d=a*a+c*c,v=h*h+p*p,g=Math.sqrt(d),y=Math.sqrt(l),_=i*Math.tan((gv-Math.acos((d+l-v)/(2*g*y)))/2),m=_/y,x=_/g;Math.abs(m-1)>1e-6&&(this._+="L"+(t+m*s)+","+(n+m*f)),this._+="A"+i+","+i+",0,0,"+ +(f*h>s*p)+","+(this._x1=t+x*a)+","+(this._y1=n+x*c)}else this._+="L"+(this._x1=t)+","+(this._y1=n);else;},arc:function(t,n,e,r,i,o){t=+t,n=+n,e=+e;var u=e*Math.cos(r),a=e*Math.sin(r),c=t+u,s=n+a,f=1^o,l=o?r-i:i-r;if(e<0)throw new Error("negative radius: "+e);null===this._x1?this._+="M"+c+","+s:(Math.abs(this._x1-c)>1e-6||Math.abs(this._y1-s)>1e-6)&&(this._+="L"+c+","+s),e&&(l<0&&(l=l%yv+yv),l>_v?this._+="A"+e+","+e+",0,1,"+f+","+(t-u)+","+(n-a)+"A"+e+","+e+",0,1,"+f+","+(this._x1=c)+","+(this._y1=s):l>1e-6&&(this._+="A"+e+","+e+",0,"+ +(l>=gv)+","+f+","+(this._x1=t+e*Math.cos(i))+","+(this._y1=n+e*Math.sin(i))))},rect:function(t,n,e,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)+"h"+ +e+"v"+ +r+"h"+-e+"Z"},toString:function(){return this._}};var mv=function(){function t(){var t,a=dv.call(arguments),c=n.apply(this,a),s=e.apply(this,a),f=+r.apply(this,(a[0]=c,a)),l=i.apply(this,a)-fv,h=o.apply(this,a)-fv,p=f*av(l),d=f*cv(l),v=+r.apply(this,(a[0]=s,a)),g=i.apply(this,a)-fv,y=o.apply(this,a)-fv;if(u||(u=t=Oe()),u.moveTo(p,d),u.arc(0,0,f,l,h),l===g&&h===y||(u.quadraticCurveTo(0,0,v*av(g),v*cv(g)),u.arc(0,0,v,g,y)),u.quadraticCurveTo(0,0,p,d),u.closePath(),t)return u=null,t+""||null}var n=Fe,e=Ye,r=Ie,i=He,o=Be,u=null;return t.radius=function(n){return arguments.length?(r="function"==typeof n?n:vv(+n),t):r},t.startAngle=function(n){return arguments.length?(i="function"==typeof n?n:vv(+n),t):i},t.endAngle=function(n){return arguments.length?(o="function"==typeof n?n:vv(+n),t):o},t.source=function(e){return arguments.length?(n=e,t):n},t.target=function(n){return arguments.length?(e=n,t):e},t.context=function(n){return arguments.length?(u=null==n?null:n,t):u},t};je.prototype=Xe.prototype={constructor:je,has:function(t){return"$"+t in this},get:function(t){return this["$"+t]},set:function(t,n){return this["$"+t]=n,this},remove:function(t){var n="$"+t;return n in this&&delete this[n]},clear:function(){for(var t in this)"$"===t[0]&&delete this[t]},keys:function(){var t=[];for(var n in this)"$"===n[0]&&t.push(n.slice(1));return t},values:function(){var t=[];for(var n in this)"$"===n[0]&&t.push(this[n]);return t},entries:function(){var t=[];for(var n in this)"$"===n[0]&&t.push({key:n.slice(1),value:this[n]});return t},size:function(){var t=0;for(var n in this)"$"===n[0]&&++t;return t},empty:function(){for(var t in this)if("$"===t[0])return!1;return!0},each:function(t){for(var n in this)"$"===n[0]&&t(this[n],n.slice(1),this)}};var xv=function(){function t(n,i,u,a){if(i>=o.length)return null!=e&&n.sort(e),null!=r?r(n):n;for(var c,s,f,l=-1,h=n.length,p=o[i++],d=Xe(),v=u();++l<h;)(f=d.get(c=p(s=n[l])+""))?f.push(s):d.set(c,[s]);return d.each(function(n,e){a(v,e,t(n,i,u,a))}),v}function n(t,e){if(++e>o.length)return t;var i,a=u[e-1];return null!=r&&e>=o.length?i=t.entries():(i=[],t.each(function(t,r){i.push({key:r,values:n(t,e)})})),null!=a?i.sort(function(t,n){return a(t.key,n.key)}):i}var e,r,i,o=[],u=[];return i={object:function(n){return t(n,0,We,Ve)},map:function(n){return t(n,0,$e,Ze)},entries:function(e){return n(t(e,0,$e,Ze),0)},key:function(t){return o.push(t),i},sortKeys:function(t){return u[o.length-1]=t,i},sortValues:function(t){return e=t,i},rollup:function(t){return r=t,i}}},bv=Xe.prototype;Ge.prototype=Qe.prototype={constructor:Ge,has:bv.has,add:function(t){return t+="",this["$"+t]=t,this},remove:bv.remove,clear:bv.clear,values:bv.keys,size:bv.size,empty:bv.empty,each:bv.each};var wv=function(t){var n=[];for(var e in t)n.push(e);return n},Mv=function(t){var n=[];for(var e in t)n.push(t[e]);return n},Tv=function(t){var n=[];for(var e in t)n.push({key:e,value:t[e]});return n},Nv={},kv={},Sv=34,Av=10,Ev=13,Cv=function(t){function n(t,n){var r,i,o=e(t,function(t,e){if(r)return r(t,e-1);i=t,r=n?Ke(t,n):Je(t)});return o.columns=i||[],o}function e(t,n){function e(){if(s)return kv;if(f)return f=!1,Nv;var n,e,r=u;if(t.charCodeAt(r)===Sv){for(;u++<o&&t.charCodeAt(u)!==Sv||t.charCodeAt(++u)===Sv;);return(n=u)>=o?s=!0:(e=t.charCodeAt(u++))===Av?f=!0:e===Ev&&(f=!0,t.charCodeAt(u)===Av&&++u),t.slice(r+1,n-1).replace(/""/g,'"')}for(;u<o;){if((e=t.charCodeAt(n=u++))===Av)f=!0;else if(e===Ev)f=!0,t.charCodeAt(u)===Av&&++u;else if(e!==c)continue;return t.slice(r,n)}return s=!0,t.slice(r,o)}var r,i=[],o=t.length,u=0,a=0,s=o<=0,f=!1;for(t.charCodeAt(o-1)===Av&&--o,t.charCodeAt(o-1)===Ev&&--o;(r=e())!==kv;){for(var l=[];r!==Nv&&r!==kv;)l.push(r),r=e();n&&null==(l=n(l,a++))||i.push(l)}return i}function r(n,e){return null==e&&(e=tr(n)), | |
[e.map(u).join(t)].concat(n.map(function(n){return e.map(function(t){return u(n[t])}).join(t)})).join("\n")}function i(t){return t.map(o).join("\n")}function o(n){return n.map(u).join(t)}function u(t){return null==t?"":a.test(t+="")?'"'+t.replace(/"/g,'""')+'"':t}var a=new RegExp('["'+t+"\n\r]"),c=t.charCodeAt(0);return{parse:n,parseRows:e,format:r,formatRows:i}},zv=Cv(","),Pv=zv.parse,Rv=zv.parseRows,Lv=zv.format,Dv=zv.formatRows,qv=Cv("\t"),Uv=qv.parse,Ov=qv.parseRows,Fv=qv.format,Yv=qv.formatRows,Iv=function(t,n){function e(){var e,i,o=r.length,u=0,a=0;for(e=0;e<o;++e)i=r[e],u+=i.x,a+=i.y;for(u=u/o-t,a=a/o-n,e=0;e<o;++e)i=r[e],i.x-=u,i.y-=a}var r;return null==t&&(t=0),null==n&&(n=0),e.initialize=function(t){r=t},e.x=function(n){return arguments.length?(t=+n,e):t},e.y=function(t){return arguments.length?(n=+t,e):n},e},Hv=function(t){return function(){return t}},Bv=function(){return 1e-6*(Math.random()-.5)},jv=function(t){var n=+this._x.call(null,t),e=+this._y.call(null,t);return nr(this.cover(n,e),n,e,t)},Xv=function(t,n){if(isNaN(t=+t)||isNaN(n=+n))return this;var e=this._x0,r=this._y0,i=this._x1,o=this._y1;if(isNaN(e))i=(e=Math.floor(t))+1,o=(r=Math.floor(n))+1;else{if(!(e>t||t>i||r>n||n>o))return this;var u,a,c=i-e,s=this._root;switch(a=(n<(r+o)/2)<<1|t<(e+i)/2){case 0:do{u=new Array(4),u[a]=s,s=u}while(c*=2,i=e+c,o=r+c,t>i||n>o);break;case 1:do{u=new Array(4),u[a]=s,s=u}while(c*=2,e=i-c,o=r+c,e>t||n>o);break;case 2:do{u=new Array(4),u[a]=s,s=u}while(c*=2,i=e+c,r=o-c,t>i||r>n);break;case 3:do{u=new Array(4),u[a]=s,s=u}while(c*=2,e=i-c,r=o-c,e>t||r>n)}this._root&&this._root.length&&(this._root=s)}return this._x0=e,this._y0=r,this._x1=i,this._y1=o,this},Wv=function(){var t=[];return this.visit(function(n){if(!n.length)do{t.push(n.data)}while(n=n.next)}),t},Vv=function(t){return arguments.length?this.cover(+t[0][0],+t[0][1]).cover(+t[1][0],+t[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},$v=function(t,n,e,r,i){this.node=t,this.x0=n,this.y0=e,this.x1=r,this.y1=i},Zv=function(t,n,e){var r,i,o,u,a,c,s,f=this._x0,l=this._y0,h=this._x1,p=this._y1,d=[],v=this._root;for(v&&d.push(new $v(v,f,l,h,p)),null==e?e=1/0:(f=t-e,l=n-e,h=t+e,p=n+e,e*=e);c=d.pop();)if(!(!(v=c.node)||(i=c.x0)>h||(o=c.y0)>p||(u=c.x1)<f||(a=c.y1)<l))if(v.length){var g=(i+u)/2,y=(o+a)/2;d.push(new $v(v[3],g,y,u,a),new $v(v[2],i,y,g,a),new $v(v[1],g,o,u,y),new $v(v[0],i,o,g,y)),(s=(n>=y)<<1|t>=g)&&(c=d[d.length-1],d[d.length-1]=d[d.length-1-s],d[d.length-1-s]=c)}else{var _=t-+this._x.call(null,v.data),m=n-+this._y.call(null,v.data),x=_*_+m*m;if(x<e){var b=Math.sqrt(e=x);f=t-b,l=n-b,h=t+b,p=n+b,r=v.data}}return r},Gv=function(t){if(isNaN(o=+this._x.call(null,t))||isNaN(u=+this._y.call(null,t)))return this;var n,e,r,i,o,u,a,c,s,f,l,h,p=this._root,d=this._x0,v=this._y0,g=this._x1,y=this._y1;if(!p)return this;if(p.length)for(;;){if((s=o>=(a=(d+g)/2))?d=a:g=a,(f=u>=(c=(v+y)/2))?v=c:y=c,n=p,!(p=p[l=f<<1|s]))return this;if(!p.length)break;(n[l+1&3]||n[l+2&3]||n[l+3&3])&&(e=n,h=l)}for(;p.data!==t;)if(r=p,!(p=p.next))return this;return(i=p.next)&&delete p.next,r?(i?r.next=i:delete r.next,this):n?(i?n[l]=i:delete n[l],(p=n[0]||n[1]||n[2]||n[3])&&p===(n[3]||n[2]||n[1]||n[0])&&!p.length&&(e?e[h]=p:this._root=p),this):(this._root=i,this)},Qv=function(){return this._root},Jv=function(){var t=0;return this.visit(function(n){if(!n.length)do{++t}while(n=n.next)}),t},Kv=function(t){var n,e,r,i,o,u,a=[],c=this._root;for(c&&a.push(new $v(c,this._x0,this._y0,this._x1,this._y1));n=a.pop();)if(!t(c=n.node,r=n.x0,i=n.y0,o=n.x1,u=n.y1)&&c.length){var s=(r+o)/2,f=(i+u)/2;(e=c[3])&&a.push(new $v(e,s,f,o,u)),(e=c[2])&&a.push(new $v(e,r,f,s,u)),(e=c[1])&&a.push(new $v(e,s,i,o,f)),(e=c[0])&&a.push(new $v(e,r,i,s,f))}return this},tg=function(t){var n,e=[],r=[];for(this._root&&e.push(new $v(this._root,this._x0,this._y0,this._x1,this._y1));n=e.pop();){var i=n.node;if(i.length){var o,u=n.x0,a=n.y0,c=n.x1,s=n.y1,f=(u+c)/2,l=(a+s)/2;(o=i[0])&&e.push(new $v(o,u,a,f,l)),(o=i[1])&&e.push(new $v(o,f,a,c,l)),(o=i[2])&&e.push(new $v(o,u,l,f,s)),(o=i[3])&&e.push(new $v(o,f,l,c,s))}r.push(n)}for(;n=r.pop();)t(n.node,n.x0,n.y0,n.x1,n.y1);return this},ng=function(t){return arguments.length?(this._x=t,this):this._x},eg=function(t){return arguments.length?(this._y=t,this):this._y},rg=ur.prototype=ar.prototype;rg.copy=function(){var t,n,e=new ar(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return e;if(!r.length)return e._root=cr(r),e;for(t=[{source:r,target:e._root=new Array(4)}];r=t.pop();)for(var i=0;i<4;++i)(n=r.source[i])&&(n.length?t.push({source:n,target:r.target[i]=new Array(4)}):r.target[i]=cr(n));return e},rg.add=jv,rg.addAll=er,rg.cover=Xv,rg.data=Wv,rg.extent=Vv,rg.find=Zv,rg.remove=Gv,rg.removeAll=rr,rg.root=Qv,rg.size=Jv,rg.visit=Kv,rg.visitAfter=tg,rg.x=ng,rg.y=eg;var ig,og=function(t){function n(){function t(t,n,e,r,i){var o=t.data,a=t.r,p=l+a;{if(!o)return n>s+p||r<s-p||e>f+p||i<f-p;if(o.index>c.index){var d=s-o.x-o.vx,v=f-o.y-o.vy,g=d*d+v*v;g<p*p&&(0===d&&(d=Bv(),g+=d*d),0===v&&(v=Bv(),g+=v*v),g=(p-(g=Math.sqrt(g)))/g*u,c.vx+=(d*=g)*(p=(a*=a)/(h+a)),c.vy+=(v*=g)*p,o.vx-=d*(p=1-p),o.vy-=v*p)}}}for(var n,r,c,s,f,l,h,p=i.length,d=0;d<a;++d)for(r=ur(i,sr,fr).visitAfter(e),n=0;n<p;++n)c=i[n],l=o[c.index],h=l*l,s=c.x+c.vx,f=c.y+c.vy,r.visit(t)}function e(t){if(t.data)return t.r=o[t.data.index];for(var n=t.r=0;n<4;++n)t[n]&&t[n].r>t.r&&(t.r=t[n].r)}function r(){if(i){var n,e,r=i.length;for(o=new Array(r),n=0;n<r;++n)e=i[n],o[e.index]=+t(e,n,i)}}var i,o,u=1,a=1;return"function"!=typeof t&&(t=Hv(null==t?1:+t)),n.initialize=function(t){i=t,r()},n.iterations=function(t){return arguments.length?(a=+t,n):a},n.strength=function(t){return arguments.length?(u=+t,n):u},n.radius=function(e){return arguments.length?(t="function"==typeof e?e:Hv(+e),r(),n):t},n},ug=function(t){function n(t){return 1/Math.min(s[t.source.index],s[t.target.index])}function e(n){for(var e=0,r=t.length;e<d;++e)for(var i,o,c,s,l,h,p,v=0;v<r;++v)i=t[v],o=i.source,c=i.target,s=c.x+c.vx-o.x-o.vx||Bv(),l=c.y+c.vy-o.y-o.vy||Bv(),h=Math.sqrt(s*s+l*l),h=(h-a[v])/h*n*u[v],s*=h,l*=h,c.vx-=s*(p=f[v]),c.vy-=l*p,o.vx+=s*(p=1-p),o.vy+=l*p}function r(){if(c){var n,e,r=c.length,h=t.length,p=Xe(c,l);for(n=0,s=new Array(r);n<h;++n)e=t[n],e.index=n,"object"!=typeof e.source&&(e.source=hr(p,e.source)),"object"!=typeof e.target&&(e.target=hr(p,e.target)),s[e.source.index]=(s[e.source.index]||0)+1,s[e.target.index]=(s[e.target.index]||0)+1;for(n=0,f=new Array(h);n<h;++n)e=t[n],f[n]=s[e.source.index]/(s[e.source.index]+s[e.target.index]);u=new Array(h),i(),a=new Array(h),o()}}function i(){if(c)for(var n=0,e=t.length;n<e;++n)u[n]=+h(t[n],n,t)}function o(){if(c)for(var n=0,e=t.length;n<e;++n)a[n]=+p(t[n],n,t)}var u,a,c,s,f,l=lr,h=n,p=Hv(30),d=1;return null==t&&(t=[]),e.initialize=function(t){c=t,r()},e.links=function(n){return arguments.length?(t=n,r(),e):t},e.id=function(t){return arguments.length?(l=t,e):l},e.iterations=function(t){return arguments.length?(d=+t,e):d},e.strength=function(t){return arguments.length?(h="function"==typeof t?t:Hv(+t),i(),e):h},e.distance=function(t){return arguments.length?(p="function"==typeof t?t:Hv(+t),o(),e):p},e},ag=10,cg=Math.PI*(3-Math.sqrt(5)),sg=function(t){function n(){e(),p.call("tick",o),u<a&&(h.stop(),p.call("end",o))}function e(){var n,e,r=t.length;for(u+=(s-u)*c,l.each(function(t){t(u)}),n=0;n<r;++n)e=t[n],null==e.fx?e.x+=e.vx*=f:(e.x=e.fx,e.vx=0),null==e.fy?e.y+=e.vy*=f:(e.y=e.fy,e.vy=0)}function r(){for(var n,e=0,r=t.length;e<r;++e){if(n=t[e],n.index=e,isNaN(n.x)||isNaN(n.y)){var i=ag*Math.sqrt(e),o=e*cg;n.x=i*Math.cos(o),n.y=i*Math.sin(o)}(isNaN(n.vx)||isNaN(n.vy))&&(n.vx=n.vy=0)}}function i(n){return n.initialize&&n.initialize(t),n}var o,u=1,a=.001,c=1-Math.pow(a,1/300),s=0,f=.6,l=Xe(),h=bn(n),p=g("tick","end");return null==t&&(t=[]),r(),o={tick:e,restart:function(){return h.restart(n),o},stop:function(){return h.stop(),o},nodes:function(n){return arguments.length?(t=n,r(),l.each(i),o):t},alpha:function(t){return arguments.length?(u=+t,o):u},alphaMin:function(t){return arguments.length?(a=+t,o):a},alphaDecay:function(t){return arguments.length?(c=+t,o):+c},alphaTarget:function(t){return arguments.length?(s=+t,o):s},velocityDecay:function(t){return arguments.length?(f=1-t,o):1-f},force:function(t,n){return arguments.length>1?(null==n?l.remove(t):l.set(t,i(n)),o):l.get(t)},find:function(n,e,r){var i,o,u,a,c,s=0,f=t.length;for(null==r?r=1/0:r*=r,s=0;s<f;++s)a=t[s],i=n-a.x,o=e-a.y,(u=i*i+o*o)<r&&(c=a,r=u);return c},on:function(t,n){return arguments.length>1?(p.on(t,n),o):p.on(t)}}},fg=function(){function t(t){var n,a=i.length,c=ur(i,pr,dr).visitAfter(e);for(u=t,n=0;n<a;++n)o=i[n],c.visit(r)}function n(){if(i){var t,n,e=i.length;for(a=new Array(e),t=0;t<e;++t)n=i[t],a[n.index]=+c(n,t,i)}}function e(t){var n,e,r,i,o,u=0,c=0;if(t.length){for(r=i=o=0;o<4;++o)(n=t[o])&&(e=Math.abs(n.value))&&(u+=n.value,c+=e,r+=e*n.x,i+=e*n.y);t.x=r/c,t.y=i/c}else{n=t,n.x=n.data.x,n.y=n.data.y;do{u+=a[n.data.index]}while(n=n.next)}t.value=u}function r(t,n,e,r){if(!t.value)return!0;var i=t.x-o.x,c=t.y-o.y,h=r-n,p=i*i+c*c;if(h*h/l<p)return p<f&&(0===i&&(i=Bv(),p+=i*i),0===c&&(c=Bv(),p+=c*c),p<s&&(p=Math.sqrt(s*p)),o.vx+=i*t.value*u/p,o.vy+=c*t.value*u/p),!0;if(!(t.length||p>=f)){(t.data!==o||t.next)&&(0===i&&(i=Bv(),p+=i*i),0===c&&(c=Bv(),p+=c*c),p<s&&(p=Math.sqrt(s*p)));do{t.data!==o&&(h=a[t.data.index]*u/p,o.vx+=i*h,o.vy+=c*h)}while(t=t.next)}}var i,o,u,a,c=Hv(-30),s=1,f=1/0,l=.81;return t.initialize=function(t){i=t,n()},t.strength=function(e){return arguments.length?(c="function"==typeof e?e:Hv(+e),n(),t):c},t.distanceMin=function(n){return arguments.length?(s=n*n,t):Math.sqrt(s)},t.distanceMax=function(n){return arguments.length?(f=n*n,t):Math.sqrt(f)},t.theta=function(n){return arguments.length?(l=n*n,t):Math.sqrt(l)},t},lg=function(t,n,e){function r(t){for(var r=0,i=o.length;r<i;++r){var c=o[r],s=c.x-n||1e-6,f=c.y-e||1e-6,l=Math.sqrt(s*s+f*f),h=(a[r]-l)*u[r]*t/l;c.vx+=s*h,c.vy+=f*h}}function i(){if(o){var n,e=o.length;for(u=new Array(e),a=new Array(e),n=0;n<e;++n)a[n]=+t(o[n],n,o),u[n]=isNaN(a[n])?0:+c(o[n],n,o)}}var o,u,a,c=Hv(.1);return"function"!=typeof t&&(t=Hv(+t)),null==n&&(n=0),null==e&&(e=0),r.initialize=function(t){o=t,i()},r.strength=function(t){return arguments.length?(c="function"==typeof t?t:Hv(+t),i(),r):c},r.radius=function(n){return arguments.length?(t="function"==typeof n?n:Hv(+n),i(),r):t},r.x=function(t){return arguments.length?(n=+t,r):n},r.y=function(t){return arguments.length?(e=+t,r):e},r},hg=function(t){function n(t){for(var n,e=0,u=r.length;e<u;++e)n=r[e],n.vx+=(o[e]-n.x)*i[e]*t}function e(){if(r){var n,e=r.length;for(i=new Array(e),o=new Array(e),n=0;n<e;++n)i[n]=isNaN(o[n]=+t(r[n],n,r))?0:+u(r[n],n,r)}}var r,i,o,u=Hv(.1);return"function"!=typeof t&&(t=Hv(null==t?0:+t)),n.initialize=function(t){r=t,e()},n.strength=function(t){return arguments.length?(u="function"==typeof t?t:Hv(+t),e(),n):u},n.x=function(r){return arguments.length?(t="function"==typeof r?r:Hv(+r),e(),n):t},n},pg=function(t){function n(t){for(var n,e=0,u=r.length;e<u;++e)n=r[e],n.vy+=(o[e]-n.y)*i[e]*t}function e(){if(r){var n,e=r.length;for(i=new Array(e),o=new Array(e),n=0;n<e;++n)i[n]=isNaN(o[n]=+t(r[n],n,r))?0:+u(r[n],n,r)}}var r,i,o,u=Hv(.1);return"function"!=typeof t&&(t=Hv(null==t?0:+t)),n.initialize=function(t){r=t,e()},n.strength=function(t){return arguments.length?(u="function"==typeof t?t:Hv(+t),e(),n):u},n.y=function(r){return arguments.length?(t="function"==typeof r?r:Hv(+r),e(),n):t},n},dg=function(t,n){if((e=(t=n?t.toExponential(n-1):t.toExponential()).indexOf("e"))<0)return null;var e,r=t.slice(0,e);return[r.length>1?r[0]+r.slice(2):r,+t.slice(e+1)]},vg=function(t){return t=dg(Math.abs(t)),t?t[1]:NaN},gg=function(t,n){return function(e,r){for(var i=e.length,o=[],u=0,a=t[0],c=0;i>0&&a>0&&(c+a+1>r&&(a=Math.max(1,r-c)),o.push(e.substring(i-=a,i+a)),!((c+=a+1)>r));)a=t[u=(u+1)%t.length];return o.reverse().join(n)}},yg=function(t){return function(n){return n.replace(/[0-9]/g,function(n){return t[+n]})}},_g=function(t,n){t=t.toPrecision(n);t:for(var e,r=t.length,i=1,o=-1;i<r;++i)switch(t[i]){case".":o=e=i;break;case"0":0===o&&(o=i),e=i;break;case"e":break t;default:o>0&&(o=0)}return o>0?t.slice(0,o)+t.slice(e+1):t},mg=function(t,n){var e=dg(t,n);if(!e)return t+"";var r=e[0],i=e[1],o=i-(ig=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,u=r.length;return o===u?r:o>u?r+new Array(o-u+1).join("0"):o>0?r.slice(0,o)+"."+r.slice(o):"0."+new Array(1-o).join("0")+dg(t,Math.max(0,n+o-1))[0]},xg=function(t,n){var e=dg(t,n);if(!e)return t+"";var r=e[0],i=e[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")},bg={"":_g,"%":function(t,n){return(100*t).toFixed(n)},b:function(t){return Math.round(t).toString(2)},c:function(t){return t+""},d:function(t){return Math.round(t).toString(10)},e:function(t,n){return t.toExponential(n)},f:function(t,n){return t.toFixed(n)},g:function(t,n){return t.toPrecision(n)},o:function(t){return Math.round(t).toString(8)},p:function(t,n){return xg(100*t,n)},r:xg,s:mg,X:function(t){return Math.round(t).toString(16).toUpperCase()},x:function(t){return Math.round(t).toString(16)}},wg=/^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;vr.prototype=gr.prototype,gr.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(null==this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(null==this.precision?"":"."+Math.max(0,0|this.precision))+this.type};var Mg,Tg=function(t){return t},Ng=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"],kg=function(t){function n(t){function n(t){var n,i,a,f=g,x=y;if("c"===v)x=_(t)+x,t="";else{t=+t;var b=t<0;if(t=_(Math.abs(t),d),b&&0==+t&&(b=!1),f=(b?"("===s?s:"-":"-"===s||"("===s?"":s)+f,x=x+("s"===v?Ng[8+ig/3]:"")+(b&&"("===s?")":""),m)for(n=-1,i=t.length;++n<i;)if(48>(a=t.charCodeAt(n))||a>57){x=(46===a?o+t.slice(n+1):t.slice(n))+x,t=t.slice(0,n);break}}p&&!l&&(t=r(t,1/0));var w=f.length+t.length+x.length,M=w<h?new Array(h-w+1).join(e):"";switch(p&&l&&(t=r(M+t,M.length?h-x.length:1/0),M=""),c){case"<":t=f+t+x+M;break;case"=":t=f+M+t+x;break;case"^":t=M.slice(0,w=M.length>>1)+f+t+x+M.slice(w);break;default:t=M+f+t+x}return u(t)}t=vr(t);var e=t.fill,c=t.align,s=t.sign,f=t.symbol,l=t.zero,h=t.width,p=t.comma,d=t.precision,v=t.type,g="$"===f?i[0]:"#"===f&&/[boxX]/.test(v)?"0"+v.toLowerCase():"",y="$"===f?i[1]:/[%p]/.test(v)?a:"",_=bg[v],m=!v||/[defgprs%]/.test(v);return d=null==d?v?6:12:/[gprs]/.test(v)?Math.max(1,Math.min(21,d)):Math.max(0,Math.min(20,d)),n.toString=function(){return t+""},n}function e(t,e){var r=n((t=vr(t),t.type="f",t)),i=3*Math.max(-8,Math.min(8,Math.floor(vg(e)/3))),o=Math.pow(10,-i),u=Ng[8+i/3];return function(t){return r(o*t)+u}}var r=t.grouping&&t.thousands?gg(t.grouping,t.thousands):Tg,i=t.currency,o=t.decimal,u=t.numerals?yg(t.numerals):Tg,a=t.percent||"%";return{format:n,formatPrefix:e}};yr({decimal:".",thousands:",",grouping:[3],currency:["$",""]});var Sg=function(t){return Math.max(0,-vg(Math.abs(t)))},Ag=function(t,n){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(vg(n)/3)))-vg(Math.abs(t)))},Eg=function(t,n){return t=Math.abs(t),n=Math.abs(n)-t,Math.max(0,vg(n)-vg(t))+1},Cg=function(){return new _r};_r.prototype={constructor:_r,reset:function(){this.s=this.t=0},add:function(t){mr(cy,t,this.t),mr(this,cy.s,this.s),this.s?this.t+=cy.t:this.s=cy.t},valueOf:function(){return this.s}};var zg,Pg,Rg,Lg,Dg,qg,Ug,Og,Fg,Yg,Ig,Hg,Bg,jg,Xg,Wg,Vg,$g,Zg,Gg,Qg,Jg,Kg,ty,ny,ey,ry,iy,oy,uy,ay,cy=new _r,sy=1e-6,fy=Math.PI,ly=fy/2,hy=fy/4,py=2*fy,dy=180/fy,vy=fy/180,gy=Math.abs,yy=Math.atan,_y=Math.atan2,my=Math.cos,xy=Math.ceil,by=Math.exp,wy=Math.log,My=Math.pow,Ty=Math.sin,Ny=Math.sign||function(t){return t>0?1:t<0?-1:0},ky=Math.sqrt,Sy=Math.tan,Ay={Feature:function(t,n){Tr(t.geometry,n)},FeatureCollection:function(t,n){for(var e=t.features,r=-1,i=e.length;++r<i;)Tr(e[r].geometry,n)}},Ey={Sphere:function(t,n){n.sphere()},Point:function(t,n){t=t.coordinates,n.point(t[0],t[1],t[2])},MultiPoint:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)t=e[r],n.point(t[0],t[1],t[2])},LineString:function(t,n){Nr(t.coordinates,n,0)},MultiLineString:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)Nr(e[r],n,0)},Polygon:function(t,n){kr(t.coordinates,n)},MultiPolygon:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)kr(e[r],n)},GeometryCollection:function(t,n){for(var e=t.geometries,r=-1,i=e.length;++r<i;)Tr(e[r],n)}},Cy=function(t,n){t&&Ay.hasOwnProperty(t.type)?Ay[t.type](t,n):Tr(t,n)},zy=Cg(),Py=Cg(),Ry={point:Mr,lineStart:Mr,lineEnd:Mr,polygonStart:function(){zy.reset(),Ry.lineStart=Sr,Ry.lineEnd=Ar},polygonEnd:function(){var t=+zy;Py.add(t<0?py+t:t),this.lineStart=this.lineEnd=this.point=Mr},sphere:function(){Py.add(py)}},Ly=function(t){return Py.reset(),Cy(t,Ry),2*Py},Dy=Cg(),qy={point:Or,lineStart:Yr,lineEnd:Ir,polygonStart:function(){qy.point=Hr,qy.lineStart=Br,qy.lineEnd=jr,Dy.reset(),Ry.polygonStart()},polygonEnd:function(){Ry.polygonEnd(),qy.point=Or,qy.lineStart=Yr,qy.lineEnd=Ir,zy<0?(qg=-(Og=180),Ug=-(Fg=90)):Dy>sy?Fg=90:Dy<-sy&&(Ug=-90),Xg[0]=qg,Xg[1]=Og}},Uy=function(t){var n,e,r,i,o,u,a;if(Fg=Og=-(qg=Ug=1/0),jg=[],Cy(t,qy),e=jg.length){for(jg.sort(Wr),n=1,r=jg[0],o=[r];n<e;++n)i=jg[n],Vr(r,i[0])||Vr(r,i[1])?(Xr(r[0],i[1])>Xr(r[0],r[1])&&(r[1]=i[1]),Xr(i[0],r[1])>Xr(r[0],r[1])&&(r[0]=i[0])):o.push(r=i);for(u=-1/0,e=o.length-1,n=0,r=o[e];n<=e;r=i,++n)i=o[n],(a=Xr(r[1],i[0]))>u&&(u=a,qg=i[0],Og=r[1])}return jg=Xg=null,qg===1/0||Ug===1/0?[[NaN,NaN],[NaN,NaN]]:[[qg,Ug],[Og,Fg]]},Oy={sphere:Mr,point:$r,lineStart:Gr,lineEnd:Kr,polygonStart:function(){Oy.lineStart=ti,Oy.lineEnd=ni},polygonEnd:function(){Oy.lineStart=Gr,Oy.lineEnd=Kr}},Fy=function(t){Wg=Vg=$g=Zg=Gg=Qg=Jg=Kg=ty=ny=ey=0,Cy(t,Oy);var n=ty,e=ny,r=ey,i=n*n+e*e+r*r;return i<1e-12&&(n=Qg,e=Jg,r=Kg,Vg<sy&&(n=$g,e=Zg,r=Gg),(i=n*n+e*e+r*r)<1e-12)?[NaN,NaN]:[_y(e,n)*dy,br(r/ky(i))*dy]},Yy=function(t){return function(){return t}},Iy=function(t,n){function e(e,r){return e=t(e,r),n(e[0],e[1])}return t.invert&&n.invert&&(e.invert=function(e,r){return(e=n.invert(e,r))&&t.invert(e[0],e[1])}),e};ii.invert=ii;var Hy,By,jy,Xy,Wy,Vy,$y,Zy,Gy,Qy,Jy,Ky=function(t){function n(n){return n=t(n[0]*vy,n[1]*vy),n[0]*=dy,n[1]*=dy,n}return t=oi(t[0]*vy,t[1]*vy,t.length>2?t[2]*vy:0),n.invert=function(n){return n=t.invert(n[0]*vy,n[1]*vy),n[0]*=dy,n[1]*=dy,n},n},t_=function(){function t(t,n){e.push(t=r(t,n)),t[0]*=dy,t[1]*=dy}function n(){var t=i.apply(this,arguments),n=o.apply(this,arguments)*vy,c=u.apply(this,arguments)*vy;return e=[],r=oi(-t[0]*vy,-t[1]*vy,0).invert,si(a,n,c,1),t={type:"Polygon",coordinates:[e]},e=r=null,t}var e,r,i=Yy([0,0]),o=Yy(90),u=Yy(6),a={point:t};return n.center=function(t){return arguments.length?(i="function"==typeof t?t:Yy([+t[0],+t[1]]),n):i},n.radius=function(t){return arguments.length?(o="function"==typeof t?t:Yy(+t),n):o},n.precision=function(t){return arguments.length?(u="function"==typeof t?t:Yy(+t),n):u},n},n_=function(){var t,n=[];return{point:function(n,e){t.push([n,e])},lineStart:function(){n.push(t=[])},lineEnd:Mr,rejoin:function(){n.length>1&&n.push(n.pop().concat(n.shift()))},result:function(){var e=n;return n=[],t=null,e}}},e_=function(t,n){return gy(t[0]-n[0])<sy&&gy(t[1]-n[1])<sy},r_=function(t,n,e,r,i){var o,u,a=[],c=[];if(t.forEach(function(t){if(!((n=t.length-1)<=0)){var n,e,r=t[0],u=t[n];if(e_(r,u)){for(i.lineStart(),o=0;o<n;++o)i.point((r=t[o])[0],r[1]);return void i.lineEnd()}a.push(e=new li(r,t,null,!0)),c.push(e.o=new li(r,null,e,!1)),a.push(e=new li(u,t,null,!1)),c.push(e.o=new li(u,null,e,!0))}}),a.length){for(c.sort(n),hi(a),hi(c),o=0,u=c.length;o<u;++o)c[o].e=e=!e;for(var s,f,l=a[0];;){for(var h=l,p=!0;h.v;)if((h=h.n)===l)return;s=h.z,i.lineStart();do{if(h.v=h.o.v=!0,h.e){if(p)for(o=0,u=s.length;o<u;++o)i.point((f=s[o])[0],f[1]);else r(h.x,h.n.x,1,i);h=h.n}else{if(p)for(s=h.p.z,o=s.length-1;o>=0;--o)i.point((f=s[o])[0],f[1]);else r(h.x,h.p.x,-1,i);h=h.p}h=h.o,s=h.z,p=!p}while(!h.v);i.lineEnd()}}},i_=Cg(),o_=function(t,n){var e=n[0],r=n[1],i=[Ty(e),-my(e),0],o=0,u=0;i_.reset();for(var a=0,c=t.length;a<c;++a)if(f=(s=t[a]).length)for(var s,f,l=s[f-1],h=l[0],p=l[1]/2+hy,d=Ty(p),v=my(p),g=0;g<f;++g,h=_,d=x,v=b,l=y){var y=s[g],_=y[0],m=y[1]/2+hy,x=Ty(m),b=my(m),w=_-h,M=w>=0?1:-1,T=M*w,N=T>fy,k=d*x;if(i_.add(_y(k*M*Ty(T),v*b+k*my(T))),o+=N?w+M*py:w,N^h>=e^_>=e){var S=Lr(Pr(l),Pr(y));Ur(S);var A=Lr(i,S);Ur(A);var E=(N^w>=0?-1:1)*br(A[2]);(r>E||r===E&&(S[0]||S[1]))&&(u+=N^w>=0?1:-1)}}return(o<-sy||o<sy&&i_<-sy)^1&u},u_=function(t,n,e,r){return function(i){function o(n,e){t(n,e)&&i.point(n,e)}function u(t,n){v.point(t,n)}function a(){m.point=u,v.lineStart()}function c(){m.point=o,v.lineEnd()}function s(t,n){d.push([t,n]),y.point(t,n)}function f(){y.lineStart(),d=[]}function l(){s(d[0][0],d[0][1]),y.lineEnd();var t,n,e,r,o=y.clean(),u=g.result(),a=u.length;if(d.pop(),h.push(d),d=null,a)if(1&o){if(e=u[0],(n=e.length-1)>0){for(_||(i.polygonStart(),_=!0),i.lineStart(),t=0;t<n;++t)i.point((r=e[t])[0],r[1]);i.lineEnd()}}else a>1&&2&o&&u.push(u.pop().concat(u.shift())),p.push(u.filter(pi))}var h,p,d,v=n(i),g=n_(),y=n(g),_=!1,m={point:o,lineStart:a,lineEnd:c,polygonStart:function(){m.point=s,m.lineStart=f,m.lineEnd=l,p=[],h=[]},polygonEnd:function(){m.point=o,m.lineStart=a,m.lineEnd=c,p=Kf(p);var t=o_(h,r);p.length?(_||(i.polygonStart(),_=!0),r_(p,di,t,e,i)):t&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),p=h=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}};return m}},a_=u_(function(){return!0},vi,yi,[-fy,-ly]),c_=function(t){function n(n,e,r,i){si(i,t,a,r,n,e)}function e(t,n){return my(t)*my(n)>u}function r(t){var n,r,u,a,f;return{lineStart:function(){a=u=!1,f=1},point:function(l,h){var p,d=[l,h],v=e(l,h),g=c?v?0:o(l,h):v?o(l+(l<0?fy:-fy),h):0;if(!n&&(a=u=v)&&t.lineStart(),v!==u&&(!(p=i(n,d))||e_(n,p)||e_(d,p))&&(d[0]+=sy,d[1]+=sy,v=e(d[0],d[1])),v!==u)f=0,v?(t.lineStart(),p=i(d,n),t.point(p[0],p[1])):(p=i(n,d),t.point(p[0],p[1]),t.lineEnd()),n=p;else if(s&&n&&c^v){var y;g&r||!(y=i(d,n,!0))||(f=0,c?(t.lineStart(),t.point(y[0][0],y[0][1]),t.point(y[1][0],y[1][1]),t.lineEnd()):(t.point(y[1][0],y[1][1]),t.lineEnd(),t.lineStart(),t.point(y[0][0],y[0][1])))}!v||n&&e_(n,d)||t.point(d[0],d[1]),n=d,u=v,r=g},lineEnd:function(){u&&t.lineEnd(),n=null},clean:function(){return f|(a&&u)<<1}}}function i(t,n,e){var r=Pr(t),i=Pr(n),o=[1,0,0],a=Lr(r,i),c=Rr(a,a),s=a[0],f=c-s*s;if(!f)return!e&&t;var l=u*c/f,h=-u*s/f,p=Lr(o,a),d=qr(o,l);Dr(d,qr(a,h));var v=p,g=Rr(d,v),y=Rr(v,v),_=g*g-y*(Rr(d,d)-1);if(!(_<0)){var m=ky(_),x=qr(v,(-g-m)/y);if(Dr(x,d),x=zr(x),!e)return x;var b,w=t[0],M=n[0],T=t[1],N=n[1];M<w&&(b=w,w=M,M=b);var k=M-w,S=gy(k-fy)<sy,A=S||k<sy;if(!S&&N<T&&(b=T,T=N,N=b),A?S?T+N>0^x[1]<(gy(x[0]-w)<sy?T:N):T<=x[1]&&x[1]<=N:k>fy^(w<=x[0]&&x[0]<=M)){var E=qr(v,(-g+m)/y);return Dr(E,d),[x,zr(E)]}}}function o(n,e){var r=c?t:fy-t,i=0;return n<-r?i|=1:n>r&&(i|=2),e<-r?i|=4:e>r&&(i|=8),i}var u=my(t),a=6*vy,c=u>0,s=gy(u)>sy;return u_(e,r,n,c?[0,-t]:[-fy,t-fy])},s_=function(t,n,e,r,i,o){var u,a=t[0],c=t[1],s=n[0],f=n[1],l=0,h=1,p=s-a,d=f-c;if(u=e-a,p||!(u>0)){if(u/=p,p<0){if(u<l)return;u<h&&(h=u)}else if(p>0){if(u>h)return;u>l&&(l=u)}if(u=i-a,p||!(u<0)){if(u/=p,p<0){if(u>h)return;u>l&&(l=u)}else if(p>0){if(u<l)return;u<h&&(h=u)}if(u=r-c,d||!(u>0)){if(u/=d,d<0){if(u<l)return;u<h&&(h=u)}else if(d>0){if(u>h)return;u>l&&(l=u)}if(u=o-c,d||!(u<0)){if(u/=d,d<0){if(u>h)return;u>l&&(l=u)}else if(d>0){if(u<l)return;u<h&&(h=u)}return l>0&&(t[0]=a+l*p,t[1]=c+l*d),h<1&&(n[0]=a+h*p,n[1]=c+h*d),!0}}}}},f_=1e9,l_=-f_,h_=function(){var t,n,e,r=0,i=0,o=960,u=500;return e={stream:function(e){return t&&n===e?t:t=_i(r,i,o,u)(n=e)},extent:function(a){return arguments.length?(r=+a[0][0],i=+a[0][1],o=+a[1][0],u=+a[1][1],t=n=null,e):[[r,i],[o,u]]}}},p_=Cg(),d_={sphere:Mr,point:Mr,lineStart:mi,lineEnd:Mr,polygonStart:Mr,polygonEnd:Mr},v_=function(t){return p_.reset(),Cy(t,d_),+p_},g_=[null,null],y_={type:"LineString",coordinates:g_},__=function(t,n){return g_[0]=t,g_[1]=n,v_(y_)},m_={Feature:function(t,n){return Mi(t.geometry,n)},FeatureCollection:function(t,n){for(var e=t.features,r=-1,i=e.length;++r<i;)if(Mi(e[r].geometry,n))return!0;return!1}},x_={Sphere:function(){return!0},Point:function(t,n){return Ti(t.coordinates,n)},MultiPoint:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)if(Ti(e[r],n))return!0;return!1},LineString:function(t,n){return Ni(t.coordinates,n)},MultiLineString:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)if(Ni(e[r],n))return!0;return!1},Polygon:function(t,n){return ki(t.coordinates,n)},MultiPolygon:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)if(ki(e[r],n))return!0;return!1},GeometryCollection:function(t,n){for(var e=t.geometries,r=-1,i=e.length;++r<i;)if(Mi(e[r],n))return!0;return!1}},b_=function(t,n){return(t&&m_.hasOwnProperty(t.type)?m_[t.type]:Mi)(t,n)},w_=function(t,n){var e=t[0]*vy,r=t[1]*vy,i=n[0]*vy,o=n[1]*vy,u=my(r),a=Ty(r),c=my(o),s=Ty(o),f=u*my(e),l=u*Ty(e),h=c*my(i),p=c*Ty(i),d=2*br(ky(wr(o-r)+u*c*wr(i-e))),v=Ty(d),g=d?function(t){var n=Ty(t*=d)/v,e=Ty(d-t)/v,r=e*f+n*h,i=e*l+n*p,o=e*a+n*s;return[_y(i,r)*dy,_y(o,ky(r*r+i*i))*dy]}:function(){return[e*dy,r*dy]};return g.distance=d,g},M_=function(t){return t},T_=Cg(),N_=Cg(),k_={point:Mr,lineStart:Mr,lineEnd:Mr,polygonStart:function(){k_.lineStart=Ri,k_.lineEnd=qi},polygonEnd:function(){k_.lineStart=k_.lineEnd=k_.point=Mr,T_.add(gy(N_)),N_.reset()},result:function(){var t=T_/2;return T_.reset(),t}},S_=1/0,A_=S_,E_=-S_,C_=E_,z_={point:Ui,lineStart:Mr,lineEnd:Mr,polygonStart:Mr,polygonEnd:Mr,result:function(){var t=[[S_,A_],[E_,C_]];return E_=C_=-(A_=S_=1/0),t}},P_=0,R_=0,L_=0,D_=0,q_=0,U_=0,O_=0,F_=0,Y_=0,I_={point:Oi,lineStart:Fi,lineEnd:Hi,polygonStart:function(){I_.lineStart=Bi,I_.lineEnd=ji},polygonEnd:function(){I_.point=Oi,I_.lineStart=Fi,I_.lineEnd=Hi},result:function(){var t=Y_?[O_/Y_,F_/Y_]:U_?[D_/U_,q_/U_]:L_?[P_/L_,R_/L_]:[NaN,NaN];return P_=R_=L_=D_=q_=U_=O_=F_=Y_=0,t}};Vi.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(t,n){switch(this._point){case 0:this._context.moveTo(t,n),this._point=1;break;case 1:this._context.lineTo(t,n);break;default:this._context.moveTo(t+this._radius,n),this._context.arc(t,n,this._radius,0,py)}},result:Mr};var H_,B_,j_,X_,W_,V_=Cg(),$_={point:Mr,lineStart:function(){$_.point=$i},lineEnd:function(){H_&&Zi(B_,j_),$_.point=Mr},polygonStart:function(){H_=!0},polygonEnd:function(){H_=null},result:function(){var t=+V_;return V_.reset(),t}};Gi.prototype={_radius:4.5,_circle:Qi(4.5),pointRadius:function(t){return(t=+t)!==this._radius&&(this._radius=t,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push("Z"),this._point=NaN},point:function(t,n){switch(this._point){case 0:this._string.push("M",t,",",n),this._point=1;break;case 1:this._string.push("L",t,",",n);break;default:null==this._circle&&(this._circle=Qi(this._radius)),this._string.push("M",t,",",n,this._circle)}},result:function(){if(this._string.length){var t=this._string.join("");return this._string=[],t}return null}};var Z_=function(t,n){function e(t){return t&&("function"==typeof o&&i.pointRadius(+o.apply(this,arguments)),Cy(t,r(i))),i.result()}var r,i,o=4.5;return e.area=function(t){return Cy(t,r(k_)),k_.result()},e.measure=function(t){return Cy(t,r($_)),$_.result()},e.bounds=function(t){return Cy(t,r(z_)),z_.result()},e.centroid=function(t){return Cy(t,r(I_)),I_.result()},e.projection=function(n){return arguments.length?(r=null==n?(t=null,M_):(t=n).stream,e):t},e.context=function(t){return arguments.length?(i=null==t?(n=null,new Gi):new Vi(n=t),"function"!=typeof o&&i.pointRadius(o),e):n},e.pointRadius=function(t){return arguments.length?(o="function"==typeof t?t:(i.pointRadius(+t),+t),e):o},e.projection(t).context(n)},G_=function(t){return{stream:Ji(t)}};Ki.prototype={constructor:Ki,point:function(t,n){this.stream.point(t,n)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var Q_=16,J_=my(30*vy),K_=function(t,n){return+n?uo(t,n):oo(t)},tm=Ji({point:function(t,n){this.stream.point(t*vy,n*vy)}}),nm=function(){return fo(ho).scale(155.424).center([0,33.6442])},em=function(){return nm().parallels([29.5,45.5]).scale(1070).translate([480,250]).rotate([96,0]).center([-.6,38.7])},rm=function(){function t(t){var n=t[0],e=t[1];return a=null,i.point(n,e),a||(o.point(n,e),a)||(u.point(n,e),a)}function n(){return e=r=null,t}var e,r,i,o,u,a,c=em(),s=nm().rotate([154,0]).center([-2,58.5]).parallels([55,65]),f=nm().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(t,n){a=[t,n]}};return t.invert=function(t){var n=c.scale(),e=c.translate(),r=(t[0]-e[0])/n,i=(t[1]-e[1])/n;return(i>=.12&&i<.234&&r>=-.425&&r<-.214?s:i>=.166&&i<.234&&r>=-.214&&r<-.115?f:c).invert(t)},t.stream=function(t){return e&&r===t?e:e=po([c.stream(r=t),s.stream(t),f.stream(t)])},t.precision=function(t){return arguments.length?(c.precision(t),s.precision(t),f.precision(t),n()):c.precision()},t.scale=function(n){return arguments.length?(c.scale(n),s.scale(.35*n),f.scale(n),t.translate(c.translate())):c.scale()},t.translate=function(t){if(!arguments.length)return c.translate();var e=c.scale(),r=+t[0],a=+t[1];return i=c.translate(t).clipExtent([[r-.455*e,a-.238*e],[r+.455*e,a+.238*e]]).stream(l),o=s.translate([r-.307*e,a+.201*e]).clipExtent([[r-.425*e+sy,a+.12*e+sy],[r-.214*e-sy,a+.234*e-sy]]).stream(l),u=f.translate([r-.205*e,a+.212*e]).clipExtent([[r-.214*e+sy,a+.166*e+sy],[r-.115*e-sy,a+.234*e-sy]]).stream(l),n()},t.fitExtent=function(n,e){return no(t,n,e)},t.fitSize=function(n,e){return eo(t,n,e)},t.fitWidth=function(n,e){return ro(t,n,e)},t.fitHeight=function(n,e){return io(t,n,e)},t.scale(1070)},im=vo(function(t){return ky(2/(1+t))});im.invert=go(function(t){return 2*br(t/2)});var om=function(){return co(im).scale(124.75).clipAngle(179.999)},um=vo(function(t){return(t=xr(t))&&t/Ty(t)});um.invert=go(function(t){return t});var am=function(){return co(um).scale(79.4188).clipAngle(179.999)};yo.invert=function(t,n){return[t,2*yy(by(n))-ly]};var cm=function(){return _o(yo).scale(961/py)},sm=function(){return fo(xo).scale(109.5).parallels([30,30])};bo.invert=bo;var fm=function(){return co(bo).scale(152.63)},lm=function(){return fo(wo).scale(131.154).center([0,13.9389])};Mo.invert=go(yy);var hm=function(){return co(Mo).scale(144.049).clipAngle(60)},pm=function(){function t(){return i=o=null,u}var n,e,r,i,o,u,a=1,c=0,s=0,f=1,l=1,h=M_,p=null,d=M_;return u={stream:function(t){return i&&o===t?i:i=h(d(o=t))},postclip:function(i){return arguments.length?(d=i,p=n=e=r=null,t()):d},clipExtent:function(i){return arguments.length?(d=null==i?(p=n=e=r=null,M_):_i(p=+i[0][0],n=+i[0][1],e=+i[1][0],r=+i[1][1]),t()):null==p?null:[[p,n],[e,r]]},scale:function(n){return arguments.length?(h=To((a=+n)*f,a*l,c,s),t()):a},translate:function(n){return arguments.length?(h=To(a*f,a*l,c=+n[0],s=+n[1]),t()):[c,s]},reflectX:function(n){return arguments.length?(h=To(a*(f=n?-1:1),a*l,c,s),t()):f<0},reflectY:function(n){return arguments.length?(h=To(a*f,a*(l=n?-1:1),c,s),t()):l<0},fitExtent:function(t,n){return no(u,t,n)},fitSize:function(t,n){return eo(u,t,n)},fitWidth:function(t,n){return ro(u,t,n)},fitHeight:function(t,n){return io(u,t,n)}}};No.invert=function(t,n){ | |
var e,r=n,i=25;do{var o=r*r,u=o*o;r-=e=(r*(1.007226+o*(.015085+u*(.028874*o-.044475-.005916*u)))-n)/(1.007226+o*(.045255+u*(.259866*o-.311325-.005916*11*u)))}while(gy(e)>sy&&--i>0);return[t/(.8707+(o=r*r)*(o*(o*o*o*(.003971-.001529*o)-.013791)-.131979)),r]};var dm=function(){return co(No).scale(175.295)};ko.invert=go(br);var vm=function(){return co(ko).scale(249.5).clipAngle(90+sy)};So.invert=go(function(t){return 2*yy(t)});var gm=function(){return co(So).scale(250).clipAngle(142)};Ao.invert=function(t,n){return[-n,2*yy(by(t))-ly]};var ym=function(){var t=_o(Ao),n=t.center,e=t.rotate;return t.center=function(t){return arguments.length?n([-t[1],t[0]]):(t=n(),[t[1],-t[0]])},t.rotate=function(t){return arguments.length?e([t[0],t[1],t.length>2?t[2]+90:90]):(t=e(),[t[0],t[1],t[2]-90])},e([0,0,90]).scale(159.155)},_m=function(){function t(t){var o,u=0;t.eachAfter(function(t){var e=t.children;e?(t.x=Co(e),t.y=Po(e)):(t.x=o?u+=n(t,o):0,t.y=0,o=t)});var a=Lo(t),c=Do(t),s=a.x-n(a,c)/2,f=c.x+n(c,a)/2;return t.eachAfter(i?function(n){n.x=(n.x-t.x)*e,n.y=(t.y-n.y)*r}:function(n){n.x=(n.x-s)/(f-s)*e,n.y=(1-(t.y?n.y/t.y:1))*r})}var n=Eo,e=1,r=1,i=!1;return t.separation=function(e){return arguments.length?(n=e,t):n},t.size=function(n){return arguments.length?(i=!1,e=+n[0],r=+n[1],t):i?null:[e,r]},t.nodeSize=function(n){return arguments.length?(i=!0,e=+n[0],r=+n[1],t):i?[e,r]:null},t},mm=function(){return this.eachAfter(qo)},xm=function(t){var n,e,r,i,o=this,u=[o];do{for(n=u.reverse(),u=[];o=n.pop();)if(t(o),e=o.children)for(r=0,i=e.length;r<i;++r)u.push(e[r])}while(u.length);return this},bm=function(t){for(var n,e,r=this,i=[r];r=i.pop();)if(t(r),n=r.children)for(e=n.length-1;e>=0;--e)i.push(n[e]);return this},wm=function(t){for(var n,e,r,i=this,o=[i],u=[];i=o.pop();)if(u.push(i),n=i.children)for(e=0,r=n.length;e<r;++e)o.push(n[e]);for(;i=u.pop();)t(i);return this},Mm=function(t){return this.eachAfter(function(n){for(var e=+t(n.data)||0,r=n.children,i=r&&r.length;--i>=0;)e+=r[i].value;n.value=e})},Tm=function(t){return this.eachBefore(function(n){n.children&&n.children.sort(t)})},Nm=function(t){for(var n=this,e=Uo(n,t),r=[n];n!==e;)n=n.parent,r.push(n);for(var i=r.length;t!==e;)r.splice(i,0,t),t=t.parent;return r},km=function(){for(var t=this,n=[t];t=t.parent;)n.push(t);return n},Sm=function(){var t=[];return this.each(function(n){t.push(n)}),t},Am=function(){var t=[];return this.eachBefore(function(n){n.children||t.push(n)}),t},Em=function(){var t=this,n=[];return t.each(function(e){e!==t&&n.push({source:e.parent,target:e})}),n};Bo.prototype=Oo.prototype={constructor:Bo,count:mm,each:xm,eachAfter:wm,eachBefore:bm,sum:Mm,sort:Tm,path:Nm,ancestors:km,descendants:Sm,leaves:Am,links:Em,copy:Fo};var Cm=Array.prototype.slice,zm=function(t){for(var n,e,r=0,i=(t=jo(Cm.call(t))).length,o=[];r<i;)n=t[r],e&&Vo(e,n)?++r:(e=Zo(o=Xo(o,n)),r=0);return e},Pm=function(t){return ru(t),t},Rm=function(t){return function(){return t}},Lm=function(){function t(t){return t.x=e/2,t.y=r/2,n?t.eachBefore(cu(n)).eachAfter(su(i,.5)).eachBefore(fu(1)):t.eachBefore(cu(au)).eachAfter(su(uu,1)).eachAfter(su(i,t.r/Math.min(e,r))).eachBefore(fu(Math.min(e,r)/(2*t.r))),t}var n=null,e=1,r=1,i=uu;return t.radius=function(e){return arguments.length?(n=iu(e),t):n},t.size=function(n){return arguments.length?(e=+n[0],r=+n[1],t):[e,r]},t.padding=function(n){return arguments.length?(i="function"==typeof n?n:Rm(+n),t):i},t},Dm=function(t){t.x0=Math.round(t.x0),t.y0=Math.round(t.y0),t.x1=Math.round(t.x1),t.y1=Math.round(t.y1)},qm=function(t,n,e,r,i){for(var o,u=t.children,a=-1,c=u.length,s=t.value&&(r-n)/t.value;++a<c;)o=u[a],o.y0=e,o.y1=i,o.x0=n,o.x1=n+=o.value*s},Um=function(){function t(t){var u=t.height+1;return t.x0=t.y0=i,t.x1=e,t.y1=r/u,t.eachBefore(n(r,u)),o&&t.eachBefore(Dm),t}function n(t,n){return function(e){e.children&&qm(e,e.x0,t*(e.depth+1)/n,e.x1,t*(e.depth+2)/n);var r=e.x0,o=e.y0,u=e.x1-i,a=e.y1-i;u<r&&(r=u=(r+u)/2),a<o&&(o=a=(o+a)/2),e.x0=r,e.y0=o,e.x1=u,e.y1=a}}var e=1,r=1,i=0,o=!1;return t.round=function(n){return arguments.length?(o=!!n,t):o},t.size=function(n){return arguments.length?(e=+n[0],r=+n[1],t):[e,r]},t.padding=function(n){return arguments.length?(i=+n,t):i},t},Om="$",Fm={depth:-1},Ym={},Im=function(){function t(t){var r,i,o,u,a,c,s,f=t.length,l=new Array(f),h={};for(i=0;i<f;++i)r=t[i],a=l[i]=new Bo(r),null!=(c=n(r,i,t))&&(c+="")&&(s=Om+(a.id=c),h[s]=s in h?Ym:a);for(i=0;i<f;++i)if(a=l[i],null!=(c=e(t[i],i,t))&&(c+="")){if(!(u=h[Om+c]))throw new Error("missing: "+c);if(u===Ym)throw new Error("ambiguous: "+c);u.children?u.children.push(a):u.children=[a],a.parent=u}else{if(o)throw new Error("multiple roots");o=a}if(!o)throw new Error("no root");if(o.parent=Fm,o.eachBefore(function(t){t.depth=t.parent.depth+1,--f}).eachBefore(Ho),o.parent=null,f>0)throw new Error("cycle");return o}var n=lu,e=hu;return t.id=function(e){return arguments.length?(n=ou(e),t):n},t.parentId=function(n){return arguments.length?(e=ou(n),t):e},t};mu.prototype=Object.create(Bo.prototype);var Hm=function(){function t(t){var r=xu(t);if(r.eachAfter(n),r.parent.m=-r.z,r.eachBefore(e),c)t.eachBefore(i);else{var s=t,f=t,l=t;t.eachBefore(function(t){t.x<s.x&&(s=t),t.x>f.x&&(f=t),t.depth>l.depth&&(l=t)});var h=s===f?1:o(s,f)/2,p=h-s.x,d=u/(f.x+h+p),v=a/(l.depth||1);t.eachBefore(function(t){t.x=(t.x+p)*d,t.y=t.depth*v})}return t}function n(t){var n=t.children,e=t.parent.children,i=t.i?e[t.i-1]:null;if(n){yu(t);var u=(n[0].z+n[n.length-1].z)/2;i?(t.z=i.z+o(t._,i._),t.m=t.z-u):t.z=u}else i&&(t.z=i.z+o(t._,i._));t.parent.A=r(t,i,t.parent.A||e[0])}function e(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function r(t,n,e){if(n){for(var r,i=t,u=t,a=n,c=i.parent.children[0],s=i.m,f=u.m,l=a.m,h=c.m;a=vu(a),i=du(i),a&&i;)c=du(c),u=vu(u),u.a=t,r=a.z+l-i.z-s+o(a._,i._),r>0&&(gu(_u(a,t,e),t,r),s+=r,f+=r),l+=a.m,s+=i.m,h+=c.m,f+=u.m;a&&!vu(u)&&(u.t=a,u.m+=l-f),i&&!du(c)&&(c.t=i,c.m+=s-h,e=t)}return e}function i(t){t.x*=u,t.y=t.depth*a}var o=pu,u=1,a=1,c=null;return t.separation=function(n){return arguments.length?(o=n,t):o},t.size=function(n){return arguments.length?(c=!1,u=+n[0],a=+n[1],t):c?null:[u,a]},t.nodeSize=function(n){return arguments.length?(c=!0,u=+n[0],a=+n[1],t):c?[u,a]:null},t},Bm=function(t,n,e,r,i){for(var o,u=t.children,a=-1,c=u.length,s=t.value&&(i-e)/t.value;++a<c;)o=u[a],o.x0=n,o.x1=r,o.y0=e,o.y1=e+=o.value*s},jm=(1+Math.sqrt(5))/2,Xm=function t(n){function e(t,e,r,i,o){bu(n,t,e,r,i,o)}return e.ratio=function(n){return t((n=+n)>1?n:1)},e}(jm),Wm=function(){function t(t){return t.x0=t.y0=0,t.x1=i,t.y1=o,t.eachBefore(n),u=[0],r&&t.eachBefore(Dm),t}function n(t){var n=u[t.depth],r=t.x0+n,i=t.y0+n,o=t.x1-n,h=t.y1-n;o<r&&(r=o=(r+o)/2),h<i&&(i=h=(i+h)/2),t.x0=r,t.y0=i,t.x1=o,t.y1=h,t.children&&(n=u[t.depth+1]=a(t)/2,r+=l(t)-n,i+=c(t)-n,o-=s(t)-n,h-=f(t)-n,o<r&&(r=o=(r+o)/2),h<i&&(i=h=(i+h)/2),e(t,r,i,o,h))}var e=Xm,r=!1,i=1,o=1,u=[0],a=uu,c=uu,s=uu,f=uu,l=uu;return t.round=function(n){return arguments.length?(r=!!n,t):r},t.size=function(n){return arguments.length?(i=+n[0],o=+n[1],t):[i,o]},t.tile=function(n){return arguments.length?(e=ou(n),t):e},t.padding=function(n){return arguments.length?t.paddingInner(n).paddingOuter(n):t.paddingInner()},t.paddingInner=function(n){return arguments.length?(a="function"==typeof n?n:Rm(+n),t):a},t.paddingOuter=function(n){return arguments.length?t.paddingTop(n).paddingRight(n).paddingBottom(n).paddingLeft(n):t.paddingTop()},t.paddingTop=function(n){return arguments.length?(c="function"==typeof n?n:Rm(+n),t):c},t.paddingRight=function(n){return arguments.length?(s="function"==typeof n?n:Rm(+n),t):s},t.paddingBottom=function(n){return arguments.length?(f="function"==typeof n?n:Rm(+n),t):f},t.paddingLeft=function(n){return arguments.length?(l="function"==typeof n?n:Rm(+n),t):l},t},Vm=function(t,n,e,r,i){function o(t,n,e,r,i,u,a){if(t>=n-1){var s=c[t];return s.x0=r,s.y0=i,s.x1=u,s.y1=a,void 0}for(var l=f[t],h=e/2+l,p=t+1,d=n-1;p<d;){var v=p+d>>>1;f[v]<h?p=v+1:d=v}h-f[p-1]<f[p]-h&&t+1<p&&--p;var g=f[p]-l,y=e-g;if(u-r>a-i){var _=(r*y+u*g)/e;o(t,p,g,r,i,_,a),o(p,n,y,_,i,u,a)}else{var m=(i*y+a*g)/e;o(t,p,g,r,i,u,m),o(p,n,y,r,m,u,a)}}var u,a,c=t.children,s=c.length,f=new Array(s+1);for(f[0]=a=u=0;u<s;++u)f[u+1]=a+=c[u].value;o(0,s,t.value,n,e,r,i)},$m=function(t,n,e,r,i){(1&t.depth?Bm:qm)(t,n,e,r,i)},Zm=function t(n){function e(t,e,r,i,o){if((u=t._squarify)&&u.ratio===n)for(var u,a,c,s,f,l=-1,h=u.length,p=t.value;++l<h;){for(a=u[l],c=a.children,s=a.value=0,f=c.length;s<f;++s)a.value+=c[s].value;a.dice?qm(a,e,r,i,r+=(o-r)*a.value/p):Bm(a,e,r,e+=(i-e)*a.value/p,o),p-=a.value}else t._squarify=u=bu(n,t,e,r,i,o),u.ratio=n}return e.ratio=function(n){return t((n=+n)>1?n:1)},e}(jm),Gm=function(t){for(var n,e=-1,r=t.length,i=t[r-1],o=0;++e<r;)n=i,i=t[e],o+=n[1]*i[0]-n[0]*i[1];return o/2},Qm=function(t){for(var n,e,r=-1,i=t.length,o=0,u=0,a=t[i-1],c=0;++r<i;)n=a,a=t[r],c+=e=n[0]*a[1]-a[0]*n[1],o+=(n[0]+a[0])*e,u+=(n[1]+a[1])*e;return c*=3,[o/c,u/c]},Jm=function(t,n,e){return(n[0]-t[0])*(e[1]-t[1])-(n[1]-t[1])*(e[0]-t[0])},Km=function(t){if((e=t.length)<3)return null;var n,e,r=new Array(e),i=new Array(e);for(n=0;n<e;++n)r[n]=[+t[n][0],+t[n][1],n];for(r.sort(wu),n=0;n<e;++n)i[n]=[r[n][0],-r[n][1]];var o=Mu(r),u=Mu(i),a=u[0]===o[0],c=u[u.length-1]===o[o.length-1],s=[];for(n=o.length-1;n>=0;--n)s.push(t[r[o[n]][2]]);for(n=+a;n<u.length-c;++n)s.push(t[r[u[n]][2]]);return s},tx=function(t,n){for(var e,r,i=t.length,o=t[i-1],u=n[0],a=n[1],c=o[0],s=o[1],f=!1,l=0;l<i;++l)o=t[l],e=o[0],r=o[1],r>a!=s>a&&u<(c-e)*(a-r)/(s-r)+e&&(f=!f),c=e,s=r;return f},nx=function(t){for(var n,e,r=-1,i=t.length,o=t[i-1],u=o[0],a=o[1],c=0;++r<i;)n=u,e=a,o=t[r],u=o[0],a=o[1],n-=u,e-=a,c+=Math.sqrt(n*n+e*e);return c},ex=[].slice,rx={};Tu.prototype=Cu.prototype={constructor:Tu,defer:function(t){if("function"!=typeof t)throw new Error("invalid callback");if(this._call)throw new Error("defer after await");if(null!=this._error)return this;var n=ex.call(arguments,1);return n.push(t),++this._waiting,this._tasks.push(n),Nu(this),this},abort:function(){return null==this._error&&Au(this,new Error("abort")),this},await:function(t){if("function"!=typeof t)throw new Error("invalid callback");if(this._call)throw new Error("multiple await");return this._call=function(n,e){t.apply(null,[n].concat(e))},Eu(this),this},awaitAll:function(t){if("function"!=typeof t)throw new Error("invalid callback");if(this._call)throw new Error("multiple await");return this._call=t,Eu(this),this}};var ix=function(){return Math.random()},ox=function t(n){function e(t,e){return t=null==t?0:+t,e=null==e?1:+e,1===arguments.length?(e=t,t=0):e-=t,function(){return n()*e+t}}return e.source=t,e}(ix),ux=function t(n){function e(t,e){var r,i;return t=null==t?0:+t,e=null==e?1:+e,function(){var o;if(null!=r)o=r,r=null;else do{r=2*n()-1,o=2*n()-1,i=r*r+o*o}while(!i||i>1);return t+e*o*Math.sqrt(-2*Math.log(i)/i)}}return e.source=t,e}(ix),ax=function t(n){function e(){var t=ux.source(n).apply(this,arguments);return function(){return Math.exp(t())}}return e.source=t,e}(ix),cx=function t(n){function e(t){return function(){for(var e=0,r=0;r<t;++r)e+=n();return e}}return e.source=t,e}(ix),sx=function t(n){function e(t){var e=cx.source(n)(t);return function(){return e()/t}}return e.source=t,e}(ix),fx=function t(n){function e(t){return function(){return-Math.log(1-n())/t}}return e.source=t,e}(ix),lx=function(t,n){function e(t){var n,e=s.status;if(!e&&Pu(s)||e>=200&&e<300||304===e){if(o)try{n=o.call(r,s)}catch(t){return void a.call("error",r,t)}else n=s;a.call("load",r,n)}else a.call("error",r,t)}var r,i,o,u,a=g("beforesend","progress","load","error"),c=Xe(),s=new XMLHttpRequest,f=null,l=null,h=0;if("undefined"==typeof XDomainRequest||"withCredentials"in s||!/^(http(s)?:)?\/\//.test(t)||(s=new XDomainRequest),"onload"in s?s.onload=s.onerror=s.ontimeout=e:s.onreadystatechange=function(t){s.readyState>3&&e(t)},s.onprogress=function(t){a.call("progress",r,t)},r={header:function(t,n){return t=(t+"").toLowerCase(),arguments.length<2?c.get(t):(null==n?c.remove(t):c.set(t,n+""),r)},mimeType:function(t){return arguments.length?(i=null==t?null:t+"",r):i},responseType:function(t){return arguments.length?(u=t,r):u},timeout:function(t){return arguments.length?(h=+t,r):h},user:function(t){return arguments.length<1?f:(f=null==t?null:t+"",r)},password:function(t){return arguments.length<1?l:(l=null==t?null:t+"",r)},response:function(t){return o=t,r},get:function(t,n){return r.send("GET",t,n)},post:function(t,n){return r.send("POST",t,n)},send:function(n,e,o){return s.open(n,t,!0,f,l),null==i||c.has("accept")||c.set("accept",i+",*/*"),s.setRequestHeader&&c.each(function(t,n){s.setRequestHeader(n,t)}),null!=i&&s.overrideMimeType&&s.overrideMimeType(i),null!=u&&(s.responseType=u),h>0&&(s.timeout=h),null==o&&"function"==typeof e&&(o=e,e=null),null!=o&&1===o.length&&(o=zu(o)),null!=o&&r.on("error",o).on("load",function(t){o(null,t)}),a.call("beforesend",r,s),s.send(null==e?null:e),r},abort:function(){return s.abort(),r},on:function(){var t=a.on.apply(a,arguments);return t===a?r:t}},null!=n){if("function"!=typeof n)throw new Error("invalid callback: "+n);return r.get(n)}return r},hx=function(t,n){return function(e,r){var i=lx(e).mimeType(t).response(n);if(null!=r){if("function"!=typeof r)throw new Error("invalid callback: "+r);return i.get(r)}return i}},px=hx("text/html",function(t){return document.createRange().createContextualFragment(t.responseText)}),dx=hx("application/json",function(t){return JSON.parse(t.responseText)}),vx=hx("text/plain",function(t){return t.responseText}),gx=hx("application/xml",function(t){var n=t.responseXML;if(!n)throw new Error("parse error");return n}),yx=function(t,n){return function(e,r,i){arguments.length<3&&(i=r,r=null);var o=lx(e).mimeType(t);return o.row=function(t){return arguments.length?o.response(Ru(n,r=t)):r},o.row(r),i?o.get(i):o}},_x=yx("text/csv",Pv),mx=yx("text/tab-separated-values",Uv),xx=Array.prototype,bx=xx.map,wx=xx.slice,Mx={name:"implicit"},Tx=function(t){return function(){return t}},Nx=function(t){return+t},kx=[0,1],Sx=function(n,e,r){var o,u=n[0],a=n[n.length-1],c=i(u,a,null==e?10:e);switch(r=vr(null==r?",f":r),r.type){case"s":var s=Math.max(Math.abs(u),Math.abs(a));return null!=r.precision||isNaN(o=Ag(c,s))||(r.precision=o),t.formatPrefix(r,s);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(o=Eg(c,Math.max(Math.abs(u),Math.abs(a))))||(r.precision=o-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(o=Sg(c))||(r.precision=o-2*("%"===r.type))}return t.format(r)},Ax=function(t,n){t=t.slice();var e,r=0,i=t.length-1,o=t[r],u=t[i];return u<o&&(e=r,r=i,i=e,e=o,o=u,u=e),t[r]=n.floor(o),t[i]=n.ceil(u),t},Ex=new Date,Cx=new Date,zx=aa(function(){},function(t,n){t.setTime(+t+n)},function(t,n){return n-t});zx.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?aa(function(n){n.setTime(Math.floor(n/t)*t)},function(n,e){n.setTime(+n+e*t)},function(n,e){return(e-n)/t}):zx:null};var Px=zx.range,Rx=6e4,Lx=6048e5,Dx=aa(function(t){t.setTime(1e3*Math.floor(t/1e3))},function(t,n){t.setTime(+t+1e3*n)},function(t,n){return(n-t)/1e3},function(t){return t.getUTCSeconds()}),qx=Dx.range,Ux=aa(function(t){t.setTime(Math.floor(t/Rx)*Rx)},function(t,n){t.setTime(+t+n*Rx)},function(t,n){return(n-t)/Rx},function(t){return t.getMinutes()}),Ox=Ux.range,Fx=aa(function(t){var n=t.getTimezoneOffset()*Rx%36e5;n<0&&(n+=36e5),t.setTime(36e5*Math.floor((+t-n)/36e5)+n)},function(t,n){t.setTime(+t+36e5*n)},function(t,n){return(n-t)/36e5},function(t){return t.getHours()}),Yx=Fx.range,Ix=aa(function(t){t.setHours(0,0,0,0)},function(t,n){t.setDate(t.getDate()+n)},function(t,n){return(n-t-(n.getTimezoneOffset()-t.getTimezoneOffset())*Rx)/864e5},function(t){return t.getDate()-1}),Hx=Ix.range,Bx=ca(0),jx=ca(1),Xx=ca(2),Wx=ca(3),Vx=ca(4),$x=ca(5),Zx=ca(6),Gx=Bx.range,Qx=jx.range,Jx=Xx.range,Kx=Wx.range,tb=Vx.range,nb=$x.range,eb=Zx.range,rb=aa(function(t){t.setDate(1),t.setHours(0,0,0,0)},function(t,n){t.setMonth(t.getMonth()+n)},function(t,n){return n.getMonth()-t.getMonth()+12*(n.getFullYear()-t.getFullYear())},function(t){return t.getMonth()}),ib=rb.range,ob=aa(function(t){t.setMonth(0,1),t.setHours(0,0,0,0)},function(t,n){t.setFullYear(t.getFullYear()+n)},function(t,n){return n.getFullYear()-t.getFullYear()},function(t){return t.getFullYear()});ob.every=function(t){return isFinite(t=Math.floor(t))&&t>0?aa(function(n){n.setFullYear(Math.floor(n.getFullYear()/t)*t),n.setMonth(0,1),n.setHours(0,0,0,0)},function(n,e){n.setFullYear(n.getFullYear()+e*t)}):null};var ub=ob.range,ab=aa(function(t){t.setUTCSeconds(0,0)},function(t,n){t.setTime(+t+n*Rx)},function(t,n){return(n-t)/Rx},function(t){return t.getUTCMinutes()}),cb=ab.range,sb=aa(function(t){t.setUTCMinutes(0,0,0)},function(t,n){t.setTime(+t+36e5*n)},function(t,n){return(n-t)/36e5},function(t){return t.getUTCHours()}),fb=sb.range,lb=aa(function(t){t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCDate(t.getUTCDate()+n)},function(t,n){return(n-t)/864e5},function(t){return t.getUTCDate()-1}),hb=lb.range,pb=sa(0),db=sa(1),vb=sa(2),gb=sa(3),yb=sa(4),_b=sa(5),mb=sa(6),xb=pb.range,bb=db.range,wb=vb.range,Mb=gb.range,Tb=yb.range,Nb=_b.range,kb=mb.range,Sb=aa(function(t){t.setUTCDate(1),t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCMonth(t.getUTCMonth()+n)},function(t,n){return n.getUTCMonth()-t.getUTCMonth()+12*(n.getUTCFullYear()-t.getUTCFullYear())},function(t){return t.getUTCMonth()}),Ab=Sb.range,Eb=aa(function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCFullYear(t.getUTCFullYear()+n)},function(t,n){return n.getUTCFullYear()-t.getUTCFullYear()},function(t){return t.getUTCFullYear()});Eb.every=function(t){return isFinite(t=Math.floor(t))&&t>0?aa(function(n){n.setUTCFullYear(Math.floor(n.getUTCFullYear()/t)*t),n.setUTCMonth(0,1),n.setUTCHours(0,0,0,0)},function(n,e){n.setUTCFullYear(n.getUTCFullYear()+e*t)}):null};var Cb,zb=Eb.range,Pb={"-":"",_:" ",0:"0"},Rb=/^\s*\d+/,Lb=/^%/,Db=/[\\^$*+?|[\]().{}]/g;xc({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});var qb=Date.prototype.toISOString?bc:t.utcFormat("%Y-%m-%dT%H:%M:%S.%LZ"),Ub=+new Date("2000-01-01T00:00:00.000Z")?wc:t.utcParse("%Y-%m-%dT%H:%M:%S.%LZ"),Ob=1e3,Fb=60*Ob,Yb=60*Fb,Ib=24*Yb,Hb=7*Ib,Bb=30*Ib,jb=365*Ib,Xb=function(){return Nc(ob,rb,Bx,Ix,Fx,Ux,Dx,zx,t.timeFormat).domain([new Date(2e3,0,1),new Date(2e3,0,2)])},Wb=function(){return Nc(Eb,Sb,pb,lb,sb,ab,Dx,zx,t.utcFormat).domain([Date.UTC(2e3,0,1),Date.UTC(2e3,0,2)])},Vb=function(t){return t.match(/.{6}/g).map(function(t){return"#"+t})},$b=Vb("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf"),Zb=Vb("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6"),Gb=Vb("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9"),Qb=Vb("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5"),Jb=Sp(Gt(300,.5,0),Gt(-240,.5,1)),Kb=Sp(Gt(-100,.75,.35),Gt(80,1.5,.8)),tw=Sp(Gt(260,.75,.35),Gt(80,1.5,.8)),nw=Gt(),ew=function(t){(t<0||t>1)&&(t-=Math.floor(t));var n=Math.abs(t-.5);return nw.h=360*t-100,nw.s=1.5-1.5*n,nw.l=.8-.9*n,nw+""},rw=kc(Vb("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")),iw=kc(Vb("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),ow=kc(Vb("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),uw=kc(Vb("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")),aw=function(t){return function(){return t}},cw=Math.abs,sw=Math.atan2,fw=Math.cos,lw=Math.max,hw=Math.min,pw=Math.sin,dw=Math.sqrt,vw=1e-12,gw=Math.PI,yw=gw/2,_w=2*gw,mw=function(){function t(){var t,s,f=+n.apply(this,arguments),l=+e.apply(this,arguments),h=o.apply(this,arguments)-yw,p=u.apply(this,arguments)-yw,d=cw(p-h),v=p>h;if(c||(c=t=Oe()),l<f&&(s=l,l=f,f=s),l>vw)if(d>_w-vw)c.moveTo(l*fw(h),l*pw(h)),c.arc(0,0,l,h,p,!v),f>vw&&(c.moveTo(f*fw(p),f*pw(p)),c.arc(0,0,f,p,h,v));else{var g,y,_=h,m=p,x=h,b=p,w=d,M=d,T=a.apply(this,arguments)/2,N=T>vw&&(i?+i.apply(this,arguments):dw(f*f+l*l)),k=hw(cw(l-f)/2,+r.apply(this,arguments)),S=k,A=k;if(N>vw){var E=Ec(N/f*pw(T)),C=Ec(N/l*pw(T));(w-=2*E)>vw?(E*=v?1:-1,x+=E,b-=E):(w=0,x=b=(h+p)/2),(M-=2*C)>vw?(C*=v?1:-1,_+=C,m-=C):(M=0,_=m=(h+p)/2)}var z=l*fw(_),P=l*pw(_),R=f*fw(b),L=f*pw(b);if(k>vw){var D=l*fw(m),q=l*pw(m),U=f*fw(x),O=f*pw(x);if(d<gw){var F=w>vw?Dc(z,P,U,O,D,q,R,L):[R,L],Y=z-F[0],I=P-F[1],H=D-F[0],B=q-F[1],j=1/pw(Ac((Y*H+I*B)/(dw(Y*Y+I*I)*dw(H*H+B*B)))/2),X=dw(F[0]*F[0]+F[1]*F[1]);S=hw(k,(f-X)/(j-1)),A=hw(k,(l-X)/(j+1))}}M>vw?A>vw?(g=qc(U,O,z,P,l,A,v),y=qc(D,q,R,L,l,A,v),c.moveTo(g.cx+g.x01,g.cy+g.y01),A<k?c.arc(g.cx,g.cy,A,sw(g.y01,g.x01),sw(y.y01,y.x01),!v):(c.arc(g.cx,g.cy,A,sw(g.y01,g.x01),sw(g.y11,g.x11),!v),c.arc(0,0,l,sw(g.cy+g.y11,g.cx+g.x11),sw(y.cy+y.y11,y.cx+y.x11),!v),c.arc(y.cx,y.cy,A,sw(y.y11,y.x11),sw(y.y01,y.x01),!v))):(c.moveTo(z,P),c.arc(0,0,l,_,m,!v)):c.moveTo(z,P),f>vw&&w>vw?S>vw?(g=qc(R,L,D,q,f,-S,v),y=qc(z,P,U,O,f,-S,v),c.lineTo(g.cx+g.x01,g.cy+g.y01),S<k?c.arc(g.cx,g.cy,S,sw(g.y01,g.x01),sw(y.y01,y.x01),!v):(c.arc(g.cx,g.cy,S,sw(g.y01,g.x01),sw(g.y11,g.x11),!v),c.arc(0,0,f,sw(g.cy+g.y11,g.cx+g.x11),sw(y.cy+y.y11,y.cx+y.x11),v),c.arc(y.cx,y.cy,S,sw(y.y11,y.x11),sw(y.y01,y.x01),!v))):c.arc(0,0,f,b,x,v):c.lineTo(R,L)}else c.moveTo(0,0);if(c.closePath(),t)return c=null,t+""||null}var n=Cc,e=zc,r=aw(0),i=null,o=Pc,u=Rc,a=Lc,c=null;return t.centroid=function(){var t=(+n.apply(this,arguments)+ +e.apply(this,arguments))/2,r=(+o.apply(this,arguments)+ +u.apply(this,arguments))/2-gw/2;return[fw(r)*t,pw(r)*t]},t.innerRadius=function(e){return arguments.length?(n="function"==typeof e?e:aw(+e),t):n},t.outerRadius=function(n){return arguments.length?(e="function"==typeof n?n:aw(+n),t):e},t.cornerRadius=function(n){return arguments.length?(r="function"==typeof n?n:aw(+n),t):r},t.padRadius=function(n){return arguments.length?(i=null==n?null:"function"==typeof n?n:aw(+n),t):i},t.startAngle=function(n){return arguments.length?(o="function"==typeof n?n:aw(+n),t):o},t.endAngle=function(n){return arguments.length?(u="function"==typeof n?n:aw(+n),t):u},t.padAngle=function(n){return arguments.length?(a="function"==typeof n?n:aw(+n),t):a},t.context=function(n){return arguments.length?(c=null==n?null:n,t):c},t};Uc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;default:this._context.lineTo(t,n)}}};var xw=function(t){return new Uc(t)},bw=function(){function t(t){var a,c,s,f=t.length,l=!1;for(null==i&&(u=o(s=Oe())),a=0;a<=f;++a)!(a<f&&r(c=t[a],a,t))===l&&((l=!l)?u.lineStart():u.lineEnd()),l&&u.point(+n(c,a,t),+e(c,a,t));if(s)return u=null,s+""||null}var n=Oc,e=Fc,r=aw(!0),i=null,o=xw,u=null;return t.x=function(e){return arguments.length?(n="function"==typeof e?e:aw(+e),t):n},t.y=function(n){return arguments.length?(e="function"==typeof n?n:aw(+n),t):e},t.defined=function(n){return arguments.length?(r="function"==typeof n?n:aw(!!n),t):r},t.curve=function(n){return arguments.length?(o=n,null!=i&&(u=o(i)),t):o},t.context=function(n){return arguments.length?(null==n?i=u=null:u=o(i=n),t):i},t},ww=function(){function t(t){var n,f,l,h,p,d=t.length,v=!1,g=new Array(d),y=new Array(d);for(null==a&&(s=c(p=Oe())),n=0;n<=d;++n){if(!(n<d&&u(h=t[n],n,t))===v)if(v=!v)f=n,s.areaStart(),s.lineStart();else{for(s.lineEnd(),s.lineStart(),l=n-1;l>=f;--l)s.point(g[l],y[l]);s.lineEnd(),s.areaEnd()}v&&(g[n]=+e(h,n,t),y[n]=+i(h,n,t),s.point(r?+r(h,n,t):g[n],o?+o(h,n,t):y[n]))}if(p)return s=null,p+""||null}function n(){return bw().defined(u).curve(c).context(a)}var e=Oc,r=null,i=aw(0),o=Fc,u=aw(!0),a=null,c=xw,s=null;return t.x=function(n){return arguments.length?(e="function"==typeof n?n:aw(+n),r=null,t):e},t.x0=function(n){return arguments.length?(e="function"==typeof n?n:aw(+n),t):e},t.x1=function(n){return arguments.length?(r=null==n?null:"function"==typeof n?n:aw(+n),t):r},t.y=function(n){return arguments.length?(i="function"==typeof n?n:aw(+n),o=null,t):i},t.y0=function(n){return arguments.length?(i="function"==typeof n?n:aw(+n),t):i},t.y1=function(n){return arguments.length?(o=null==n?null:"function"==typeof n?n:aw(+n),t):o},t.lineX0=t.lineY0=function(){return n().x(e).y(i)},t.lineY1=function(){return n().x(e).y(o)},t.lineX1=function(){return n().x(r).y(i)},t.defined=function(n){return arguments.length?(u="function"==typeof n?n:aw(!!n),t):u},t.curve=function(n){return arguments.length?(c=n,null!=a&&(s=c(a)),t):c},t.context=function(n){return arguments.length?(null==n?a=s=null:s=c(a=n),t):a},t},Mw=function(t,n){return n<t?-1:n>t?1:n>=t?0:NaN},Tw=function(t){return t},Nw=function(){function t(t){var a,c,s,f,l,h=t.length,p=0,d=new Array(h),v=new Array(h),g=+i.apply(this,arguments),y=Math.min(_w,Math.max(-_w,o.apply(this,arguments)-g)),_=Math.min(Math.abs(y)/h,u.apply(this,arguments)),m=_*(y<0?-1:1);for(a=0;a<h;++a)(l=v[d[a]=a]=+n(t[a],a,t))>0&&(p+=l);for(null!=e?d.sort(function(t,n){return e(v[t],v[n])}):null!=r&&d.sort(function(n,e){return r(t[n],t[e])}),a=0,s=p?(y-h*m)/p:0;a<h;++a,g=f)c=d[a],l=v[c],f=g+(l>0?l*s:0)+m,v[c]={data:t[c],index:a,value:l,startAngle:g,endAngle:f,padAngle:_};return v}var n=Tw,e=Mw,r=null,i=aw(0),o=aw(_w),u=aw(0);return t.value=function(e){return arguments.length?(n="function"==typeof e?e:aw(+e),t):n},t.sortValues=function(n){return arguments.length?(e=n,r=null,t):e}, | |
t.sort=function(n){return arguments.length?(r=n,e=null,t):r},t.startAngle=function(n){return arguments.length?(i="function"==typeof n?n:aw(+n),t):i},t.endAngle=function(n){return arguments.length?(o="function"==typeof n?n:aw(+n),t):o},t.padAngle=function(n){return arguments.length?(u="function"==typeof n?n:aw(+n),t):u},t},kw=Ic(xw);Yc.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(t,n){this._curve.point(n*Math.sin(t),n*-Math.cos(t))}};var Sw=function(){return Hc(bw().curve(kw))},Aw=function(){var t=ww().curve(kw),n=t.curve,e=t.lineX0,r=t.lineX1,i=t.lineY0,o=t.lineY1;return t.angle=t.x,delete t.x,t.startAngle=t.x0,delete t.x0,t.endAngle=t.x1,delete t.x1,t.radius=t.y,delete t.y,t.innerRadius=t.y0,delete t.y0,t.outerRadius=t.y1,delete t.y1,t.lineStartAngle=function(){return Hc(e())},delete t.lineX0,t.lineEndAngle=function(){return Hc(r())},delete t.lineX1,t.lineInnerRadius=function(){return Hc(i())},delete t.lineY0,t.lineOuterRadius=function(){return Hc(o())},delete t.lineY1,t.curve=function(t){return arguments.length?n(Ic(t)):n()._curve},t},Ew=function(t,n){return[(n=+n)*Math.cos(t-=Math.PI/2),n*Math.sin(t)]},Cw=Array.prototype.slice,zw={draw:function(t,n){var e=Math.sqrt(n/gw);t.moveTo(e,0),t.arc(0,0,e,0,_w)}},Pw={draw:function(t,n){var e=Math.sqrt(n/5)/2;t.moveTo(-3*e,-e),t.lineTo(-e,-e),t.lineTo(-e,-3*e),t.lineTo(e,-3*e),t.lineTo(e,-e),t.lineTo(3*e,-e),t.lineTo(3*e,e),t.lineTo(e,e),t.lineTo(e,3*e),t.lineTo(-e,3*e),t.lineTo(-e,e),t.lineTo(-3*e,e),t.closePath()}},Rw=Math.sqrt(1/3),Lw=2*Rw,Dw={draw:function(t,n){var e=Math.sqrt(n/Lw),r=e*Rw;t.moveTo(0,-e),t.lineTo(r,0),t.lineTo(0,e),t.lineTo(-r,0),t.closePath()}},qw=Math.sin(gw/10)/Math.sin(7*gw/10),Uw=Math.sin(_w/10)*qw,Ow=-Math.cos(_w/10)*qw,Fw={draw:function(t,n){var e=Math.sqrt(.8908130915292852*n),r=Uw*e,i=Ow*e;t.moveTo(0,-e),t.lineTo(r,i);for(var o=1;o<5;++o){var u=_w*o/5,a=Math.cos(u),c=Math.sin(u);t.lineTo(c*e,-a*e),t.lineTo(a*r-c*i,c*r+a*i)}t.closePath()}},Yw={draw:function(t,n){var e=Math.sqrt(n),r=-e/2;t.rect(r,r,e,e)}},Iw=Math.sqrt(3),Hw={draw:function(t,n){var e=-Math.sqrt(n/(3*Iw));t.moveTo(0,2*e),t.lineTo(-Iw*e,-e),t.lineTo(Iw*e,-e),t.closePath()}},Bw=-.5,jw=Math.sqrt(3)/2,Xw=1/Math.sqrt(12),Ww=3*(Xw/2+1),Vw={draw:function(t,n){var e=Math.sqrt(n/Ww),r=e/2,i=e*Xw,o=r,u=e*Xw+e,a=-o,c=u;t.moveTo(r,i),t.lineTo(o,u),t.lineTo(a,c),t.lineTo(Bw*r-jw*i,jw*r+Bw*i),t.lineTo(Bw*o-jw*u,jw*o+Bw*u),t.lineTo(Bw*a-jw*c,jw*a+Bw*c),t.lineTo(Bw*r+jw*i,Bw*i-jw*r),t.lineTo(Bw*o+jw*u,Bw*u-jw*o),t.lineTo(Bw*a+jw*c,Bw*c-jw*a),t.closePath()}},$w=[zw,Pw,Dw,Yw,Fw,Hw,Vw],Zw=function(){function t(){var t;if(r||(r=t=Oe()),n.apply(this,arguments).draw(r,+e.apply(this,arguments)),t)return r=null,t+""||null}var n=aw(zw),e=aw(64),r=null;return t.type=function(e){return arguments.length?(n="function"==typeof e?e:aw(e),t):n},t.size=function(n){return arguments.length?(e="function"==typeof n?n:aw(+n),t):e},t.context=function(n){return arguments.length?(r=null==n?null:n,t):r},t},Gw=function(){};Kc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Jc(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Jc(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}};var Qw=function(t){return new Kc(t)};ts.prototype={areaStart:Gw,areaEnd:Gw,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._x2=t,this._y2=n;break;case 1:this._point=2,this._x3=t,this._y3=n;break;case 2:this._point=3,this._x4=t,this._y4=n,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+n)/6);break;default:Jc(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}};var Jw=function(t){return new ts(t)};ns.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var e=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+n)/6;this._line?this._context.lineTo(e,r):this._context.moveTo(e,r);break;case 3:this._point=4;default:Jc(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}};var Kw=function(t){return new ns(t)};es.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,n=this._y,e=t.length-1;if(e>0)for(var r,i=t[0],o=n[0],u=t[e]-i,a=n[e]-o,c=-1;++c<=e;)r=c/e,this._basis.point(this._beta*t[c]+(1-this._beta)*(i+r*u),this._beta*n[c]+(1-this._beta)*(o+r*a));this._x=this._y=null,this._basis.lineEnd()},point:function(t,n){this._x.push(+t),this._y.push(+n)}};var tM=function t(n){function e(t){return 1===n?new Kc(t):new es(t,n)}return e.beta=function(n){return t(+n)},e}(.85);is.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:rs(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2,this._x1=t,this._y1=n;break;case 2:this._point=3;default:rs(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var nM=function t(n){function e(t){return new is(t,n)}return e.tension=function(n){return t(+n)},e}(0);os.prototype={areaStart:Gw,areaEnd:Gw,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._x3=t,this._y3=n;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=n);break;case 2:this._point=3,this._x5=t,this._y5=n;break;default:rs(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var eM=function t(n){function e(t){return new os(t,n)}return e.tension=function(n){return t(+n)},e}(0);us.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:rs(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var rM=function t(n){function e(t){return new us(t,n)}return e.tension=function(n){return t(+n)},e}(0);cs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3;default:as(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var iM=function t(n){function e(t){return n?new cs(t,n):new is(t,0)}return e.alpha=function(n){return t(+n)},e}(.5);ss.prototype={areaStart:Gw,areaEnd:Gw,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=n;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=n);break;case 2:this._point=3,this._x5=t,this._y5=n;break;default:as(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var oM=function t(n){function e(t){return n?new ss(t,n):new os(t,0)}return e.alpha=function(n){return t(+n)},e}(.5);fs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:as(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var uM=function t(n){function e(t){return n?new fs(t,n):new us(t,0)}return e.alpha=function(n){return t(+n)},e}(.5);ls.prototype={areaStart:Gw,areaEnd:Gw,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,n){t=+t,n=+n,this._point?this._context.lineTo(t,n):(this._point=1,this._context.moveTo(t,n))}};var aM=function(t){return new ls(t)};gs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:vs(this,this._t0,ds(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){var e=NaN;if(t=+t,n=+n,t!==this._x1||n!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3,vs(this,ds(this,e=ps(this,t,n)),e);break;default:vs(this,this._t0,e=ps(this,t,n))}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n,this._t0=e}}},(ys.prototype=Object.create(gs.prototype)).point=function(t,n){gs.prototype.point.call(this,n,t)},_s.prototype={moveTo:function(t,n){this._context.moveTo(n,t)},closePath:function(){this._context.closePath()},lineTo:function(t,n){this._context.lineTo(n,t)},bezierCurveTo:function(t,n,e,r,i,o){this._context.bezierCurveTo(n,t,r,e,o,i)}},bs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,n=this._y,e=t.length;if(e)if(this._line?this._context.lineTo(t[0],n[0]):this._context.moveTo(t[0],n[0]),2===e)this._context.lineTo(t[1],n[1]);else for(var r=ws(t),i=ws(n),o=0,u=1;u<e;++o,++u)this._context.bezierCurveTo(r[0][o],i[0][o],r[1][o],i[1][o],t[u],n[u]);(this._line||0!==this._line&&1===e)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},point:function(t,n){this._x.push(+t),this._y.push(+n)}};var cM=function(t){return new bs(t)};Ms.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){0<this._t&&this._t<1&&2===this._point&&this._context.lineTo(this._x,this._y),(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line>=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,n),this._context.lineTo(t,n);else{var e=this._x*(1-this._t)+t*this._t;this._context.lineTo(e,this._y),this._context.lineTo(e,n)}}this._x=t,this._y=n}};var sM=function(t){return new Ms(t,.5)},fM=function(t,n){if((i=t.length)>1)for(var e,r,i,o=1,u=t[n[0]],a=u.length;o<i;++o)for(r=u,u=t[n[o]],e=0;e<a;++e)u[e][1]+=u[e][0]=isNaN(r[e][1])?r[e][0]:r[e][1]},lM=function(t){for(var n=t.length,e=new Array(n);--n>=0;)e[n]=n;return e},hM=function(){function t(t){var o,u,a=n.apply(this,arguments),c=t.length,s=a.length,f=new Array(s);for(o=0;o<s;++o){for(var l,h=a[o],p=f[o]=new Array(c),d=0;d<c;++d)p[d]=l=[0,+i(t[d],h,d,t)],l.data=t[d];p.key=h}for(o=0,u=e(f);o<s;++o)f[u[o]].index=o;return r(f,u),f}var n=aw([]),e=lM,r=fM,i=ks;return t.keys=function(e){return arguments.length?(n="function"==typeof e?e:aw(Cw.call(e)),t):n},t.value=function(n){return arguments.length?(i="function"==typeof n?n:aw(+n),t):i},t.order=function(n){return arguments.length?(e=null==n?lM:"function"==typeof n?n:aw(Cw.call(n)),t):e},t.offset=function(n){return arguments.length?(r=null==n?fM:n,t):r},t},pM=function(t,n){if((r=t.length)>0){for(var e,r,i,o=0,u=t[0].length;o<u;++o){for(i=e=0;e<r;++e)i+=t[e][o][1]||0;if(i)for(e=0;e<r;++e)t[e][o][1]/=i}fM(t,n)}},dM=function(t,n){if((a=t.length)>1)for(var e,r,i,o,u,a,c=0,s=t[n[0]].length;c<s;++c)for(o=u=0,e=0;e<a;++e)(i=(r=t[n[e]][c])[1]-r[0])>=0?(r[0]=o,r[1]=o+=i):i<0?(r[1]=u,r[0]=u+=i):r[0]=o},vM=function(t,n){if((e=t.length)>0){for(var e,r=0,i=t[n[0]],o=i.length;r<o;++r){for(var u=0,a=0;u<e;++u)a+=t[u][r][1]||0;i[r][1]+=i[r][0]=-a/2}fM(t,n)}},gM=function(t,n){if((i=t.length)>0&&(r=(e=t[n[0]]).length)>0){for(var e,r,i,o=0,u=1;u<r;++u){for(var a=0,c=0,s=0;a<i;++a){for(var f=t[n[a]],l=f[u][1]||0,h=f[u-1][1]||0,p=(l-h)/2,d=0;d<a;++d){var v=t[n[d]];p+=(v[u][1]||0)-(v[u-1][1]||0)}c+=l,s+=p*l}e[u-1][1]+=e[u-1][0]=o,c&&(o-=s/c)}e[u-1][1]+=e[u-1][0]=o,fM(t,n)}},yM=function(t){var n=t.map(Ss);return lM(t).sort(function(t,e){return n[t]-n[e]})},_M=function(t){return yM(t).reverse()},mM=function(t){var n,e,r=t.length,i=t.map(Ss),o=lM(t).sort(function(t,n){return i[n]-i[t]}),u=0,a=0,c=[],s=[];for(n=0;n<r;++n)e=o[n],u<a?(u+=i[e],c.push(e)):(a+=i[e],s.push(e));return s.reverse().concat(c)},xM=function(t){return lM(t).reverse()},bM=function(t){return function(){return t}};Cs.prototype={constructor:Cs,insert:function(t,n){var e,r,i;if(t){if(n.P=t,n.N=t.N,t.N&&(t.N.P=n),t.N=n,t.R){for(t=t.R;t.L;)t=t.L;t.L=n}else t.R=n;e=t}else this._?(t=Ls(this._),n.P=null,n.N=t,t.P=t.L=n,e=t):(n.P=n.N=null,this._=n,e=null);for(n.L=n.R=null,n.U=e,n.C=!0,t=n;e&&e.C;)r=e.U,e===r.L?(i=r.R,i&&i.C?(e.C=i.C=!1,r.C=!0,t=r):(t===e.R&&(Ps(this,e),t=e,e=t.U),e.C=!1,r.C=!0,Rs(this,r))):(i=r.L,i&&i.C?(e.C=i.C=!1,r.C=!0,t=r):(t===e.L&&(Rs(this,e),t=e,e=t.U),e.C=!1,r.C=!0,Ps(this,r))),e=t.U;this._.C=!1},remove:function(t){t.N&&(t.N.P=t.P),t.P&&(t.P.N=t.N),t.N=t.P=null;var n,e,r,i=t.U,o=t.L,u=t.R;if(e=o?u?Ls(u):o:u,i?i.L===t?i.L=e:i.R=e:this._=e,o&&u?(r=e.C,e.C=t.C,e.L=o,o.U=e,e!==u?(i=e.U,e.U=t.U,t=e.R,i.L=t,e.R=u,u.U=e):(e.U=i,i=e,t=e.R)):(r=t.C,t=e),t&&(t.U=i),!r){if(t&&t.C)return void(t.C=!1);do{if(t===this._)break;if(t===i.L){if(n=i.R,n.C&&(n.C=!1,i.C=!0,Ps(this,i),n=i.R),n.L&&n.L.C||n.R&&n.R.C){n.R&&n.R.C||(n.L.C=!1,n.C=!0,Rs(this,n),n=i.R),n.C=i.C,i.C=n.R.C=!1,Ps(this,i),t=this._;break}}else if(n=i.L,n.C&&(n.C=!1,i.C=!0,Rs(this,i),n=i.L),n.L&&n.L.C||n.R&&n.R.C){n.L&&n.L.C||(n.R.C=!1,n.C=!0,Ps(this,n),n=i.L),n.C=i.C,i.C=n.L.C=!1,Rs(this,i),t=this._;break}n.C=!0,t=i,i=i.U}while(!t.C);t&&(t.C=!1)}}};var wM,MM,TM,NM,kM,SM=[],AM=[],EM=1e-6,CM=1e-12;uf.prototype={constructor:uf,polygons:function(){var t=this.edges;return this.cells.map(function(n){var e=n.halfedges.map(function(e){return Bs(n,t[e])});return e.data=n.site.data,e})},triangles:function(){var t=[],n=this.edges;return this.cells.forEach(function(e,r){if(o=(i=e.halfedges).length)for(var i,o,u,a=e.site,c=-1,s=n[i[o-1]],f=s.left===a?s.right:s.left;++c<o;)u=f,s=n[i[c]],f=s.left===a?s.right:s.left,u&&f&&r<u.index&&r<f.index&&rf(a,u,f)<0&&t.push([a.data,u.data,f.data])}),t},links:function(){return this.edges.filter(function(t){return t.right}).map(function(t){return{source:t.left.data,target:t.right.data}})},find:function(t,n,e){for(var r,i,o=this,u=o._found||0,a=o.cells.length;!(i=o.cells[u]);)if(++u>=a)return null;var c=t-i.site[0],s=n-i.site[1],f=c*c+s*s;do{i=o.cells[r=u],u=null,i.halfedges.forEach(function(e){var r=o.edges[e],a=r.left;if(a!==i.site&&a||(a=r.right)){var c=t-a[0],s=n-a[1],l=c*c+s*s;l<f&&(f=l,u=a.index)}})}while(null!==u);return o._found=r,null==e||f<=e*e?i.site:null}};var zM=function(){function t(t){return new uf(t.map(function(r,i){var o=[Math.round(n(r,i,t)/EM)*EM,Math.round(e(r,i,t)/EM)*EM];return o.index=i,o.data=r,o}),r)}var n=As,e=Es,r=null;return t.polygons=function(n){return t(n).polygons()},t.links=function(n){return t(n).links()},t.triangles=function(n){return t(n).triangles()},t.x=function(e){return arguments.length?(n="function"==typeof e?e:bM(+e),t):n},t.y=function(n){return arguments.length?(e="function"==typeof n?n:bM(+n),t):e},t.extent=function(n){return arguments.length?(r=null==n?null:[[+n[0][0],+n[0][1]],[+n[1][0],+n[1][1]]],t):r&&[[r[0][0],r[0][1]],[r[1][0],r[1][1]]]},t.size=function(n){return arguments.length?(r=null==n?null:[[0,0],[+n[0],+n[1]]],t):r&&[r[1][0]-r[0][0],r[1][1]-r[0][1]]},t},PM=function(t){return function(){return t}};cf.prototype={constructor:cf,scale:function(t){return 1===t?this:new cf(this.k*t,this.x,this.y)},translate:function(t,n){return 0===t&0===n?this:new cf(this.k,this.x+this.k*t,this.y+this.k*n)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var RM=new cf(1,0,0);sf.prototype=cf.prototype;var LM=function(){t.event.preventDefault(),t.event.stopImmediatePropagation()},DM=function(){function n(t){t.property("__zoom",pf).on("wheel.zoom",c).on("mousedown.zoom",s).on("dblclick.zoom",f).filter(b).on("touchstart.zoom",l).on("touchmove.zoom",h).on("touchend.zoom touchcancel.zoom",p).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function e(t,n){return n=Math.max(w[0],Math.min(w[1],n)),n===t.k?t:new cf(n,t.x,t.y)}function r(t,n,e){var r=n[0]-e[0]*t.k,i=n[1]-e[1]*t.k;return r===t.x&&i===t.y?t:new cf(t.k,r,i)}function i(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function o(t,n,e){t.on("start.zoom",function(){u(this,arguments).start()}).on("interrupt.zoom end.zoom",function(){u(this,arguments).end()}).tween("zoom",function(){var t=this,r=arguments,o=u(t,r),a=_.apply(t,r),c=e||i(a),s=Math.max(a[1][0]-a[0][0],a[1][1]-a[0][1]),f=t.__zoom,l="function"==typeof n?n.apply(t,r):n,h=N(f.invert(c).concat(s/f.k),l.invert(c).concat(s/l.k));return function(t){if(1===t)t=l;else{var n=h(t),e=s/n[2];t=new cf(e,c[0]-n[0]*e,c[1]-n[1]*e)}o.zoom(null,t)}})}function u(t,n){for(var e,r=0,i=k.length;r<i;++r)if((e=k[r]).that===t)return e;return new a(t,n)}function a(t,n){this.that=t,this.args=n,this.index=-1,this.active=0,this.extent=_.apply(t,n)}function c(){function t(){n.wheel=null,n.end()}if(y.apply(this,arguments)){var n=u(this,arguments),i=this.__zoom,o=Math.max(w[0],Math.min(w[1],i.k*Math.pow(2,x.apply(this,arguments)))),a=Al(this);if(n.wheel)n.mouse[0][0]===a[0]&&n.mouse[0][1]===a[1]||(n.mouse[1]=i.invert(n.mouse[0]=a)),clearTimeout(n.wheel);else{if(i.k===o)return;n.mouse=[a,i.invert(a)],Gp(this),n.start()}LM(),n.wheel=setTimeout(t,E),n.zoom("mouse",m(r(e(i,o),n.mouse[0],n.mouse[1]),n.extent,M))}}function s(){function n(){if(LM(),!i.moved){var n=t.event.clientX-c,e=t.event.clientY-s;i.moved=n*n+e*e>z}i.zoom("mouse",m(r(i.that.__zoom,i.mouse[0]=Al(i.that),i.mouse[1]),i.extent,M))}function e(){o.on("mousemove.zoom mouseup.zoom",null),xt(t.event.view,i.moved),LM(),i.end()}if(!v&&y.apply(this,arguments)){var i=u(this,arguments),o=fh(t.event.view).on("mousemove.zoom",n,!0).on("mouseup.zoom",e,!0),a=Al(this),c=t.event.clientX,s=t.event.clientY;vh(t.event.view),ff(),i.mouse=[a,this.__zoom.invert(a)],Gp(this),i.start()}}function f(){if(y.apply(this,arguments)){var i=this.__zoom,u=Al(this),a=i.invert(u),c=i.k*(t.event.shiftKey?.5:2),s=m(r(e(i,c),u,a),_.apply(this,arguments),M);LM(),T>0?fh(this).transition().duration(T).call(o,s,u):fh(this).call(n.transform,s)}}function l(){if(y.apply(this,arguments)){var n,e,r,i,o=u(this,arguments),a=t.event.changedTouches,c=a.length;for(ff(),e=0;e<c;++e)r=a[e],i=hh(this,a,r.identifier),i=[i,this.__zoom.invert(i),r.identifier],o.touch0?o.touch1||(o.touch1=i):(o.touch0=i,n=!0);if(d&&(d=clearTimeout(d),!o.touch1))return o.end(),void((i=fh(this).on("dblclick.zoom"))&&i.apply(this,arguments));n&&(d=setTimeout(function(){d=null},A),Gp(this),o.start())}}function h(){var n,i,o,a,c=u(this,arguments),s=t.event.changedTouches,f=s.length;for(LM(),d&&(d=clearTimeout(d)),n=0;n<f;++n)i=s[n],o=hh(this,s,i.identifier),c.touch0&&c.touch0[2]===i.identifier?c.touch0[0]=o:c.touch1&&c.touch1[2]===i.identifier&&(c.touch1[0]=o);if(i=c.that.__zoom,c.touch1){var l=c.touch0[0],h=c.touch0[1],p=c.touch1[0],v=c.touch1[1],g=(g=p[0]-l[0])*g+(g=p[1]-l[1])*g,y=(y=v[0]-h[0])*y+(y=v[1]-h[1])*y;i=e(i,Math.sqrt(g/y)),o=[(l[0]+p[0])/2,(l[1]+p[1])/2],a=[(h[0]+v[0])/2,(h[1]+v[1])/2]}else{if(!c.touch0)return;o=c.touch0[0],a=c.touch0[1]}c.zoom("touch",m(r(i,o,a),c.extent,M))}function p(){var n,e,r=u(this,arguments),i=t.event.changedTouches,o=i.length;for(ff(),v&&clearTimeout(v),v=setTimeout(function(){v=null},A),n=0;n<o;++n)e=i[n],r.touch0&&r.touch0[2]===e.identifier?delete r.touch0:r.touch1&&r.touch1[2]===e.identifier&&delete r.touch1;r.touch1&&!r.touch0&&(r.touch0=r.touch1,delete r.touch1),r.touch0?r.touch0[1]=this.__zoom.invert(r.touch0[0]):r.end()}var d,v,y=lf,_=hf,m=gf,x=df,b=vf,w=[0,1/0],M=[[-1/0,-1/0],[1/0,1/0]],T=250,N=bp,k=[],S=g("start","zoom","end"),A=500,E=150,z=0;return n.transform=function(t,n){var e=t.selection?t.selection():t;e.property("__zoom",pf),t!==e?o(t,n):e.interrupt().each(function(){u(this,arguments).start().zoom(null,"function"==typeof n?n.apply(this,arguments):n).end()})},n.scaleBy=function(t,e){n.scaleTo(t,function(){return this.__zoom.k*("function"==typeof e?e.apply(this,arguments):e)})},n.scaleTo=function(t,o){n.transform(t,function(){var t=_.apply(this,arguments),n=this.__zoom,u=i(t),a=n.invert(u),c="function"==typeof o?o.apply(this,arguments):o;return m(r(e(n,c),u,a),t,M)})},n.translateBy=function(t,e,r){n.transform(t,function(){return m(this.__zoom.translate("function"==typeof e?e.apply(this,arguments):e,"function"==typeof r?r.apply(this,arguments):r),_.apply(this,arguments),M)})},n.translateTo=function(t,e,r){n.transform(t,function(){var t=_.apply(this,arguments),n=this.__zoom,o=i(t);return m(RM.translate(o[0],o[1]).scale(n.k).translate("function"==typeof e?-e.apply(this,arguments):-e,"function"==typeof r?-r.apply(this,arguments):-r),t,M)})},a.prototype={start:function(){return 1==++this.active&&(this.index=k.push(this)-1,this.emit("start")),this},zoom:function(t,n){return this.mouse&&"mouse"!==t&&(this.mouse[1]=n.invert(this.mouse[0])),this.touch0&&"touch"!==t&&(this.touch0[1]=n.invert(this.touch0[0])),this.touch1&&"touch"!==t&&(this.touch1[1]=n.invert(this.touch1[0])),this.that.__zoom=n,this.emit("zoom"),this},end:function(){return 0==--this.active&&(k.splice(this.index,1),this.index=-1,this.emit("end")),this},emit:function(t){C(new af(n,t,this.that.__zoom),S.apply,S,[t,this.that,this.args])}},n.wheelDelta=function(t){return arguments.length?(x="function"==typeof t?t:PM(+t),n):x},n.filter=function(t){return arguments.length?(y="function"==typeof t?t:PM(!!t),n):y},n.touchable=function(t){return arguments.length?(b="function"==typeof t?t:PM(!!t),n):b},n.extent=function(t){return arguments.length?(_="function"==typeof t?t:PM([[+t[0][0],+t[0][1]],[+t[1][0],+t[1][1]]]),n):_},n.scaleExtent=function(t){return arguments.length?(w[0]=+t[0],w[1]=+t[1],n):[w[0],w[1]]},n.translateExtent=function(t){return arguments.length?(M[0][0]=+t[0][0],M[1][0]=+t[1][0],M[0][1]=+t[0][1],M[1][1]=+t[1][1],n):[[M[0][0],M[0][1]],[M[1][0],M[1][1]]]},n.constrain=function(t){return arguments.length?(m=t,n):m},n.duration=function(t){return arguments.length?(T=+t,n):T},n.interpolate=function(t){return arguments.length?(N=t,n):N},n.on=function(){var t=S.on.apply(S,arguments);return t===S?n:t},n.clickDistance=function(t){return arguments.length?(z=(t=+t)*t,n):Math.sqrt(z)},n},qM=function(t,n){var e=this.node();return e?e.getBBox?this.attr("transform",function(e,r){var i="function"==typeof t?t.call(this,e,r):t;return 0===n?i=[i,0]:1===n&&(i=[0,i]),"translate("+i[0]+","+i[1]+")"}):this.style("transform",function(e,r){var i="function"==typeof t?t.call(this,e,r):t;return 0===n?i=[i,0]:1===n&&(i=[0,i]),"translate("+i[0]+"px,"+i[1]+"px)"}):this},UM=function(t){if("string"==typeof t){var n,e={},r=t.split(/([\.#])/g);for(t=r.shift();n=r.shift();)"."==n?e.class=e.class?e.class+" "+r.shift():r.shift():"#"==n&&(e.id=r.shift());return{tag:t,attr:e}}return t},OM=function(t){var n,e;"function"==typeof t?n=t:(e=UM(t),n=_l(e.tag));var r=this.select(function(){return this.appendChild(n.apply(this,arguments))});if(e)for(var i in e.attr)r.attr(i,e.attr[i]);return r},FM=function(t,n){var e=UM(t),r=_l(e.tag),i=null==n?yf:"function"==typeof n?n:El(n),o=this.select(function(){return this.insertBefore(r.apply(this,arguments),i.apply(this,arguments)||null)});for(var u in e.attr)o.attr(u,e.attr[u]);return o},YM=function(){var t=[];return this.filter(function(){return!(t.indexOf(this.parentNode)>-1)&&(t.push(this.parentNode),!0)}).select(function(){return this.parentNode})},IM=function(t){var n,e=El(t),r=UM(t);t=_l(r.tag),n=this.select(function(){return e.apply(this,arguments)||this.appendChild(t.apply(this,arguments))});for(var i in r.attr)n.attr(i,r.attr[i]);return n},HM=function(t,n){return this.selectAll("tspan").data(function(n){return("function"==typeof t?t(n):t).map(function(t){return{line:t,parent:n}})}).enter().append("tspan").text(function(t){return t.line}).attr("x",0).attr("dy",function(t,e){return e?("function"==typeof n?n(t.parent,t.line,e):n)||15:0})},BM=function(t,n){if("string"==typeof n){console.warn("DEPRECATED: jetpack's appendMany order of arguments has changed. It's appendMany('div', data) from now on");var e=n;n=t,t=e}return this.selectAll(null).data(n).enter().append(t)},jM=function(t,n){if("object"==typeof t){for(var e in t)this.attr(e.replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase(),t[e]);return this}return 1==arguments.length?this.attr(t):this.attr(t,n)};_f.not=function(t){return!t},_f.run=function(t){return t()},_f.objToFn=function(t,n){return 1==arguments.length&&(n=void 0),function(e){return void 0!==t[e]?t[e]:n}};var XM=function(t,n){function e(t,n,e){return n=n.replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase(),~"top left bottom right padding-top padding-left padding-bottom padding-right border-top b-width border-left-width border-botto-width m border-right-width margin-top margin-left margin-bottom margin-right font-size width height stroke-width line-height margin padding border border-radius max-width min-width".indexOf(n)?t.style(n,"function"==typeof e?i(e):r(e)):t.style(n,e),t}function r(t){return t.match?t:t+"px"}function i(t){return function(){return r(t.apply(this,arguments))}}if("object"==typeof t){for(var o in t)e(this,o,t[o]);return this}return 1==arguments.length?this.style(t):e(this,t,n)},WM={A:7,a:7,B:8,b:7,C:8,c:6,D:9,d:7,E:7,e:7,F:7,f:4,G:9,g:7,H:9,h:7,I:3,i:3,J:5,j:3,K:8,k:6,L:7,l:3,M:11,m:11,N:9,n:7,O:9,o:7,P:8,p:7,Q:9,q:7,R:8,r:4,S:8,s:6,T:7,t:4,U:9,u:7,V:7,v:6,W:11,w:9,X:7,x:6,Y:7,y:6,Z:7,z:5,".":2,",":2,":":2,";":2},VM=function(t,n,e,r){function i(t){return!r&&WM[t]||WM.a}function o(t){return t.length}function u(t,n){return t-n}var a,c,s,f,l,h,p=[],d=[],v=[];return c=t.split(" "),c.forEach(function(t,n){var e=t.split("-");e.length>1?e.forEach(function(t,n){d.push(t+(n<e.length-1?"-":""))}):d.push(t+(n<c.length-1?" ":""))}),s=n||40,f=e||Math.max(3,Math.min(.5*s,.75*d.map(o).sort(u)[Math.round(d.length/2)])),l=s*WM.a,h=f*WM.a,a=0,d.forEach(function(t){var n=il(t.split("").map(i));return a+n>l&&a>h&&(p.push(v.join("")),v.length=0,a=0),a+=n,v.push(t)}),v.length&&p.push(v.join("")),p.filter(function(t){return""!==t})},$M=function(t){return"function"==typeof t?function(n,e){return t(n)<t(e)?-1:t(n)>t(e)?1:t(n)>=t(e)?0:NaN}:function(n,e){return n[t]<e[t]?-1:n[t]>e[t]?1:n[t]>=e[t]?0:NaN}},ZM=function(t){return"function"==typeof t?function(n,e){return t(e)<t(n)?-1:t(e)>t(n)?1:t(e)>=t(n)?0:NaN}:function(n,e){return e[t]<n[t]?-1:e[t]>n[t]?1:e[t]>=n[t]?0:NaN}},GM=function(t){t=t||{},t.margin=t.margin||{},["top","right","bottom","left"].forEach(function(n){t.margin[n]||0===t.margin[n]||(t.margin[n]=20)}),t.parentSel&&(t.sel=t.parentSel);var n=t.sel&&t.sel.node();return t.totalWidth=t.totalWidth||n&&n.offsetWidth||960,t.totalHeight=t.totalHeight||n&&n.offsetHeight||500,t.width=t.width||t.totalWidth-t.margin.left-t.margin.right,t.height=t.height||t.totalHeight-t.margin.top-t.margin.bottom, | |
t.totalWidth=t.width+t.margin.left+t.margin.right,t.totalHeight=t.height+t.margin.top+t.margin.bottom,t.sel=t.sel||fh("body"),t.sel.st({position:"relative",height:t.totalHeight,width:t.totalWidth}),t.x=t.x||Wu().range([0,t.width]),t.y=t.y||Wu().range([t.height,0]),t.xAxis=t.xAxis||d().scale(t.x),t.yAxis=t.yAxis||v().scale(t.y),t.layers=(t.layers||"s").split("").map(function(n){var e;if("s"==n)e=t.sel.append("svg").st({position:t.layers?"absolute":""}).attr("width",t.totalWidth).attr("height",t.totalHeight).append("g").attr("transform","translate("+t.margin.left+","+t.margin.top+")"),t.svg||(t.svg=e);else if("c"==n){var r=window.devicePixelRatio||1;e=t.sel.append("canvas").at({width:t.totalWidth*r,height:t.totalHeight*r}).st({width:t.totalWidth,height:t.totalHeight}).st({position:"absolute"}).node().getContext("2d"),e.scale(r,r),e.translate(t.margin.left,t.margin.top)}else"d"==n&&(e=t.sel.append("div").st({position:"absolute",left:t.margin.left,top:t.margin.top,width:t.width,height:t.height}));return e}),t},QM=function(t){return{xAxisSel:t.svg.append("g").attr("class","x axis").attr("transform","translate(0,"+t.height+")").call(t.xAxis),yAxisSel:t.svg.append("g").attr("class","y axis").call(t.yAxis)}},JM=function(t,n,e){return Math.max(t,Math.min(e,n))},KM=function(n,e,r){function i(t){e.classed("tooltip-hidden",!1).html("").appendMany("div",r).html(function(n){return n(t)}),fh(this).classed("tooltipped",!0)}function o(n){if(e.size()){var r=t.event,i=r.clientX,o=r.clientY,u=e.node().getBoundingClientRect(),a=JM(20,i-u.width/2,window.innerWidth-u.width-20),c=innerHeight>o+20+u.height?o+20:o-u.height-20;e.style("left",a+"px").style("top",c+"px")}}function u(t){e.classed("tooltip-hidden",!0),lh(".tooltipped").classed("tooltipped",!1)}if(n.size()){e=e||fh(".tooltip"),n.on("mouseover.attachTooltip",i).on("mousemove.attachTooltip",o).on("mouseout.attachTooltip",u).on("click.attachTooltip",function(t){console.log(t)});var a=n.datum();r=r||wv(a).filter(function(t){return"object"!=typeof a[t]&&"array"!=a[t]}).map(function(t){return function(n){return t+": <b>"+n[t]+"</b>"}})}},tT=function(){var t=Cu(),n=[].slice.call(arguments),e=n.slice(0,n.length-1),r=n[n.length-1];e.forEach(function(n){var e=n.split("?")[0].split(".").reverse()[0],i={csv:_x,tsv:mx,json:dx}[e];if(!i)return r(new Error("Invalid type",n));t.defer(i,n)}),t.awaitAll(r)},nT=function(t,n){return xv().key(n).entries(t).map(function(t){return t.values.key=t.key,t.values})},eT=function(t,n){return n?Math.round(t*(n=Math.pow(10,n)))/n:Math.round(t)},rT=function(t,n){for(var e,r,i,o,u,a,c=bf(n),s=-1,f=t.length-bf(t),l=t[f-1];++s<f;){for(e=n.slice(),n.length=0,o=t[s],u=e[(i=e.length-c)-1],r=-1;++r<i;)a=e[r],mf(a,l,o)?(mf(u,l,o)||n.push(xf(u,a,l,o)),n.push(a)):mf(u,l,o)&&n.push(xf(u,a,l,o)),u=a;c&&n.push(n[0]),l=o}return n};_t.prototype.translate=qM,ie.prototype.translate=qM,_t.prototype.append=OM,_t.prototype.insert=FM,_t.prototype.parent=YM,_t.prototype.selectAppend=IM,_t.prototype.tspans=HM,_t.prototype.appendMany=BM,_t.prototype.at=jM,_t.prototype.st=XM,ie.prototype.at=jM,ie.prototype.st=XM,_t.prototype.prop=_t.prototype.property,xc({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan.","Feb.","March","April","May","June","July","Aug.","Sept.","Oct.","Nov.","Dec."]}),t.version="4.12.0",t.bisect=kf,t.bisectRight=kf,t.bisectLeft=Sf,t.ascending=Mf,t.bisector=Tf,t.cross=Ef,t.descending=Cf,t.deviation=Rf,t.extent=Lf,t.histogram=Wf,t.thresholdFreedmanDiaconis=$f,t.thresholdScott=Zf,t.thresholdSturges=Xf,t.max=Gf,t.mean=Qf,t.median=Jf,t.merge=Kf,t.min=tl,t.pairs=Af,t.permute=nl,t.quantile=Vf,t.range=Yf,t.scan=el,t.shuffle=rl,t.sum=il,t.ticks=jf,t.tickIncrement=r,t.tickStep=i,t.transpose=ol,t.variance=Pf,t.zip=ul,t.axisTop=h,t.axisRight=p,t.axisBottom=d,t.axisLeft=v,t.brush=uv,t.brushX=Re,t.brushY=Le,t.brushSelection=Pe,t.chord=pv,t.ribbon=mv,t.nest=xv,t.set=Qe,t.map=Xe,t.keys=wv,t.values=Mv,t.entries=Tv,t.color=At,t.rgb=Pt,t.hsl=qt,t.lab=Yt,t.hcl=Vt,t.cubehelix=Gt,t.dispatch=g,t.drag=yh,t.dragDisable=vh,t.dragEnable=xt,t.dsvFormat=Cv,t.csvParse=Pv,t.csvParseRows=Rv,t.csvFormat=Lv,t.csvFormatRows=Dv,t.tsvParse=Uv,t.tsvParseRows=Ov,t.tsvFormat=Fv,t.tsvFormatRows=Yv,t.easeLinear=ue,t.easeQuad=se,t.easeQuadIn=ae,t.easeQuadOut=ce,t.easeQuadInOut=se,t.easeCubic=he,t.easeCubicIn=fe,t.easeCubicOut=le,t.easeCubicInOut=he,t.easePoly=bd,t.easePolyIn=md,t.easePolyOut=xd,t.easePolyInOut=bd,t.easeSin=ve,t.easeSinIn=pe,t.easeSinOut=de,t.easeSinInOut=ve,t.easeExp=_e,t.easeExpIn=ge,t.easeExpOut=ye,t.easeExpInOut=_e,t.easeCircle=be,t.easeCircleIn=me,t.easeCircleOut=xe,t.easeCircleInOut=be,t.easeBounce=Me,t.easeBounceIn=we,t.easeBounceOut=Me,t.easeBounceInOut=Te,t.easeBack=qd,t.easeBackIn=Ld,t.easeBackOut=Dd,t.easeBackInOut=qd,t.easeElastic=Fd,t.easeElasticIn=Od,t.easeElasticOut=Fd,t.easeElasticInOut=Yd,t.forceCenter=Iv,t.forceCollide=og,t.forceLink=ug,t.forceManyBody=fg,t.forceRadial=lg,t.forceSimulation=sg,t.forceX=hg,t.forceY=pg,t.formatDefaultLocale=yr,t.formatLocale=kg,t.formatSpecifier=vr,t.precisionFixed=Sg,t.precisionPrefix=Ag,t.precisionRound=Eg,t.geoArea=Ly,t.geoBounds=Uy,t.geoCentroid=Fy,t.geoCircle=t_,t.geoClipAntimeridian=a_,t.geoClipCircle=c_,t.geoClipExtent=h_,t.geoClipRectangle=_i,t.geoContains=b_,t.geoDistance=__,t.geoGraticule=zi,t.geoGraticule10=Pi,t.geoInterpolate=w_,t.geoLength=v_,t.geoPath=Z_,t.geoAlbers=em,t.geoAlbersUsa=rm,t.geoAzimuthalEqualArea=om,t.geoAzimuthalEqualAreaRaw=im,t.geoAzimuthalEquidistant=am,t.geoAzimuthalEquidistantRaw=um,t.geoConicConformal=sm,t.geoConicConformalRaw=xo,t.geoConicEqualArea=nm,t.geoConicEqualAreaRaw=ho,t.geoConicEquidistant=lm,t.geoConicEquidistantRaw=wo,t.geoEquirectangular=fm,t.geoEquirectangularRaw=bo,t.geoGnomonic=hm,t.geoGnomonicRaw=Mo,t.geoIdentity=pm,t.geoProjection=co,t.geoProjectionMutator=so,t.geoMercator=cm,t.geoMercatorRaw=yo,t.geoNaturalEarth1=dm,t.geoNaturalEarth1Raw=No,t.geoOrthographic=vm,t.geoOrthographicRaw=ko,t.geoStereographic=gm,t.geoStereographicRaw=So,t.geoTransverseMercator=ym,t.geoTransverseMercatorRaw=Ao,t.geoRotation=Ky,t.geoStream=Cy,t.geoTransform=G_,t.cluster=_m,t.hierarchy=Oo,t.pack=Lm,t.packSiblings=Pm,t.packEnclose=zm,t.partition=Um,t.stratify=Im,t.tree=Hm,t.treemap=Wm,t.treemapBinary=Vm,t.treemapDice=qm,t.treemapSlice=Bm,t.treemapSliceDice=$m,t.treemapSquarify=Xm,t.treemapResquarify=Zm,t.interpolate=pp,t.interpolateArray=up,t.interpolateBasis=tp,t.interpolateBasisClosed=np,t.interpolateDate=ap,t.interpolateNumber=cp,t.interpolateObject=sp,t.interpolateRound=dp,t.interpolateString=hp,t.interpolateTransformCss=_p,t.interpolateTransformSvg=mp,t.interpolateZoom=bp,t.interpolateRgb=rp,t.interpolateRgbBasis=ip,t.interpolateRgbBasisClosed=op,t.interpolateHsl=wp,t.interpolateHslLong=Mp,t.interpolateLab=vn,t.interpolateHcl=Tp;t.interpolateHclLong=Np,t.interpolateCubehelix=kp,t.interpolateCubehelixLong=Sp,t.quantize=Ap,t.path=Oe,t.polygonArea=Gm,t.polygonCentroid=Qm,t.polygonHull=Km,t.polygonContains=tx,t.polygonLength=nx,t.quadtree=ur,t.queue=Cu,t.randomUniform=ox,t.randomNormal=ux,t.randomLogNormal=ax,t.randomBates=sx,t.randomIrwinHall=cx,t.randomExponential=fx,t.request=lx,t.html=px,t.json=dx,t.text=vx,t.xml=gx,t.csv=_x,t.tsv=mx,t.scaleBand=Du,t.scalePoint=Uu,t.scaleIdentity=Vu,t.scaleLinear=Wu,t.scaleLog=ta,t.scaleOrdinal=Lu,t.scaleImplicit=Mx,t.scalePow=ea,t.scaleSqrt=ra,t.scaleQuantile=ia,t.scaleQuantize=oa,t.scaleThreshold=ua,t.scaleTime=Xb,t.scaleUtc=Wb,t.schemeCategory10=$b,t.schemeCategory20b=Zb,t.schemeCategory20c=Gb,t.schemeCategory20=Qb,t.interpolateCubehelixDefault=Jb,t.interpolateRainbow=ew,t.interpolateWarm=Kb,t.interpolateCool=tw,t.interpolateViridis=rw,t.interpolateMagma=iw,t.interpolateInferno=ow,t.interpolatePlasma=uw,t.scaleSequential=Sc,t.creator=_l,t.local=M,t.matcher=Ml,t.mouse=Al,t.namespace=yl,t.namespaces=gl,t.clientPoint=Sl,t.select=fh,t.selectAll=lh,t.selection=_t,t.selector=El,t.selectorAll=zl,t.style=W,t.touch=hh,t.touches=ph,t.window=Gl,t.customEvent=C,t.arc=mw,t.area=ww,t.line=bw,t.pie=Nw,t.areaRadial=Aw,t.radialArea=Aw,t.lineRadial=Sw,t.radialLine=Sw,t.pointRadial=Ew,t.linkHorizontal=Zc,t.linkVertical=Gc,t.linkRadial=Qc,t.symbol=Zw,t.symbols=$w,t.symbolCircle=zw,t.symbolCross=Pw,t.symbolDiamond=Dw,t.symbolSquare=Yw,t.symbolStar=Fw,t.symbolTriangle=Hw,t.symbolWye=Vw,t.curveBasisClosed=Jw,t.curveBasisOpen=Kw,t.curveBasis=Qw,t.curveBundle=tM,t.curveCardinalClosed=eM,t.curveCardinalOpen=rM,t.curveCardinal=nM,t.curveCatmullRomClosed=oM,t.curveCatmullRomOpen=uM,t.curveCatmullRom=iM,t.curveLinearClosed=aM,t.curveLinear=xw,t.curveMonotoneX=ms,t.curveMonotoneY=xs,t.curveNatural=cM,t.curveStep=sM,t.curveStepAfter=Ns,t.curveStepBefore=Ts,t.stack=hM,t.stackOffsetExpand=pM,t.stackOffsetDiverging=dM,t.stackOffsetNone=fM,t.stackOffsetSilhouette=vM,t.stackOffsetWiggle=gM,t.stackOrderAscending=yM,t.stackOrderDescending=_M,t.stackOrderInsideOut=mM,t.stackOrderNone=lM,t.stackOrderReverse=xM,t.timeInterval=aa,t.timeMillisecond=zx,t.timeMilliseconds=Px,t.utcMillisecond=zx,t.utcMilliseconds=Px,t.timeSecond=Dx,t.timeSeconds=qx,t.utcSecond=Dx,t.utcSeconds=qx,t.timeMinute=Ux,t.timeMinutes=Ox,t.timeHour=Fx,t.timeHours=Yx,t.timeDay=Ix,t.timeDays=Hx,t.timeWeek=Bx,t.timeWeeks=Gx,t.timeSunday=Bx,t.timeSundays=Gx,t.timeMonday=jx,t.timeMondays=Qx,t.timeTuesday=Xx,t.timeTuesdays=Jx,t.timeWednesday=Wx,t.timeWednesdays=Kx,t.timeThursday=Vx,t.timeThursdays=tb,t.timeFriday=$x,t.timeFridays=nb,t.timeSaturday=Zx,t.timeSaturdays=eb,t.timeMonth=rb,t.timeMonths=ib,t.timeYear=ob,t.timeYears=ub,t.utcMinute=ab,t.utcMinutes=cb,t.utcHour=sb,t.utcHours=fb,t.utcDay=lb,t.utcDays=hb,t.utcWeek=pb,t.utcWeeks=xb,t.utcSunday=pb,t.utcSundays=xb,t.utcMonday=db,t.utcMondays=bb,t.utcTuesday=vb,t.utcTuesdays=wb,t.utcWednesday=gb,t.utcWednesdays=Mb,t.utcThursday=yb,t.utcThursdays=Tb,t.utcFriday=_b,t.utcFridays=Nb,t.utcSaturday=mb,t.utcSaturdays=kb,t.utcMonth=Sb,t.utcMonths=Ab,t.utcYear=Eb,t.utcYears=zb,t.timeFormatDefaultLocale=xc,t.timeFormatLocale=pa,t.isoFormat=qb,t.isoParse=Ub,t.now=_n,t.timer=bn,t.timerFlush=wn,t.timeout=Op,t.interval=Fp,t.transition=ie,t.active=jd,t.interrupt=Gp,t.voronoi=zM,t.zoom=DM,t.zoomTransform=sf,t.zoomIdentity=RM,t.wordwrap=VM,t.parseAttributes=UM,t.f=_f,t.ascendingKey=$M;t.descendingKey=ZM,t.conventions=GM,t.drawAxis=QM,t.attachTooltip=KM,t.loadData=tT,t.nestBy=nT,t.round=eT,t.clamp=JM,t.polygonClip=rT,t.graphScroll=wf,Object.defineProperty(t,"__esModule",{value:!0})}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset='utf-8'> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="stylesheet" href="style.css"> | |
<div id='graph'></div> | |
<script src='d3_.js'></script> | |
<script src='three.js'></script> | |
<!-- https://unpkg.com/three@0.115.0/examples/js/controls/OrbitControls.js --> | |
<script src='orbit.js'></script> | |
<script src='script.js'></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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 | |
* @author ScieCode / http://github.com/sciecode | |
*/ | |
// 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/meta/shiftKey, or arrow keys / touch: two-finger move | |
THREE.OrbitControls = function ( object, domElement ) { | |
if ( domElement === undefined ) console.warn( 'THREE.OrbitControls: The second parameter "domElement" is now mandatory.' ); | |
if ( domElement === document ) console.error( 'THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' ); | |
this.object = object; | |
this.domElement = domElement; | |
// 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.05; | |
// 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.ROTATE, MIDDLE: THREE.MOUSE.DOLLY, RIGHT: THREE.MOUSE.PAN }; | |
// Touch fingers | |
this.touches = { ONE: THREE.TOUCH.ROTATE, TWO: THREE.TOUCH.DOLLY_PAN }; | |
// 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() ); | |
} | |
if ( scope.enableDamping ) { | |
spherical.theta += sphericalDelta.theta * scope.dampingFactor; | |
spherical.phi += sphericalDelta.phi * scope.dampingFactor; | |
} else { | |
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 | |
if ( scope.enableDamping === true ) { | |
scope.target.addScaledVector( panOffset, scope.dampingFactor ); | |
} else { | |
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 ); | |
scope.domElement.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_PAN: 4, | |
TOUCH_DOLLY_PAN: 5, | |
TOUCH_DOLLY_ROTATE: 6 | |
}; | |
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; | |
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 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; | |
} | |
} | |
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; | |
} | |
} | |
// | |
// 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; | |
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 ) { | |
dollyOut( getZoomScale() ); | |
} else if ( dollyDelta.y < 0 ) { | |
dollyIn( 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*/ ) { | |
// no-op | |
} | |
function handleMouseWheel( event ) { | |
if ( event.deltaY < 0 ) { | |
dollyIn( getZoomScale() ); | |
} else if ( event.deltaY > 0 ) { | |
dollyOut( getZoomScale() ); | |
} | |
scope.update(); | |
} | |
function handleKeyDown( event ) { | |
var needsUpdate = false; | |
switch ( event.keyCode ) { | |
case scope.keys.UP: | |
pan( 0, scope.keyPanSpeed ); | |
needsUpdate = true; | |
break; | |
case scope.keys.BOTTOM: | |
pan( 0, - scope.keyPanSpeed ); | |
needsUpdate = true; | |
break; | |
case scope.keys.LEFT: | |
pan( scope.keyPanSpeed, 0 ); | |
needsUpdate = true; | |
break; | |
case scope.keys.RIGHT: | |
pan( - scope.keyPanSpeed, 0 ); | |
needsUpdate = true; | |
break; | |
} | |
if ( needsUpdate ) { | |
// prevent the browser from scrolling on cursor keys | |
event.preventDefault(); | |
scope.update(); | |
} | |
} | |
function handleTouchStartRotate( event ) { | |
if ( event.touches.length == 1 ) { | |
rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); | |
} else { | |
var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); | |
var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); | |
rotateStart.set( x, y ); | |
} | |
} | |
function handleTouchStartPan( event ) { | |
if ( event.touches.length == 1 ) { | |
panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); | |
} else { | |
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 handleTouchStartDolly( event ) { | |
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 ); | |
} | |
function handleTouchStartDollyPan( event ) { | |
if ( scope.enableZoom ) handleTouchStartDolly( event ); | |
if ( scope.enablePan ) handleTouchStartPan( event ); | |
} | |
function handleTouchStartDollyRotate( event ) { | |
if ( scope.enableZoom ) handleTouchStartDolly( event ); | |
if ( scope.enableRotate ) handleTouchStartRotate( event ); | |
} | |
function handleTouchMoveRotate( event ) { | |
if ( event.touches.length == 1 ) { | |
rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); | |
} else { | |
var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); | |
var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); | |
rotateEnd.set( x, y ); | |
} | |
rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); | |
var element = scope.domElement; | |
rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height | |
rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); | |
rotateStart.copy( rotateEnd ); | |
} | |
function handleTouchMovePan( event ) { | |
if ( event.touches.length == 1 ) { | |
panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); | |
} else { | |
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 ); | |
} | |
function handleTouchMoveDolly( event ) { | |
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 ) ); | |
dollyOut( dollyDelta.y ); | |
dollyStart.copy( dollyEnd ); | |
} | |
function handleTouchMoveDollyPan( event ) { | |
if ( scope.enableZoom ) handleTouchMoveDolly( event ); | |
if ( scope.enablePan ) handleTouchMovePan( event ); | |
} | |
function handleTouchMoveDollyRotate( event ) { | |
if ( scope.enableZoom ) handleTouchMoveDolly( event ); | |
if ( scope.enableRotate ) handleTouchMoveRotate( event ); | |
} | |
function handleTouchEnd( /*event*/ ) { | |
// no-op | |
} | |
// | |
// event handlers - FSM: listen for events and reset state | |
// | |
function onMouseDown( event ) { | |
if ( scope.enabled === false ) return; | |
// Prevent the browser from scrolling. | |
event.preventDefault(); | |
// Manually set the focus since calling preventDefault above | |
// prevents the browser from setting it automatically. | |
scope.domElement.focus ? scope.domElement.focus() : window.focus(); | |
var mouseAction; | |
switch ( event.button ) { | |
case 0: | |
mouseAction = scope.mouseButtons.LEFT; | |
break; | |
case 1: | |
mouseAction = scope.mouseButtons.MIDDLE; | |
break; | |
case 2: | |
mouseAction = scope.mouseButtons.RIGHT; | |
break; | |
default: | |
mouseAction = - 1; | |
} | |
switch ( mouseAction ) { | |
case THREE.MOUSE.DOLLY: | |
if ( scope.enableZoom === false ) return; | |
handleMouseDownDolly( event ); | |
state = STATE.DOLLY; | |
break; | |
case THREE.MOUSE.ROTATE: | |
if ( event.ctrlKey || event.metaKey || event.shiftKey ) { | |
if ( scope.enablePan === false ) return; | |
handleMouseDownPan( event ); | |
state = STATE.PAN; | |
} else { | |
if ( scope.enableRotate === false ) return; | |
handleMouseDownRotate( event ); | |
state = STATE.ROTATE; | |
} | |
break; | |
case THREE.MOUSE.PAN: | |
if ( event.ctrlKey || event.metaKey || event.shiftKey ) { | |
if ( scope.enableRotate === false ) return; | |
handleMouseDownRotate( event ); | |
state = STATE.ROTATE; | |
} else { | |
if ( scope.enablePan === false ) return; | |
handleMouseDownPan( event ); | |
state = STATE.PAN; | |
} | |
break; | |
default: | |
state = STATE.NONE; | |
} | |
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(); // prevent scrolling | |
switch ( event.touches.length ) { | |
case 1: | |
switch ( scope.touches.ONE ) { | |
case THREE.TOUCH.ROTATE: | |
if ( scope.enableRotate === false ) return; | |
handleTouchStartRotate( event ); | |
state = STATE.TOUCH_ROTATE; | |
break; | |
case THREE.TOUCH.PAN: | |
if ( scope.enablePan === false ) return; | |
handleTouchStartPan( event ); | |
state = STATE.TOUCH_PAN; | |
break; | |
default: | |
state = STATE.NONE; | |
} | |
break; | |
case 2: | |
switch ( scope.touches.TWO ) { | |
case THREE.TOUCH.DOLLY_PAN: | |
if ( scope.enableZoom === false && scope.enablePan === false ) return; | |
handleTouchStartDollyPan( event ); | |
state = STATE.TOUCH_DOLLY_PAN; | |
break; | |
case THREE.TOUCH.DOLLY_ROTATE: | |
if ( scope.enableZoom === false && scope.enableRotate === false ) return; | |
handleTouchStartDollyRotate( event ); | |
state = STATE.TOUCH_DOLLY_ROTATE; | |
break; | |
default: | |
state = STATE.NONE; | |
} | |
break; | |
default: | |
state = STATE.NONE; | |
} | |
if ( state !== STATE.NONE ) { | |
scope.dispatchEvent( startEvent ); | |
} | |
} | |
function onTouchMove( event ) { | |
if ( scope.enabled === false ) return; | |
event.preventDefault(); // prevent scrolling | |
event.stopPropagation(); | |
switch ( state ) { | |
case STATE.TOUCH_ROTATE: | |
if ( scope.enableRotate === false ) return; | |
handleTouchMoveRotate( event ); | |
scope.update(); | |
break; | |
case STATE.TOUCH_PAN: | |
if ( scope.enablePan === false ) return; | |
handleTouchMovePan( event ); | |
scope.update(); | |
break; | |
case STATE.TOUCH_DOLLY_PAN: | |
if ( scope.enableZoom === false && scope.enablePan === false ) return; | |
handleTouchMoveDollyPan( event ); | |
scope.update(); | |
break; | |
case STATE.TOUCH_DOLLY_ROTATE: | |
if ( scope.enableZoom === false && scope.enableRotate === false ) return; | |
handleTouchMoveDollyRotate( event ); | |
scope.update(); | |
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( 'touchstart', onTouchStart, false ); | |
scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); | |
scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); | |
scope.domElement.addEventListener( 'keydown', onKeyDown, false ); | |
// make sure element can receive keys. | |
if ( scope.domElement.tabIndex === - 1 ) { | |
scope.domElement.tabIndex = 0; | |
} | |
// force an update at start | |
this.update(); | |
}; | |
THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); | |
THREE.OrbitControls.prototype.constructor = THREE.OrbitControls; | |
// This set of controls performs orbiting, dollying (zooming), and panning. | |
// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). | |
// This is very similar to OrbitControls, another set of touch behavior | |
// | |
// Orbit - right mouse, or left mouse + ctrl/meta/shiftKey / touch: two-finger rotate | |
// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish | |
// Pan - left mouse, or arrow keys / touch: one-finger move | |
THREE.MapControls = function ( object, domElement ) { | |
THREE.OrbitControls.call( this, object, domElement ); | |
this.mouseButtons.LEFT = THREE.MOUSE.PAN; | |
this.mouseButtons.RIGHT = THREE.MOUSE.ROTATE; | |
this.touches.ONE = THREE.TOUCH.PAN; | |
this.touches.TWO = THREE.TOUCH.DOLLY_ROTATE; | |
}; | |
THREE.MapControls.prototype = Object.create( THREE.EventDispatcher.prototype ); | |
THREE.MapControls.prototype.constructor = THREE.MapControls; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
d3.selectAll('canvas').remove() | |
var scene = new THREE.Scene() | |
var camera = new THREE.PerspectiveCamera(28, window.innerWidth / window.innerHeight, 40, 3500) | |
var s = 10 | |
camera.position.x = -300 | |
camera.position.y = -100 | |
camera.position.z = 150 | |
function addBox(cx, cy, cz){ | |
var particles = 1000 | |
var geometry = new THREE.BufferGeometry() | |
var positions = [] | |
var colors = [] | |
var n = s | |
for (var i = 0; i < particles; i++) { | |
var x = Math.random()*n + cx | |
var y = Math.random()*n + cy | |
var z = Math.random()*n + cz | |
positions.push(x, y, z) | |
colors.push(255, 255, 255) | |
} | |
geometry.setAttribute( | |
'position', | |
new THREE.Float32BufferAttribute(positions, 3) | |
) | |
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)) | |
geometry.computeBoundingSphere() | |
var material = new THREE.PointsMaterial({ | |
size: 1, | |
vertexColors: THREE.VertexColors | |
}) | |
var p = new THREE.Points(geometry, material) | |
scene.add(p) | |
} | |
var str = ` | |
@ @ @ @ @ @ @ @ @ | |
@ @ @ @ @ @ @ @ @ @ | |
@ @ @@ @ @ @@ @ @ @ @ @@ @@ @ @@@ | |
@@@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ | |
@ @ @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ | |
@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ | |
@ @ @@@ @ @ @@ @ @ @@ @ @ @@@ | |
`.trim() | |
var boxes = [] | |
str.split('\n').reverse().forEach((row, j) => { | |
row.split('').forEach((d, i) => { | |
if (d.trim()) boxes.push({i, j}) | |
}) | |
}) | |
boxes.forEach(({i, j}) => { | |
addBox((i - 25)*s*1.2, j*s*1.2, -100) | |
}) | |
var renderer = new THREE.WebGLRenderer() | |
renderer.setSize( window.innerWidth, window.innerHeight ) | |
document.body.appendChild( renderer.domElement ) | |
var controls = new THREE.OrbitControls( camera, renderer.domElement ) | |
if (window.__timer) window.__timer.stop() | |
window.__timer = d3.timer(() => { | |
renderer.render( scene, camera ) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body{ | |
font-family: menlo, Consolas, 'Lucida Console', monospace; | |
margin: 0px; | |
} | |
body { margin: 0; } | |
canvas { display: block; } |
This file has been truncated, but you can view the full file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(global = global || self, factory(global.THREE = {})); | |
}(this, (function (exports) { 'use strict'; | |
// Polyfills | |
if ( Number.EPSILON === undefined ) { | |
Number.EPSILON = Math.pow( 2, - 52 ); | |
} | |
if ( Number.isInteger === undefined ) { | |
// Missing in IE | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger | |
Number.isInteger = function ( value ) { | |
return typeof value === 'number' && isFinite( value ) && Math.floor( value ) === value; | |
}; | |
} | |
// | |
if ( Math.sign === undefined ) { | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign | |
Math.sign = function ( x ) { | |
return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x; | |
}; | |
} | |
if ( 'name' in Function.prototype === false ) { | |
// Missing in IE | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name | |
Object.defineProperty( Function.prototype, 'name', { | |
get: function () { | |
return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ]; | |
} | |
} ); | |
} | |
if ( Object.assign === undefined ) { | |
// Missing in IE | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign | |
Object.assign = function ( target ) { | |
if ( target === undefined || target === null ) { | |
throw new TypeError( 'Cannot convert undefined or null to object' ); | |
} | |
var output = Object( target ); | |
for ( var index = 1; index < arguments.length; index ++ ) { | |
var source = arguments[ index ]; | |
if ( source !== undefined && source !== null ) { | |
for ( var nextKey in source ) { | |
if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) { | |
output[ nextKey ] = source[ nextKey ]; | |
} | |
} | |
} | |
} | |
return output; | |
}; | |
} | |
var REVISION = '115'; | |
var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; | |
var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }; | |
var CullFaceNone = 0; | |
var CullFaceBack = 1; | |
var CullFaceFront = 2; | |
var CullFaceFrontBack = 3; | |
var FrontFaceDirectionCW = 0; | |
var FrontFaceDirectionCCW = 1; | |
var BasicShadowMap = 0; | |
var PCFShadowMap = 1; | |
var PCFSoftShadowMap = 2; | |
var VSMShadowMap = 3; | |
var FrontSide = 0; | |
var BackSide = 1; | |
var DoubleSide = 2; | |
var FlatShading = 1; | |
var SmoothShading = 2; | |
var NoBlending = 0; | |
var NormalBlending = 1; | |
var AdditiveBlending = 2; | |
var SubtractiveBlending = 3; | |
var MultiplyBlending = 4; | |
var CustomBlending = 5; | |
var AddEquation = 100; | |
var SubtractEquation = 101; | |
var ReverseSubtractEquation = 102; | |
var MinEquation = 103; | |
var MaxEquation = 104; | |
var ZeroFactor = 200; | |
var OneFactor = 201; | |
var SrcColorFactor = 202; | |
var OneMinusSrcColorFactor = 203; | |
var SrcAlphaFactor = 204; | |
var OneMinusSrcAlphaFactor = 205; | |
var DstAlphaFactor = 206; | |
var OneMinusDstAlphaFactor = 207; | |
var DstColorFactor = 208; | |
var OneMinusDstColorFactor = 209; | |
var SrcAlphaSaturateFactor = 210; | |
var NeverDepth = 0; | |
var AlwaysDepth = 1; | |
var LessDepth = 2; | |
var LessEqualDepth = 3; | |
var EqualDepth = 4; | |
var GreaterEqualDepth = 5; | |
var GreaterDepth = 6; | |
var NotEqualDepth = 7; | |
var MultiplyOperation = 0; | |
var MixOperation = 1; | |
var AddOperation = 2; | |
var NoToneMapping = 0; | |
var LinearToneMapping = 1; | |
var ReinhardToneMapping = 2; | |
var Uncharted2ToneMapping = 3; | |
var CineonToneMapping = 4; | |
var ACESFilmicToneMapping = 5; | |
var UVMapping = 300; | |
var CubeReflectionMapping = 301; | |
var CubeRefractionMapping = 302; | |
var EquirectangularReflectionMapping = 303; | |
var EquirectangularRefractionMapping = 304; | |
var SphericalReflectionMapping = 305; | |
var CubeUVReflectionMapping = 306; | |
var CubeUVRefractionMapping = 307; | |
var RepeatWrapping = 1000; | |
var ClampToEdgeWrapping = 1001; | |
var MirroredRepeatWrapping = 1002; | |
var NearestFilter = 1003; | |
var NearestMipmapNearestFilter = 1004; | |
var NearestMipMapNearestFilter = 1004; | |
var NearestMipmapLinearFilter = 1005; | |
var NearestMipMapLinearFilter = 1005; | |
var LinearFilter = 1006; | |
var LinearMipmapNearestFilter = 1007; | |
var LinearMipMapNearestFilter = 1007; | |
var LinearMipmapLinearFilter = 1008; | |
var LinearMipMapLinearFilter = 1008; | |
var UnsignedByteType = 1009; | |
var ByteType = 1010; | |
var ShortType = 1011; | |
var UnsignedShortType = 1012; | |
var IntType = 1013; | |
var UnsignedIntType = 1014; | |
var FloatType = 1015; | |
var HalfFloatType = 1016; | |
var UnsignedShort4444Type = 1017; | |
var UnsignedShort5551Type = 1018; | |
var UnsignedShort565Type = 1019; | |
var UnsignedInt248Type = 1020; | |
var AlphaFormat = 1021; | |
var RGBFormat = 1022; | |
var RGBAFormat = 1023; | |
var LuminanceFormat = 1024; | |
var LuminanceAlphaFormat = 1025; | |
var RGBEFormat = RGBAFormat; | |
var DepthFormat = 1026; | |
var DepthStencilFormat = 1027; | |
var RedFormat = 1028; | |
var RedIntegerFormat = 1029; | |
var RGFormat = 1030; | |
var RGIntegerFormat = 1031; | |
var RGBIntegerFormat = 1032; | |
var RGBAIntegerFormat = 1033; | |
var RGB_S3TC_DXT1_Format = 33776; | |
var RGBA_S3TC_DXT1_Format = 33777; | |
var RGBA_S3TC_DXT3_Format = 33778; | |
var RGBA_S3TC_DXT5_Format = 33779; | |
var RGB_PVRTC_4BPPV1_Format = 35840; | |
var RGB_PVRTC_2BPPV1_Format = 35841; | |
var RGBA_PVRTC_4BPPV1_Format = 35842; | |
var RGBA_PVRTC_2BPPV1_Format = 35843; | |
var RGB_ETC1_Format = 36196; | |
var RGB_ETC2_Format = 37492; | |
var RGBA_ETC2_EAC_Format = 37496; | |
var RGBA_ASTC_4x4_Format = 37808; | |
var RGBA_ASTC_5x4_Format = 37809; | |
var RGBA_ASTC_5x5_Format = 37810; | |
var RGBA_ASTC_6x5_Format = 37811; | |
var RGBA_ASTC_6x6_Format = 37812; | |
var RGBA_ASTC_8x5_Format = 37813; | |
var RGBA_ASTC_8x6_Format = 37814; | |
var RGBA_ASTC_8x8_Format = 37815; | |
var RGBA_ASTC_10x5_Format = 37816; | |
var RGBA_ASTC_10x6_Format = 37817; | |
var RGBA_ASTC_10x8_Format = 37818; | |
var RGBA_ASTC_10x10_Format = 37819; | |
var RGBA_ASTC_12x10_Format = 37820; | |
var RGBA_ASTC_12x12_Format = 37821; | |
var RGBA_BPTC_Format = 36492; | |
var SRGB8_ALPHA8_ASTC_4x4_Format = 37840; | |
var SRGB8_ALPHA8_ASTC_5x4_Format = 37841; | |
var SRGB8_ALPHA8_ASTC_5x5_Format = 37842; | |
var SRGB8_ALPHA8_ASTC_6x5_Format = 37843; | |
var SRGB8_ALPHA8_ASTC_6x6_Format = 37844; | |
var SRGB8_ALPHA8_ASTC_8x5_Format = 37845; | |
var SRGB8_ALPHA8_ASTC_8x6_Format = 37846; | |
var SRGB8_ALPHA8_ASTC_8x8_Format = 37847; | |
var SRGB8_ALPHA8_ASTC_10x5_Format = 37848; | |
var SRGB8_ALPHA8_ASTC_10x6_Format = 37849; | |
var SRGB8_ALPHA8_ASTC_10x8_Format = 37850; | |
var SRGB8_ALPHA8_ASTC_10x10_Format = 37851; | |
var SRGB8_ALPHA8_ASTC_12x10_Format = 37852; | |
var SRGB8_ALPHA8_ASTC_12x12_Format = 37853; | |
var LoopOnce = 2200; | |
var LoopRepeat = 2201; | |
var LoopPingPong = 2202; | |
var InterpolateDiscrete = 2300; | |
var InterpolateLinear = 2301; | |
var InterpolateSmooth = 2302; | |
var ZeroCurvatureEnding = 2400; | |
var ZeroSlopeEnding = 2401; | |
var WrapAroundEnding = 2402; | |
var TrianglesDrawMode = 0; | |
var TriangleStripDrawMode = 1; | |
var TriangleFanDrawMode = 2; | |
var LinearEncoding = 3000; | |
var sRGBEncoding = 3001; | |
var GammaEncoding = 3007; | |
var RGBEEncoding = 3002; | |
var LogLuvEncoding = 3003; | |
var RGBM7Encoding = 3004; | |
var RGBM16Encoding = 3005; | |
var RGBDEncoding = 3006; | |
var BasicDepthPacking = 3200; | |
var RGBADepthPacking = 3201; | |
var TangentSpaceNormalMap = 0; | |
var ObjectSpaceNormalMap = 1; | |
var ZeroStencilOp = 0; | |
var KeepStencilOp = 7680; | |
var ReplaceStencilOp = 7681; | |
var IncrementStencilOp = 7682; | |
var DecrementStencilOp = 7683; | |
var IncrementWrapStencilOp = 34055; | |
var DecrementWrapStencilOp = 34056; | |
var InvertStencilOp = 5386; | |
var NeverStencilFunc = 512; | |
var LessStencilFunc = 513; | |
var EqualStencilFunc = 514; | |
var LessEqualStencilFunc = 515; | |
var GreaterStencilFunc = 516; | |
var NotEqualStencilFunc = 517; | |
var GreaterEqualStencilFunc = 518; | |
var AlwaysStencilFunc = 519; | |
var StaticDrawUsage = 35044; | |
var DynamicDrawUsage = 35048; | |
var StreamDrawUsage = 35040; | |
var StaticReadUsage = 35045; | |
var DynamicReadUsage = 35049; | |
var StreamReadUsage = 35041; | |
var StaticCopyUsage = 35046; | |
var DynamicCopyUsage = 35050; | |
var StreamCopyUsage = 35042; | |
/** | |
* https://github.com/mrdoob/eventdispatcher.js/ | |
*/ | |
function EventDispatcher() {} | |
Object.assign( EventDispatcher.prototype, { | |
addEventListener: function ( type, listener ) { | |
if ( this._listeners === undefined ) { this._listeners = {}; } | |
var listeners = this._listeners; | |
if ( listeners[ type ] === undefined ) { | |
listeners[ type ] = []; | |
} | |
if ( listeners[ type ].indexOf( listener ) === - 1 ) { | |
listeners[ type ].push( listener ); | |
} | |
}, | |
hasEventListener: function ( type, listener ) { | |
if ( this._listeners === undefined ) { return false; } | |
var listeners = this._listeners; | |
return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; | |
}, | |
removeEventListener: function ( type, listener ) { | |
if ( this._listeners === undefined ) { return; } | |
var listeners = this._listeners; | |
var listenerArray = listeners[ type ]; | |
if ( listenerArray !== undefined ) { | |
var index = listenerArray.indexOf( listener ); | |
if ( index !== - 1 ) { | |
listenerArray.splice( index, 1 ); | |
} | |
} | |
}, | |
dispatchEvent: function ( event ) { | |
if ( this._listeners === undefined ) { return; } | |
var listeners = this._listeners; | |
var listenerArray = listeners[ event.type ]; | |
if ( listenerArray !== undefined ) { | |
event.target = this; | |
// Make a copy, in case listeners are removed while iterating. | |
var array = listenerArray.slice( 0 ); | |
for ( var i = 0, l = array.length; i < l; i ++ ) { | |
array[ i ].call( this, event ); | |
} | |
} | |
} | |
} ); | |
/** | |
* @author alteredq / http://alteredqualia.com/ | |
* @author mrdoob / http://mrdoob.com/ | |
* @author WestLangley / http://github.com/WestLangley | |
* @author thezwap | |
*/ | |
var _lut = []; | |
for ( var i = 0; i < 256; i ++ ) { | |
_lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 ); | |
} | |
var MathUtils = { | |
DEG2RAD: Math.PI / 180, | |
RAD2DEG: 180 / Math.PI, | |
generateUUID: function () { | |
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 | |
var d0 = Math.random() * 0xffffffff | 0; | |
var d1 = Math.random() * 0xffffffff | 0; | |
var d2 = Math.random() * 0xffffffff | 0; | |
var d3 = Math.random() * 0xffffffff | 0; | |
var uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' + | |
_lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' + | |
_lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] + | |
_lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ]; | |
// .toUpperCase() here flattens concatenated strings to save heap memory space. | |
return uuid.toUpperCase(); | |
}, | |
clamp: function ( value, min, max ) { | |
return Math.max( min, Math.min( max, value ) ); | |
}, | |
// compute euclidian modulo of m % n | |
// https://en.wikipedia.org/wiki/Modulo_operation | |
euclideanModulo: function ( n, m ) { | |
return ( ( n % m ) + m ) % m; | |
}, | |
// Linear mapping from range <a1, a2> to range <b1, b2> | |
mapLinear: function ( x, a1, a2, b1, b2 ) { | |
return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); | |
}, | |
// https://en.wikipedia.org/wiki/Linear_interpolation | |
lerp: function ( x, y, t ) { | |
return ( 1 - t ) * x + t * y; | |
}, | |
// http://en.wikipedia.org/wiki/Smoothstep | |
smoothstep: function ( x, min, max ) { | |
if ( x <= min ) { return 0; } | |
if ( x >= max ) { return 1; } | |
x = ( x - min ) / ( max - min ); | |
return x * x * ( 3 - 2 * x ); | |
}, | |
smootherstep: function ( x, min, max ) { | |
if ( x <= min ) { return 0; } | |
if ( x >= max ) { return 1; } | |
x = ( x - min ) / ( max - min ); | |
return x * x * x * ( x * ( x * 6 - 15 ) + 10 ); | |
}, | |
// Random integer from <low, high> interval | |
randInt: function ( low, high ) { | |
return low + Math.floor( Math.random() * ( high - low + 1 ) ); | |
}, | |
// Random float from <low, high> interval | |
randFloat: function ( low, high ) { | |
return low + Math.random() * ( high - low ); | |
}, | |
// Random float from <-range/2, range/2> interval | |
randFloatSpread: function ( range ) { | |
return range * ( 0.5 - Math.random() ); | |
}, | |
degToRad: function ( degrees ) { | |
return degrees * MathUtils.DEG2RAD; | |
}, | |
radToDeg: function ( radians ) { | |
return radians * MathUtils.RAD2DEG; | |
}, | |
isPowerOfTwo: function ( value ) { | |
return ( value & ( value - 1 ) ) === 0 && value !== 0; | |
}, | |
ceilPowerOfTwo: function ( value ) { | |
return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) ); | |
}, | |
floorPowerOfTwo: function ( value ) { | |
return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) ); | |
}, | |
setQuaternionFromProperEuler: function ( q, a, b, c, order ) { | |
// Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles | |
// rotations are applied to the axes in the order specified by 'order' | |
// rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c' | |
// angles are in radians | |
var cos = Math.cos; | |
var sin = Math.sin; | |
var c2 = cos( b / 2 ); | |
var s2 = sin( b / 2 ); | |
var c13 = cos( ( a + c ) / 2 ); | |
var s13 = sin( ( a + c ) / 2 ); | |
var c1_3 = cos( ( a - c ) / 2 ); | |
var s1_3 = sin( ( a - c ) / 2 ); | |
var c3_1 = cos( ( c - a ) / 2 ); | |
var s3_1 = sin( ( c - a ) / 2 ); | |
if ( order === 'XYX' ) { | |
q.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 ); | |
} else if ( order === 'YZY' ) { | |
q.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 ); | |
} else if ( order === 'ZXZ' ) { | |
q.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 ); | |
} else if ( order === 'XZX' ) { | |
q.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 ); | |
} else if ( order === 'YXY' ) { | |
q.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 ); | |
} else if ( order === 'ZYZ' ) { | |
q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 ); | |
} else { | |
console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order.' ); | |
} | |
} | |
}; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author philogb / http://blog.thejit.org/ | |
* @author egraether / http://egraether.com/ | |
* @author zz85 / http://www.lab4games.net/zz85/blog | |
*/ | |
function Vector2( x, y ) { | |
this.x = x || 0; | |
this.y = y || 0; | |
} | |
Object.defineProperties( Vector2.prototype, { | |
"width": { | |
get: function () { | |
return this.x; | |
}, | |
set: function ( value ) { | |
this.x = value; | |
} | |
}, | |
"height": { | |
get: function () { | |
return this.y; | |
}, | |
set: function ( value ) { | |
this.y = value; | |
} | |
} | |
} ); | |
Object.assign( Vector2.prototype, { | |
isVector2: true, | |
set: function ( x, y ) { | |
this.x = x; | |
this.y = y; | |
return this; | |
}, | |
setScalar: function ( scalar ) { | |
this.x = scalar; | |
this.y = scalar; | |
return this; | |
}, | |
setX: function ( x ) { | |
this.x = x; | |
return this; | |
}, | |
setY: function ( y ) { | |
this.y = y; | |
return this; | |
}, | |
setComponent: function ( index, value ) { | |
switch ( index ) { | |
case 0: this.x = value; break; | |
case 1: this.y = value; break; | |
default: throw new Error( 'index is out of range: ' + index ); | |
} | |
return this; | |
}, | |
getComponent: function ( index ) { | |
switch ( index ) { | |
case 0: return this.x; | |
case 1: return this.y; | |
default: throw new Error( 'index is out of range: ' + index ); | |
} | |
}, | |
clone: function () { | |
return new this.constructor( this.x, this.y ); | |
}, | |
copy: function ( v ) { | |
this.x = v.x; | |
this.y = v.y; | |
return this; | |
}, | |
add: function ( v, w ) { | |
if ( w !== undefined ) { | |
console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); | |
return this.addVectors( v, w ); | |
} | |
this.x += v.x; | |
this.y += v.y; | |
return this; | |
}, | |
addScalar: function ( s ) { | |
this.x += s; | |
this.y += s; | |
return this; | |
}, | |
addVectors: function ( a, b ) { | |
this.x = a.x + b.x; | |
this.y = a.y + b.y; | |
return this; | |
}, | |
addScaledVector: function ( v, s ) { | |
this.x += v.x * s; | |
this.y += v.y * s; | |
return this; | |
}, | |
sub: function ( v, w ) { | |
if ( w !== undefined ) { | |
console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); | |
return this.subVectors( v, w ); | |
} | |
this.x -= v.x; | |
this.y -= v.y; | |
return this; | |
}, | |
subScalar: function ( s ) { | |
this.x -= s; | |
this.y -= s; | |
return this; | |
}, | |
subVectors: function ( a, b ) { | |
this.x = a.x - b.x; | |
this.y = a.y - b.y; | |
return this; | |
}, | |
multiply: function ( v ) { | |
this.x *= v.x; | |
this.y *= v.y; | |
return this; | |
}, | |
multiplyScalar: function ( scalar ) { | |
this.x *= scalar; | |
this.y *= scalar; | |
return this; | |
}, | |
divide: function ( v ) { | |
this.x /= v.x; | |
this.y /= v.y; | |
return this; | |
}, | |
divideScalar: function ( scalar ) { | |
return this.multiplyScalar( 1 / scalar ); | |
}, | |
applyMatrix3: function ( m ) { | |
var x = this.x, y = this.y; | |
var e = m.elements; | |
this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ]; | |
this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ]; | |
return this; | |
}, | |
min: function ( v ) { | |
this.x = Math.min( this.x, v.x ); | |
this.y = Math.min( this.y, v.y ); | |
return this; | |
}, | |
max: function ( v ) { | |
this.x = Math.max( this.x, v.x ); | |
this.y = Math.max( this.y, v.y ); | |
return this; | |
}, | |
clamp: function ( min, max ) { | |
// assumes min < max, componentwise | |
this.x = Math.max( min.x, Math.min( max.x, this.x ) ); | |
this.y = Math.max( min.y, Math.min( max.y, this.y ) ); | |
return this; | |
}, | |
clampScalar: function ( minVal, maxVal ) { | |
this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); | |
this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); | |
return this; | |
}, | |
clampLength: function ( min, max ) { | |
var length = this.length(); | |
return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); | |
}, | |
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 = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); | |
this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); | |
return this; | |
}, | |
negate: function () { | |
this.x = - this.x; | |
this.y = - this.y; | |
return this; | |
}, | |
dot: function ( v ) { | |
return this.x * v.x + this.y * v.y; | |
}, | |
cross: function ( v ) { | |
return this.x * v.y - this.y * v.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 () { | |
// computes the angle in radians with respect to the positive x-axis | |
var angle = Math.atan2( - this.y, - this.x ) + Math.PI; | |
return angle; | |
}, | |
distanceTo: function ( v ) { | |
return Math.sqrt( this.distanceToSquared( v ) ); | |
}, | |
distanceToSquared: function ( v ) { | |
var dx = this.x - v.x, dy = this.y - v.y; | |
return dx * dx + dy * dy; | |
}, | |
manhattanDistanceTo: function ( v ) { | |
return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ); | |
}, | |
setLength: function ( length ) { | |
return this.normalize().multiplyScalar( length ); | |
}, | |
lerp: function ( v, alpha ) { | |
this.x += ( v.x - this.x ) * alpha; | |
this.y += ( v.y - this.y ) * alpha; | |
return this; | |
}, | |
lerpVectors: function ( v1, v2, alpha ) { | |
return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); | |
}, | |
equals: function ( v ) { | |
return ( ( v.x === this.x ) && ( v.y === this.y ) ); | |
}, | |
fromArray: function ( array, offset ) { | |
if ( offset === undefined ) { offset = 0; } | |
this.x = array[ offset ]; | |
this.y = array[ offset + 1 ]; | |
return this; | |
}, | |
toArray: function ( array, offset ) { | |
if ( array === undefined ) { array = []; } | |
if ( offset === undefined ) { offset = 0; } | |
array[ offset ] = this.x; | |
array[ offset + 1 ] = this.y; | |
return array; | |
}, | |
fromBufferAttribute: function ( attribute, index, offset ) { | |
if ( offset !== undefined ) { | |
console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' ); | |
} | |
this.x = attribute.getX( index ); | |
this.y = attribute.getY( index ); | |
return this; | |
}, | |
rotateAround: function ( center, angle ) { | |
var c = Math.cos( angle ), s = Math.sin( angle ); | |
var x = this.x - center.x; | |
var y = this.y - center.y; | |
this.x = x * c - y * s + center.x; | |
this.y = x * s + y * c + center.y; | |
return this; | |
} | |
} ); | |
/** | |
* @author alteredq / http://alteredqualia.com/ | |
* @author WestLangley / http://github.com/WestLangley | |
* @author bhouston / http://clara.io | |
* @author tschw | |
*/ | |
function Matrix3() { | |
this.elements = [ | |
1, 0, 0, | |
0, 1, 0, | |
0, 0, 1 | |
]; | |
if ( arguments.length > 0 ) { | |
console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); | |
} | |
} | |
Object.assign( Matrix3.prototype, { | |
isMatrix3: true, | |
set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { | |
var te = this.elements; | |
te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; | |
te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; | |
te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; | |
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 ( m ) { | |
var te = this.elements; | |
var me = m.elements; | |
te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; | |
te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; | |
te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; | |
return this; | |
}, | |
extractBasis: function ( xAxis, yAxis, zAxis ) { | |
xAxis.setFromMatrix3Column( this, 0 ); | |
yAxis.setFromMatrix3Column( this, 1 ); | |
zAxis.setFromMatrix3Column( this, 2 ); | |
return this; | |
}, | |
setFromMatrix4: function ( m ) { | |
var me = m.elements; | |
this.set( | |
me[ 0 ], me[ 4 ], me[ 8 ], | |
me[ 1 ], me[ 5 ], me[ 9 ], | |
me[ 2 ], me[ 6 ], me[ 10 ] | |
); | |
return this; | |
}, | |
multiply: function ( m ) { | |
return this.multiplyMatrices( this, m ); | |
}, | |
premultiply: function ( m ) { | |
return this.multiplyMatrices( m, this ); | |
}, | |
multiplyMatrices: function ( a, b ) { | |
var ae = a.elements; | |
var be = b.elements; | |
var te = this.elements; | |
var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; | |
var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; | |
var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; | |
var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; | |
var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; | |
var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; | |
te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; | |
te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; | |
te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; | |
te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; | |
te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; | |
te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; | |
te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; | |
te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; | |
te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; | |
return this; | |
}, | |
multiplyScalar: function ( s ) { | |
var te = this.elements; | |
te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; | |
te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; | |
te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; | |
return this; | |
}, | |
determinant: function () { | |
var te = this.elements; | |
var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], | |
d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], | |
g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; | |
return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; | |
}, | |
getInverse: function ( matrix, throwOnDegenerate ) { | |
if ( throwOnDegenerate !== undefined ) { | |
console.warn( "THREE.Matrix3: .getInverse() can no longer be configured to throw on degenerate." ); | |
} | |
var me = matrix.elements, | |
te = this.elements, | |
n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], | |
n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ], | |
n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ], | |
t11 = n33 * n22 - n32 * n23, | |
t12 = n32 * n13 - n33 * n12, | |
t13 = n23 * n12 - n22 * n13, | |
det = n11 * t11 + n21 * t12 + n31 * t13; | |
if ( det === 0 ) { return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); } | |
var detInv = 1 / det; | |
te[ 0 ] = t11 * detInv; | |
te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; | |
te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; | |
te[ 3 ] = t12 * detInv; | |
te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; | |
te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; | |
te[ 6 ] = t13 * detInv; | |
te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; | |
te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; | |
return this; | |
}, | |
transpose: function () { | |
var tmp, m = this.elements; | |
tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; | |
tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; | |
tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; | |
return this; | |
}, | |
getNormalMatrix: function ( matrix4 ) { | |
return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose(); | |
}, | |
transposeIntoArray: function ( r ) { | |
var m = this.elements; | |
r[ 0 ] = m[ 0 ]; | |
r[ 1 ] = m[ 3 ]; | |
r[ 2 ] = m[ 6 ]; | |
r[ 3 ] = m[ 1 ]; | |
r[ 4 ] = m[ 4 ]; | |
r[ 5 ] = m[ 7 ]; | |
r[ 6 ] = m[ 2 ]; | |
r[ 7 ] = m[ 5 ]; | |
r[ 8 ] = m[ 8 ]; | |
return this; | |
}, | |
setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) { | |
var c = Math.cos( rotation ); | |
var s = Math.sin( rotation ); | |
this.set( | |
sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, | |
- sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, | |
0, 0, 1 | |
); | |
}, | |
scale: function ( sx, sy ) { | |
var te = this.elements; | |
te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; | |
te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; | |
return this; | |
}, | |
rotate: function ( theta ) { | |
var c = Math.cos( theta ); | |
var s = Math.sin( theta ); | |
var te = this.elements; | |
var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; | |
var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; | |
te[ 0 ] = c * a11 + s * a21; | |
te[ 3 ] = c * a12 + s * a22; | |
te[ 6 ] = c * a13 + s * a23; | |
te[ 1 ] = - s * a11 + c * a21; | |
te[ 4 ] = - s * a12 + c * a22; | |
te[ 7 ] = - s * a13 + c * a23; | |
return this; | |
}, | |
translate: function ( tx, ty ) { | |
var te = this.elements; | |
te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ]; | |
te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ]; | |
return this; | |
}, | |
equals: function ( matrix ) { | |
var te = this.elements; | |
var me = matrix.elements; | |
for ( var i = 0; i < 9; i ++ ) { | |
if ( te[ i ] !== me[ i ] ) { return false; } | |
} | |
return true; | |
}, | |
fromArray: function ( array, offset ) { | |
if ( offset === undefined ) { offset = 0; } | |
for ( var i = 0; i < 9; i ++ ) { | |
this.elements[ i ] = array[ i + offset ]; | |
} | |
return this; | |
}, | |
toArray: function ( array, offset ) { | |
if ( array === undefined ) { array = []; } | |
if ( offset === undefined ) { offset = 0; } | |
var te = this.elements; | |
array[ offset ] = te[ 0 ]; | |
array[ offset + 1 ] = te[ 1 ]; | |
array[ offset + 2 ] = te[ 2 ]; | |
array[ offset + 3 ] = te[ 3 ]; | |
array[ offset + 4 ] = te[ 4 ]; | |
array[ offset + 5 ] = te[ 5 ]; | |
array[ offset + 6 ] = te[ 6 ]; | |
array[ offset + 7 ] = te[ 7 ]; | |
array[ offset + 8 ] = te[ 8 ]; | |
return array; | |
} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author alteredq / http://alteredqualia.com/ | |
* @author szimek / https://github.com/szimek/ | |
*/ | |
var _canvas; | |
var ImageUtils = { | |
getDataURL: function ( image ) { | |
var canvas; | |
if ( typeof HTMLCanvasElement == 'undefined' ) { | |
return image.src; | |
} else if ( image instanceof HTMLCanvasElement ) { | |
canvas = image; | |
} else { | |
if ( _canvas === undefined ) { _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); } | |
_canvas.width = image.width; | |
_canvas.height = image.height; | |
var context = _canvas.getContext( '2d' ); | |
if ( image instanceof ImageData ) { | |
context.putImageData( image, 0, 0 ); | |
} else { | |
context.drawImage( image, 0, 0, image.width, image.height ); | |
} | |
canvas = _canvas; | |
} | |
if ( canvas.width > 2048 || canvas.height > 2048 ) { | |
return canvas.toDataURL( 'image/jpeg', 0.6 ); | |
} else { | |
return canvas.toDataURL( 'image/png' ); | |
} | |
} | |
}; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author alteredq / http://alteredqualia.com/ | |
* @author szimek / https://github.com/szimek/ | |
*/ | |
var textureId = 0; | |
function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { | |
Object.defineProperty( this, 'id', { value: textureId ++ } ); | |
this.uuid = MathUtils.generateUUID(); | |
this.name = ''; | |
this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE; | |
this.mipmaps = []; | |
this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING; | |
this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping; | |
this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping; | |
this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; | |
this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter; | |
this.anisotropy = anisotropy !== undefined ? anisotropy : 1; | |
this.format = format !== undefined ? format : RGBAFormat; | |
this.internalFormat = null; | |
this.type = type !== undefined ? type : UnsignedByteType; | |
this.offset = new Vector2( 0, 0 ); | |
this.repeat = new Vector2( 1, 1 ); | |
this.center = new Vector2( 0, 0 ); | |
this.rotation = 0; | |
this.matrixAutoUpdate = true; | |
this.matrix = new Matrix3(); | |
this.generateMipmaps = true; | |
this.premultiplyAlpha = false; | |
this.flipY = true; | |
this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) | |
// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. | |
// | |
// Also changing the encoding after already used by a Material will not automatically make the Material | |
// update. You need to explicitly call Material.needsUpdate to trigger it to recompile. | |
this.encoding = encoding !== undefined ? encoding : LinearEncoding; | |
this.version = 0; | |
this.onUpdate = null; | |
} | |
Texture.DEFAULT_IMAGE = undefined; | |
Texture.DEFAULT_MAPPING = UVMapping; | |
Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { | |
constructor: Texture, | |
isTexture: true, | |
updateMatrix: function () { | |
this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y ); | |
}, | |
clone: function () { | |
return new this.constructor().copy( this ); | |
}, | |
copy: function ( source ) { | |
this.name = source.name; | |
this.image = source.image; | |
this.mipmaps = source.mipmaps.slice( 0 ); | |
this.mapping = source.mapping; | |
this.wrapS = source.wrapS; | |
this.wrapT = source.wrapT; | |
this.magFilter = source.magFilter; | |
this.minFilter = source.minFilter; | |
this.anisotropy = source.anisotropy; | |
this.format = source.format; | |
this.internalFormat = source.internalFormat; | |
this.type = source.type; | |
this.offset.copy( source.offset ); | |
this.repeat.copy( source.repeat ); | |
this.center.copy( source.center ); | |
this.rotation = source.rotation; | |
this.matrixAutoUpdate = source.matrixAutoUpdate; | |
this.matrix.copy( source.matrix ); | |
this.generateMipmaps = source.generateMipmaps; | |
this.premultiplyAlpha = source.premultiplyAlpha; | |
this.flipY = source.flipY; | |
this.unpackAlignment = source.unpackAlignment; | |
this.encoding = source.encoding; | |
return this; | |
}, | |
toJSON: function ( meta ) { | |
var isRootObject = ( meta === undefined || typeof meta === 'string' ); | |
if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { | |
return meta.textures[ this.uuid ]; | |
} | |
var output = { | |
metadata: { | |
version: 4.5, | |
type: 'Texture', | |
generator: 'Texture.toJSON' | |
}, | |
uuid: this.uuid, | |
name: this.name, | |
mapping: this.mapping, | |
repeat: [ this.repeat.x, this.repeat.y ], | |
offset: [ this.offset.x, this.offset.y ], | |
center: [ this.center.x, this.center.y ], | |
rotation: this.rotation, | |
wrap: [ this.wrapS, this.wrapT ], | |
format: this.format, | |
type: this.type, | |
encoding: this.encoding, | |
minFilter: this.minFilter, | |
magFilter: this.magFilter, | |
anisotropy: this.anisotropy, | |
flipY: this.flipY, | |
premultiplyAlpha: this.premultiplyAlpha, | |
unpackAlignment: this.unpackAlignment | |
}; | |
if ( this.image !== undefined ) { | |
// TODO: Move to THREE.Image | |
var image = this.image; | |
if ( image.uuid === undefined ) { | |
image.uuid = MathUtils.generateUUID(); // UGH | |
} | |
if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) { | |
var url; | |
if ( Array.isArray( image ) ) { | |
// process array of images e.g. CubeTexture | |
url = []; | |
for ( var i = 0, l = image.length; i < l; i ++ ) { | |
url.push( ImageUtils.getDataURL( image[ i ] ) ); | |
} | |
} else { | |
// process single image | |
url = ImageUtils.getDataURL( image ); | |
} | |
meta.images[ image.uuid ] = { | |
uuid: image.uuid, | |
url: url | |
}; | |
} | |
output.image = image.uuid; | |
} | |
if ( ! isRootObject ) { | |
meta.textures[ this.uuid ] = output; | |
} | |
return output; | |
}, | |
dispose: function () { | |
this.dispatchEvent( { type: 'dispose' } ); | |
}, | |
transformUv: function ( uv ) { | |
if ( this.mapping !== UVMapping ) { return uv; } | |
uv.applyMatrix3( this.matrix ); | |
if ( uv.x < 0 || uv.x > 1 ) { | |
switch ( this.wrapS ) { | |
case RepeatWrapping: | |
uv.x = uv.x - Math.floor( uv.x ); | |
break; | |
case ClampToEdgeWrapping: | |
uv.x = uv.x < 0 ? 0 : 1; | |
break; | |
case MirroredRepeatWrapping: | |
if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) { | |
uv.x = Math.ceil( uv.x ) - uv.x; | |
} else { | |
uv.x = uv.x - Math.floor( uv.x ); | |
} | |
break; | |
} | |
} | |
if ( uv.y < 0 || uv.y > 1 ) { | |
switch ( this.wrapT ) { | |
case RepeatWrapping: | |
uv.y = uv.y - Math.floor( uv.y ); | |
break; | |
case ClampToEdgeWrapping: | |
uv.y = uv.y < 0 ? 0 : 1; | |
break; | |
case MirroredRepeatWrapping: | |
if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) { | |
uv.y = Math.ceil( uv.y ) - uv.y; | |
} else { | |
uv.y = uv.y - Math.floor( uv.y ); | |
} | |
break; | |
} | |
} | |
if ( this.flipY ) { | |
uv.y = 1 - uv.y; | |
} | |
return uv; | |
} | |
} ); | |
Object.defineProperty( Texture.prototype, "needsUpdate", { | |
set: function ( value ) { | |
if ( value === true ) { this.version ++; } | |
} | |
} ); | |
/** | |
* @author supereggbert / http://www.paulbrunt.co.uk/ | |
* @author philogb / http://blog.thejit.org/ | |
* @author mikael emtinger / http://gomo.se/ | |
* @author egraether / http://egraether.com/ | |
* @author WestLangley / http://github.com/WestLangley | |
*/ | |
function Vector4( x, y, z, w ) { | |
this.x = x || 0; | |
this.y = y || 0; | |
this.z = z || 0; | |
this.w = ( w !== undefined ) ? w : 1; | |
} | |
Object.defineProperties( Vector4.prototype, { | |
"width": { | |
get: function () { | |
return this.z; | |
}, | |
set: function ( value ) { | |
this.z = value; | |
} | |
}, | |
"height": { | |
get: function () { | |
return this.w; | |
}, | |
set: function ( value ) { | |
this.w = value; | |
} | |
} | |
} ); | |
Object.assign( Vector4.prototype, { | |
isVector4: true, | |
set: function ( x, y, z, w ) { | |
this.x = x; | |
this.y = y; | |
this.z = z; | |
this.w = w; | |
return this; | |
}, | |
setScalar: function ( scalar ) { | |
this.x = scalar; | |
this.y = scalar; | |
this.z = scalar; | |
this.w = scalar; | |
return this; | |
}, | |
setX: function ( x ) { | |
this.x = x; | |
return this; | |
}, | |
setY: function ( y ) { | |
this.y = y; | |
return this; | |
}, | |
setZ: function ( z ) { | |
this.z = z; | |
return this; | |
}, | |
setW: function ( w ) { | |
this.w = w; | |
return this; | |
}, | |
setComponent: function ( index, value ) { | |
switch ( index ) { | |
case 0: this.x = value; break; | |
case 1: this.y = value; break; | |
case 2: this.z = value; break; | |
case 3: this.w = value; break; | |
default: throw new Error( 'index is out of range: ' + index ); | |
} | |
return this; | |
}, | |
getComponent: function ( index ) { | |
switch ( index ) { | |
case 0: return this.x; | |
case 1: return this.y; | |
case 2: return this.z; | |
case 3: return this.w; | |
default: throw new Error( 'index is out of range: ' + index ); | |
} | |
}, | |
clone: function () { | |
return new this.constructor( this.x, this.y, this.z, this.w ); | |
}, | |
copy: function ( v ) { | |
this.x = v.x; | |
this.y = v.y; | |
this.z = v.z; | |
this.w = ( v.w !== undefined ) ? v.w : 1; | |
return this; | |
}, | |
add: function ( v, w ) { | |
if ( w !== undefined ) { | |
console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); | |
return this.addVectors( v, w ); | |
} | |
this.x += v.x; | |
this.y += v.y; | |
this.z += v.z; | |
this.w += v.w; | |
return this; | |
}, | |
addScalar: function ( s ) { | |
this.x += s; | |
this.y += s; | |
this.z += s; | |
this.w += s; | |
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 ( v, s ) { | |
this.x += v.x * s; | |
this.y += v.y * s; | |
this.z += v.z * s; | |
this.w += v.w * s; | |
return this; | |
}, | |
sub: function ( v, w ) { | |
if ( w !== undefined ) { | |
console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); | |
return this.subVectors( v, w ); | |
} | |
this.x -= v.x; | |
this.y -= v.y; | |
this.z -= v.z; | |
this.w -= v.w; | |
return this; | |
}, | |
subScalar: function ( s ) { | |
this.x -= s; | |
this.y -= s; | |
this.z -= s; | |
this.w -= s; | |
return this; | |
}, | |
subVectors: function ( a, b ) { | |
this.x = a.x - b.x; | |
this.y = a.y - b.y; | |
this.z = a.z - b.z; | |
this.w = a.w - b.w; | |
return this; | |
}, | |
multiplyScalar: function ( scalar ) { | |
this.x *= scalar; | |
this.y *= scalar; | |
this.z *= scalar; | |
this.w *= scalar; | |
return this; | |
}, | |
applyMatrix4: function ( m ) { | |
var x = this.x, y = this.y, z = this.z, w = this.w; | |
var e = m.elements; | |
this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; | |
this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; | |
this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; | |
this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; | |
return this; | |
}, | |
divideScalar: function ( scalar ) { | |
return this.multiplyScalar( 1 / scalar ); | |
}, | |
setAxisAngleFromQuaternion: function ( q ) { | |
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm | |
// q is assumed to be normalized | |
this.w = 2 * Math.acos( q.w ); | |
var s = Math.sqrt( 1 - q.w * q.w ); | |
if ( s < 0.0001 ) { | |
this.x = 1; | |
this.y = 0; | |
this.z = 0; | |
} else { | |
this.x = q.x / s; | |
this.y = q.y / s; | |
this.z = q.z / s; | |
} | |
return this; | |
}, | |
setAxisAngleFromRotationMatrix: function ( m ) { | |
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm | |
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) | |
var angle, x, y, z, // variables for result | |
epsilon = 0.01, // margin to allow for rounding errors | |
epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees | |
te = m.elements, | |
m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], | |
m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], | |
m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; | |
if ( ( Math.abs( m12 - m21 ) < epsilon ) && | |
( Math.abs( m13 - m31 ) < epsilon ) && | |
( Math.abs( m23 - m32 ) < epsilon ) ) { | |
// singularity found | |
// first check for identity matrix which must have +1 for all terms | |
// in leading diagonal and zero in other terms | |
if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && | |
( Math.abs( m13 + m31 ) < epsilon2 ) && | |
( Math.abs( m23 + m32 ) < epsilon2 ) && | |
( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { | |
// this singularity is identity matrix so angle = 0 | |
this.set( 1, 0, 0, 0 ); | |
return this; // zero angle, arbitrary axis | |
} | |
// otherwise this singularity is angle = 180 | |
angle = Math.PI; | |
var xx = ( m11 + 1 ) / 2; | |
var yy = ( m22 + 1 ) / 2; | |
var zz = ( m33 + 1 ) / 2; | |
var xy = ( m12 + m21 ) / 4; | |
var xz = ( m13 + m31 ) / 4; | |
var yz = ( m23 + m32 ) / 4; | |
if ( ( xx > yy ) && ( xx > zz ) ) { | |
// m11 is the largest diagonal term | |
if ( xx < epsilon ) { | |
x = 0; | |
y = 0.707106781; | |
z = 0.707106781; | |
} else { | |
x = Math.sqrt( xx ); | |
y = xy / x; | |
z = xz / x; | |
} | |
} else if ( yy > zz ) { | |
// m22 is the largest diagonal term | |
if ( yy < epsilon ) { | |
x = 0.707106781; | |
y = 0; | |
z = 0.707106781; | |
} else { | |
y = Math.sqrt( yy ); | |
x = xy / y; | |
z = yz / y; | |
} | |
} else { | |
// m33 is the largest diagonal term so base result on this | |
if ( zz < epsilon ) { | |
x = 0.707106781; | |
y = 0.707106781; | |
z = 0; | |
} else { | |
z = Math.sqrt( zz ); | |
x = xz / z; | |
y = yz / z; | |
} | |
} | |
this.set( x, y, z, angle ); | |
return this; // return 180 deg rotation | |
} | |
// as we have reached here there are no singularities so we can handle normally | |
var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + | |
( m13 - m31 ) * ( m13 - m31 ) + | |
( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize | |
if ( Math.abs( s ) < 0.001 ) { s = 1; } | |
// prevent divide by zero, should not happen if matrix is orthogonal and should be | |
// caught by singularity test above, but I've left it in just in case | |
this.x = ( m32 - m23 ) / s; | |
this.y = ( m13 - m31 ) / s; | |
this.z = ( m21 - m12 ) / s; | |
this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); | |
return this; | |
}, | |
min: function ( v ) { | |
this.x = Math.min( this.x, v.x ); | |
this.y = Math.min( this.y, v.y ); | |
this.z = Math.min( this.z, v.z ); | |
this.w = Math.min( this.w, v.w ); | |
return this; | |
}, | |
max: function ( v ) { | |
this.x = Math.max( this.x, v.x ); | |
this.y = Math.max( this.y, v.y ); | |
this.z = Math.max( this.z, v.z ); | |
this.w = Math.max( this.w, v.w ); | |
return this; | |
}, | |
clamp: function ( min, max ) { | |
// assumes min < max, componentwise | |
this.x = Math.max( min.x, Math.min( max.x, this.x ) ); | |
this.y = Math.max( min.y, Math.min( max.y, this.y ) ); | |
this.z = Math.max( min.z, Math.min( max.z, this.z ) ); | |
this.w = Math.max( min.w, Math.min( max.w, this.w ) ); | |
return this; | |
}, | |
clampScalar: function ( minVal, maxVal ) { | |
this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); | |
this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); | |
this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); | |
this.w = Math.max( minVal, Math.min( maxVal, this.w ) ); | |
return this; | |
}, | |
clampLength: function ( min, max ) { | |
var length = this.length(); | |
return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); | |
}, | |
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 = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); | |
this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); | |
this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); | |
this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); | |
return this; | |
}, | |
negate: function () { | |
this.x = - this.x; | |
this.y = - this.y; | |
this.z = - this.z; | |
this.w = - this.w; | |
return this; | |
}, | |
dot: function ( v ) { | |
return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.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 ( length ) { | |
return this.normalize().multiplyScalar( length ); | |
}, | |
lerp: function ( v, alpha ) { | |
this.x += ( v.x - this.x ) * alpha; | |
this.y += ( v.y - this.y ) * alpha; | |
this.z += ( v.z - this.z ) * alpha; | |
this.w += ( v.w - this.w ) * alpha; | |
return this; | |
}, | |
lerpVectors: function ( v1, v2, alpha ) { | |
return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); | |
}, | |
equals: function ( v ) { | |
return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); | |
}, | |
fromArray: function ( array, offset ) { | |
if ( offset === undefined ) { offset = 0; } | |
this.x = array[ offset ]; | |
this.y = array[ offset + 1 ]; | |
this.z = array[ offset + 2 ]; | |
this.w = array[ offset + 3 ]; | |
return this; | |
}, | |
toArray: function ( array, offset ) { | |
if ( array === undefined ) { array = []; } | |
if ( offset === undefined ) { offset = 0; } | |
array[ offset ] = this.x; | |
array[ offset + 1 ] = this.y; | |
array[ offset + 2 ] = this.z; | |
array[ offset + 3 ] = this.w; | |
return array; | |
}, | |
fromBufferAttribute: function ( attribute, index, offset ) { | |
if ( offset !== undefined ) { | |
console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); | |
} | |
this.x = attribute.getX( index ); | |
this.y = attribute.getY( index ); | |
this.z = attribute.getZ( index ); | |
this.w = attribute.getW( index ); | |
return this; | |
} | |
} ); | |
/** | |
* @author szimek / https://github.com/szimek/ | |
* @author alteredq / http://alteredqualia.com/ | |
* @author Marius Kintel / https://github.com/kintel | |
*/ | |
/* | |
In options, we can specify: | |
* Texture parameters for an auto-generated target texture | |
* depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers | |
*/ | |
function WebGLRenderTarget( width, height, options ) { | |
this.width = width; | |
this.height = height; | |
this.scissor = new Vector4( 0, 0, width, height ); | |
this.scissorTest = false; | |
this.viewport = new Vector4( 0, 0, width, height ); | |
options = options || {}; | |
this.texture = new Texture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); | |
this.texture.image = {}; | |
this.texture.image.width = width; | |
this.texture.image.height = height; | |
this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; | |
this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; | |
this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; | |
this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; | |
this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; | |
} | |
WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { | |
constructor: WebGLRenderTarget, | |
isWebGLRenderTarget: true, | |
setSize: function ( width, height ) { | |
if ( this.width !== width || this.height !== height ) { | |
this.width = width; | |
this.height = height; | |
this.texture.image.width = width; | |
this.texture.image.height = height; | |
this.dispose(); | |
} | |
this.viewport.set( 0, 0, width, height ); | |
this.scissor.set( 0, 0, width, height ); | |
}, | |
clone: function () { | |
return new this.constructor().copy( this ); | |
}, | |
copy: function ( source ) { | |
this.width = source.width; | |
this.height = source.height; | |
this.viewport.copy( source.viewport ); | |
this.texture = source.texture.clone(); | |
this.depthBuffer = source.depthBuffer; | |
this.stencilBuffer = source.stencilBuffer; | |
this.depthTexture = source.depthTexture; | |
return this; | |
}, | |
dispose: function () { | |
this.dispatchEvent( { type: 'dispose' } ); | |
} | |
} ); | |
/** | |
* @author Mugen87 / https://github.com/Mugen87 | |
* @author Matt DesLauriers / @mattdesl | |
*/ | |
function WebGLMultisampleRenderTarget( width, height, options ) { | |
WebGLRenderTarget.call( this, width, height, options ); | |
this.samples = 4; | |
} | |
WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), { | |
constructor: WebGLMultisampleRenderTarget, | |
isWebGLMultisampleRenderTarget: true, | |
copy: function ( source ) { | |
WebGLRenderTarget.prototype.copy.call( this, source ); | |
this.samples = source.samples; | |
return this; | |
} | |
} ); | |
/** | |
* @author mikael emtinger / http://gomo.se/ | |
* @author alteredq / http://alteredqualia.com/ | |
* @author WestLangley / http://github.com/WestLangley | |
* @author bhouston / http://clara.io | |
*/ | |
function Quaternion( x, y, z, w ) { | |
this._x = x || 0; | |
this._y = y || 0; | |
this._z = z || 0; | |
this._w = ( w !== undefined ) ? w : 1; | |
} | |
Object.assign( Quaternion, { | |
slerp: function ( qa, qb, qm, t ) { | |
return qm.copy( qa ).slerp( qb, t ); | |
}, | |
slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { | |
// fuzz-free, array-based Quaternion SLERP operation | |
var x0 = src0[ srcOffset0 + 0 ], | |
y0 = src0[ srcOffset0 + 1 ], | |
z0 = src0[ srcOffset0 + 2 ], | |
w0 = src0[ srcOffset0 + 3 ], | |
x1 = src1[ srcOffset1 + 0 ], | |
y1 = src1[ srcOffset1 + 1 ], | |
z1 = src1[ srcOffset1 + 2 ], | |
w1 = src1[ srcOffset1 + 3 ]; | |
if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) { | |
var s = 1 - t, | |
cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, | |
dir = ( cos >= 0 ? 1 : - 1 ), | |
sqrSin = 1 - cos * cos; | |
// Skip the Slerp for tiny steps to avoid numeric problems: | |
if ( sqrSin > Number.EPSILON ) { | |
var sin = Math.sqrt( sqrSin ), | |
len = Math.atan2( sin, cos * dir ); | |
s = Math.sin( s * len ) / sin; | |
t = Math.sin( t * len ) / sin; | |
} | |
var tDir = t * dir; | |
x0 = x0 * s + x1 * tDir; | |
y0 = y0 * s + y1 * tDir; | |
z0 = z0 * s + z1 * tDir; | |
w0 = w0 * s + w1 * tDir; | |
// Normalize in case we just did a lerp: | |
if ( s === 1 - t ) { | |
var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 ); | |
x0 *= f; | |
y0 *= f; | |
z0 *= f; | |
w0 *= f; | |
} | |
} | |
dst[ dstOffset ] = x0; | |
dst[ dstOffset + 1 ] = y0; | |
dst[ dstOffset + 2 ] = z0; | |
dst[ dstOffset + 3 ] = w0; | |
} | |
} ); | |
Object.defineProperties( Quaternion.prototype, { | |
x: { | |
get: function () { | |
return this._x; | |
}, | |
set: function ( value ) { | |
this._x = value; | |
this._onChangeCallback(); | |
} | |
}, | |
y: { | |
get: function () { | |
return this._y; | |
}, | |
set: function ( value ) { | |
this._y = value; | |
this._onChangeCallback(); | |
} | |
}, | |
z: { | |
get: function () { | |
return this._z; | |
}, | |
set: function ( value ) { | |
this._z = value; | |
this._onChangeCallback(); | |
} | |
}, | |
w: { | |
get: function () { | |
return this._w; | |
}, | |
set: function ( value ) { | |
this._w = value; | |
this._onChangeCallback(); | |
} | |
} | |
} ); | |
Object.assign( Quaternion.prototype, { | |
isQuaternion: true, | |
set: function ( x, y, z, w ) { | |
this._x = x; | |
this._y = y; | |
this._z = z; | |
this._w = w; | |
this._onChangeCallback(); | |
return this; | |
}, | |
clone: function () { | |
return new this.constructor( this._x, this._y, this._z, this._w ); | |
}, | |
copy: function ( quaternion ) { | |
this._x = quaternion.x; | |
this._y = quaternion.y; | |
this._z = quaternion.z; | |
this._w = quaternion.w; | |
this._onChangeCallback(); | |
return this; | |
}, | |
setFromEuler: function ( euler, update ) { | |
if ( ! ( euler && euler.isEuler ) ) { | |
throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); | |
} | |
var x = euler._x, y = euler._y, z = euler._z, order = euler.order; | |
// http://www.mathworks.com/matlabcentral/fileexchange/ | |
// 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ | |
// content/SpinCalc.m | |
var cos = Math.cos; | |
var sin = Math.sin; | |
var c1 = cos( x / 2 ); | |
var c2 = cos( y / 2 ); | |
var c3 = cos( z / 2 ); | |
var s1 = sin( x / 2 ); | |
var s2 = sin( y / 2 ); | |
var s3 = sin( z / 2 ); | |
if ( order === 'XYZ' ) { | |
this._x = s1 * c2 * c3 + c1 * s2 * s3; | |
this._y = c1 * s2 * c3 - s1 * c2 * s3; | |
this._z = c1 * c2 * s3 + s1 * s2 * c3; | |
this._w = c1 * c2 * c3 - s1 * s2 * s3; | |
} else if ( order === 'YXZ' ) { | |
this._x = s1 * c2 * c3 + c1 * s2 * s3; | |
this._y = c1 * s2 * c3 - s1 * c2 * s3; | |
this._z = c1 * c2 * s3 - s1 * s2 * c3; | |
this._w = c1 * c2 * c3 + s1 * s2 * s3; | |
} else if ( order === 'ZXY' ) { | |
this._x = s1 * c2 * c3 - c1 * s2 * s3; | |
this._y = c1 * s2 * c3 + s1 * c2 * s3; | |
this._z = c1 * c2 * s3 + s1 * s2 * c3; | |
this._w = c1 * c2 * c3 - s1 * s2 * s3; | |
} else if ( order === 'ZYX' ) { | |
this._x = s1 * c2 * c3 - c1 * s2 * s3; | |
this._y = c1 * s2 * c3 + s1 * c2 * s3; | |
this._z = c1 * c2 * s3 - s1 * s2 * c3; | |
this._w = c1 * c2 * c3 + s1 * s2 * s3; | |
} else if ( order === 'YZX' ) { | |
this._x = s1 * c2 * c3 + c1 * s2 * s3; | |
this._y = c1 * s2 * c3 + s1 * c2 * s3; | |
this._z = c1 * c2 * s3 - s1 * s2 * c3; | |
this._w = c1 * c2 * c3 - s1 * s2 * s3; | |
} else if ( order === 'XZY' ) { | |
this._x = s1 * c2 * c3 - c1 * s2 * s3; | |
this._y = c1 * s2 * c3 - s1 * c2 * s3; | |
this._z = c1 * c2 * s3 + s1 * s2 * c3; | |
this._w = c1 * c2 * c3 + s1 * s2 * s3; | |
} | |
if ( update !== false ) { this._onChangeCallback(); } | |
return this; | |
}, | |
setFromAxisAngle: function ( axis, angle ) { | |
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm | |
// assumes axis is normalized | |
var halfAngle = angle / 2, s = Math.sin( halfAngle ); | |
this._x = axis.x * s; | |
this._y = axis.y * s; | |
this._z = axis.z * s; | |
this._w = Math.cos( halfAngle ); | |
this._onChangeCallback(); | |
return this; | |
}, | |
setFromRotationMatrix: function ( m ) { | |
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm | |
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) | |
var te = m.elements, | |
m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], | |
m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], | |
m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], | |
trace = m11 + m22 + m33, | |
s; | |
if ( trace > 0 ) { | |
s = 0.5 / Math.sqrt( trace + 1.0 ); | |
this._w = 0.25 / s; | |
this._x = ( m32 - m23 ) * s; | |
this._y = ( m13 - m31 ) * s; | |
this._z = ( m21 - m12 ) * s; | |
} else if ( m11 > m22 && m11 > m33 ) { | |
s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); | |
this._w = ( m32 - m23 ) / s; | |
this._x = 0.25 * s; | |
this._y = ( m12 + m21 ) / s; | |
this._z = ( m13 + m31 ) / s; | |
} else if ( m22 > m33 ) { | |
s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); | |
this._w = ( m13 - m31 ) / s; | |
this._x = ( m12 + m21 ) / s; | |
this._y = 0.25 * s; | |
this._z = ( m23 + m32 ) / s; | |
} else { | |
s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); | |
this._w = ( m21 - m12 ) / s; | |
this._x = ( m13 + m31 ) / s; | |
this._y = ( m23 + m32 ) / s; | |
this._z = 0.25 * s; | |
} | |
this._onChangeCallback(); | |
return this; | |
}, | |
setFromUnitVectors: function ( vFrom, vTo ) { | |
// assumes direction vectors vFrom and vTo are normalized | |
var EPS = 0.000001; | |
var r = vFrom.dot( vTo ) + 1; | |
if ( r < EPS ) { | |
r = 0; | |
if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { | |
this._x = - vFrom.y; | |
this._y = vFrom.x; | |
this._z = 0; | |
this._w = r; | |
} else { | |
this._x = 0; | |
this._y = - vFrom.z; | |
this._z = vFrom.y; | |
this._w = r; | |
} | |
} else { | |
// crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 | |
this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; | |
this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; | |
this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; | |
this._w = r; | |
} | |
return this.normalize(); | |
}, | |
angleTo: function ( q ) { | |
return 2 * Math.acos( Math.abs( MathUtils.clamp( this.dot( q ), - 1, 1 ) ) ); | |
}, | |
rotateTowards: function ( q, step ) { | |
var angle = this.angleTo( q ); | |
if ( angle === 0 ) { return this; } | |
var t = Math.min( 1, step / angle ); | |
this.slerp( q, t ); | |
return this; | |
}, | |
inverse: function () { | |
// quaternion is assumed to have unit length | |
return this.conjugate(); | |
}, | |
conjugate: function () { | |
this._x *= - 1; | |
this._y *= - 1; | |
this._z *= - 1; | |
this._onChangeCallback(); | |
return this; | |
}, | |
dot: function ( v ) { | |
return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._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 l = this.length(); | |
if ( l === 0 ) { | |
this._x = 0; | |
this._y = 0; | |
this._z = 0; | |
this._w = 1; | |
} else { | |
l = 1 / l; | |
this._x = this._x * l; | |
this._y = this._y * l; | |
this._z = this._z * l; | |
this._w = this._w * l; | |
} | |
this._onChangeCallback(); | |
return this; | |
}, | |
multiply: function ( q, p ) { | |
if ( p !== undefined ) { | |
console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); | |
return this.multiplyQuaternions( q, p ); | |
} | |
return this.multiplyQuaternions( this, q ); | |
}, | |
premultiply: function ( q ) { | |
return this.multiplyQuaternions( q, this ); | |
}, | |
multiplyQuaternions: function ( a, b ) { | |
// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm | |
var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; | |
var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; | |
this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; | |
this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; | |
this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; | |
this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; | |
this._onChangeCallback(); | |
return this; | |
}, | |
slerp: function ( qb, t ) { | |
if ( t === 0 ) { return this; } | |
if ( t === 1 ) { return this.copy( qb ); } | |
var x = this._x, y = this._y, z = this._z, w = this._w; | |
// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ | |
var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; | |
if ( cosHalfTheta < 0 ) { | |
this._w = - qb._w; | |
this._x = - qb._x; | |
this._y = - qb._y; | |
this._z = - qb._z; | |
cosHalfTheta = - cosHalfTheta; | |
} else { | |
this.copy( qb ); | |
} | |
if ( cosHalfTheta >= 1.0 ) { | |
this._w = w; | |
this._x = x; | |
this._y = y; | |
this._z = z; | |
return this; | |
} | |
var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; | |
if ( sqrSinHalfTheta <= Number.EPSILON ) { | |
var s = 1 - t; | |
this._w = s * w + t * this._w; | |
this._x = s * x + t * this._x; | |
this._y = s * y + t * this._y; | |
this._z = s * z + t * this._z; | |
this.normalize(); | |
this._onChangeCallback(); | |
return this; | |
} | |
var sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); | |
var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); | |
var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, | |
ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; | |
this._w = ( w * ratioA + this._w * ratioB ); | |
this._x = ( x * ratioA + this._x * ratioB ); | |
this._y = ( y * ratioA + this._y * ratioB ); | |
this._z = ( z * ratioA + this._z * ratioB ); | |
this._onChangeCallback(); | |
return this; | |
}, | |
equals: function ( quaternion ) { | |
return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); | |
}, | |
fromArray: function ( array, offset ) { | |
if ( offset === undefined ) { offset = 0; } | |
this._x = array[ offset ]; | |
this._y = array[ offset + 1 ]; | |
this._z = array[ offset + 2 ]; | |
this._w = array[ offset + 3 ]; | |
this._onChangeCallback(); | |
return this; | |
}, | |
toArray: function ( array, offset ) { | |
if ( array === undefined ) { array = []; } | |
if ( offset === undefined ) { offset = 0; } | |
array[ offset ] = this._x; | |
array[ offset + 1 ] = this._y; | |
array[ offset + 2 ] = this._z; | |
array[ offset + 3 ] = this._w; | |
return array; | |
}, | |
fromBufferAttribute: function ( attribute, index ) { | |
this._x = attribute.getX( index ); | |
this._y = attribute.getY( index ); | |
this._z = attribute.getZ( index ); | |
this._w = attribute.getW( index ); | |
return this; | |
}, | |
_onChange: function ( callback ) { | |
this._onChangeCallback = callback; | |
return this; | |
}, | |
_onChangeCallback: function () {} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author kile / http://kile.stravaganza.org/ | |
* @author philogb / http://blog.thejit.org/ | |
* @author mikael emtinger / http://gomo.se/ | |
* @author egraether / http://egraether.com/ | |
* @author WestLangley / http://github.com/WestLangley | |
*/ | |
var _vector = new Vector3(); | |
var _quaternion = new Quaternion(); | |
function Vector3( x, y, z ) { | |
this.x = x || 0; | |
this.y = y || 0; | |
this.z = z || 0; | |
} | |
Object.assign( Vector3.prototype, { | |
isVector3: true, | |
set: function ( x, y, z ) { | |
this.x = x; | |
this.y = y; | |
this.z = z; | |
return this; | |
}, | |
setScalar: function ( scalar ) { | |
this.x = scalar; | |
this.y = scalar; | |
this.z = scalar; | |
return this; | |
}, | |
setX: function ( x ) { | |
this.x = x; | |
return this; | |
}, | |
setY: function ( y ) { | |
this.y = y; | |
return this; | |
}, | |
setZ: function ( z ) { | |
this.z = z; | |
return this; | |
}, | |
setComponent: function ( index, value ) { | |
switch ( index ) { | |
case 0: this.x = value; break; | |
case 1: this.y = value; break; | |
case 2: this.z = value; break; | |
default: throw new Error( 'index is out of range: ' + index ); | |
} | |
return this; | |
}, | |
getComponent: function ( index ) { | |
switch ( index ) { | |
case 0: return this.x; | |
case 1: return this.y; | |
case 2: return this.z; | |
default: throw new Error( 'index is out of range: ' + index ); | |
} | |
}, | |
clone: function () { | |
return new this.constructor( this.x, this.y, this.z ); | |
}, | |
copy: function ( v ) { | |
this.x = v.x; | |
this.y = v.y; | |
this.z = v.z; | |
return this; | |
}, | |
add: function ( v, w ) { | |
if ( w !== undefined ) { | |
console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); | |
return this.addVectors( v, w ); | |
} | |
this.x += v.x; | |
this.y += v.y; | |
this.z += v.z; | |
return this; | |
}, | |
addScalar: function ( s ) { | |
this.x += s; | |
this.y += s; | |
this.z += s; | |
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 ( v, s ) { | |
this.x += v.x * s; | |
this.y += v.y * s; | |
this.z += v.z * s; | |
return this; | |
}, | |
sub: function ( v, w ) { | |
if ( w !== undefined ) { | |
console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); | |
return this.subVectors( v, w ); | |
} | |
this.x -= v.x; | |
this.y -= v.y; | |
this.z -= v.z; | |
return this; | |
}, | |
subScalar: function ( s ) { | |
this.x -= s; | |
this.y -= s; | |
this.z -= s; | |
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 ( v, w ) { | |
if ( w !== undefined ) { | |
console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); | |
return this.multiplyVectors( v, w ); | |
} | |
this.x *= v.x; | |
this.y *= v.y; | |
this.z *= v.z; | |
return this; | |
}, | |
multiplyScalar: function ( scalar ) { | |
this.x *= scalar; | |
this.y *= scalar; | |
this.z *= scalar; | |
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 ( euler ) { | |
if ( ! ( euler && euler.isEuler ) ) { | |
console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); | |
} | |
return this.applyQuaternion( _quaternion.setFromEuler( euler ) ); | |
}, | |
applyAxisAngle: function ( axis, angle ) { | |
return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) ); | |
}, | |
applyMatrix3: function ( m ) { | |
var x = this.x, y = this.y, z = this.z; | |
var e = m.elements; | |
this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; | |
this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z; | |
this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z; | |
return this; | |
}, | |
applyNormalMatrix: function ( m ) { | |
return this.applyMatrix3( m ).normalize(); | |
}, | |
applyMatrix4: function ( m ) { | |
var x = this.x, y = this.y, z = this.z; | |
var e = m.elements; | |
var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); | |
this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; | |
this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; | |
this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; | |
return this; | |
}, | |
applyQuaternion: function ( q ) { | |
var x = this.x, y = this.y, z = this.z; | |
var qx = q.x, qy = q.y, qz = q.z, qw = q.w; | |
// calculate quat * vector | |
var ix = qw * x + qy * z - qz * y; | |
var iy = qw * y + qz * x - qx * z; | |
var iz = qw * z + qx * y - qy * x; | |
var iw = - qx * x - qy * y - qz * z; | |
// calculate result * inverse quat | |
this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; | |
this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; | |
this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; | |
return this; | |
}, | |
project: function ( camera ) { | |
return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix ); | |
}, | |
unproject: function ( camera ) { | |
return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld ); | |
}, | |
transformDirection: function ( m ) { | |
// input: THREE.Matrix4 affine matrix | |
// vector interpreted as a direction | |
var x = this.x, y = this.y, z = this.z; | |
var e = m.elements; | |
this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; | |
this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; | |
this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; | |
return this.normalize(); | |
}, | |
divide: function ( v ) { | |
this.x /= v.x; | |
this.y /= v.y; | |
this.z /= v.z; | |
return this; | |
}, | |
divideScalar: function ( scalar ) { | |
return this.multiplyScalar( 1 / scalar ); | |
}, | |
min: function ( v ) { | |
this.x = Math.min( this.x, v.x ); | |
this.y = Math.min( this.y, v.y ); | |
this.z = Math.min( this.z, v.z ); | |
return this; | |
}, | |
max: function ( v ) { | |
this.x = Math.max( this.x, v.x ); | |
this.y = Math.max( this.y, v.y ); | |
this.z = Math.max( this.z, v.z ); | |
return this; | |
}, | |
clamp: function ( min, max ) { | |
// assumes min < max, componentwise | |
this.x = Math.max( min.x, Math.min( max.x, this.x ) ); | |
this.y = Math.max( min.y, Math.min( max.y, this.y ) ); | |
this.z = Math.max( min.z, Math.min( max.z, this.z ) ); | |
return this; | |
}, | |
clampScalar: function ( minVal, maxVal ) { | |
this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); | |
this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); | |
this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); | |
return this; | |
}, | |
clampLength: function ( min, max ) { | |
var length = this.length(); | |
return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); | |
}, | |
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 = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); | |
this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); | |
this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); | |
return this; | |
}, | |
negate: function () { | |
this.x = - this.x; | |
this.y = - this.y; | |
this.z = - this.z; | |
return this; | |
}, | |
dot: function ( v ) { | |
return this.x * v.x + this.y * v.y + this.z * v.z; | |
}, | |
// TODO lengthSquared? | |
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 ( length ) { | |
return this.normalize().multiplyScalar( length ); | |
}, | |
lerp: function ( v, alpha ) { | |
this.x += ( v.x - this.x ) * alpha; | |
this.y += ( v.y - this.y ) * alpha; | |
this.z += ( v.z - this.z ) * alpha; | |
return this; | |
}, | |
lerpVectors: function ( v1, v2, alpha ) { | |
return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); | |
}, | |
cross: function ( v, w ) { | |
if ( w !== undefined ) { | |
console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); | |
return this.crossVectors( v, w ); | |
} | |
return this.crossVectors( this, v ); | |
}, | |
crossVectors: function ( a, b ) { | |
var ax = a.x, ay = a.y, az = a.z; | |
var bx = b.x, by = b.y, bz = b.z; | |
this.x = ay * bz - az * by; | |
this.y = az * bx - ax * bz; | |
this.z = ax * by - ay * bx; | |
return this; | |
}, | |
projectOnVector: function ( v ) { | |
var denominator = v.lengthSq(); | |
if ( denominator === 0 ) { return this.set( 0, 0, 0 ); } | |
var scalar = v.dot( this ) / denominator; | |
return this.copy( v ).multiplyScalar( scalar ); | |
}, | |
projectOnPlane: function ( planeNormal ) { | |
_vector.copy( this ).projectOnVector( planeNormal ); | |
return this.sub( _vector ); | |
}, | |
reflect: function ( normal ) { | |
// reflect incident vector off plane orthogonal to normal | |
// normal is assumed to have unit length | |
return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); | |
}, | |
angleTo: function ( v ) { | |
var denominator = Math.sqrt( this.lengthSq() * v.lengthSq() ); | |
if ( denominator === 0 ) { return Math.PI / 2; } | |
var theta = this.dot( v ) / denominator; | |
// clamp, to handle numerical problems | |
return Math.acos( MathUtils.clamp( theta, - 1, 1 ) ); | |
}, | |
distanceTo: function ( v ) { | |
return Math.sqrt( this.distanceToSquared( v ) ); | |
}, | |
distanceToSquared: function ( v ) { | |
var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; | |
return dx * dx + dy * dy + dz * dz; | |
}, | |
manhattanDistanceTo: function ( v ) { | |
return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z ); | |
}, | |
setFromSpherical: function ( s ) { | |
return this.setFromSphericalCoords( s.radius, s.phi, s.theta ); | |
}, | |
setFromSphericalCoords: function ( radius, phi, theta ) { | |
var sinPhiRadius = Math.sin( phi ) * radius; | |
this.x = sinPhiRadius * Math.sin( theta ); | |
this.y = Math.cos( phi ) * radius; | |
this.z = sinPhiRadius * Math.cos( theta ); | |
return this; | |
}, | |
setFromCylindrical: function ( c ) { | |
return this.setFromCylindricalCoords( c.radius, c.theta, c.y ); | |
}, | |
setFromCylindricalCoords: function ( radius, theta, y ) { | |
this.x = radius * Math.sin( theta ); | |
this.y = y; | |
this.z = radius * Math.cos( theta ); | |
return this; | |
}, | |
setFromMatrixPosition: function ( m ) { | |
var e = m.elements; | |
this.x = e[ 12 ]; | |
this.y = e[ 13 ]; | |
this.z = e[ 14 ]; | |
return this; | |
}, | |
setFromMatrixScale: function ( m ) { | |
var sx = this.setFromMatrixColumn( m, 0 ).length(); | |
var sy = this.setFromMatrixColumn( m, 1 ).length(); | |
var sz = this.setFromMatrixColumn( m, 2 ).length(); | |
this.x = sx; | |
this.y = sy; | |
this.z = sz; | |
return this; | |
}, | |
setFromMatrixColumn: function ( m, index ) { | |
return this.fromArray( m.elements, index * 4 ); | |
}, | |
setFromMatrix3Column: function ( m, index ) { | |
return this.fromArray( m.elements, index * 3 ); | |
}, | |
equals: function ( v ) { | |
return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); | |
}, | |
fromArray: function ( array, offset ) { | |
if ( offset === undefined ) { offset = 0; } | |
this.x = array[ offset ]; | |
this.y = array[ offset + 1 ]; | |
this.z = array[ offset + 2 ]; | |
return this; | |
}, | |
toArray: function ( array, offset ) { | |
if ( array === undefined ) { array = []; } | |
if ( offset === undefined ) { offset = 0; } | |
array[ offset ] = this.x; | |
array[ offset + 1 ] = this.y; | |
array[ offset + 2 ] = this.z; | |
return array; | |
}, | |
fromBufferAttribute: function ( attribute, index, offset ) { | |
if ( offset !== undefined ) { | |
console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); | |
} | |
this.x = attribute.getX( index ); | |
this.y = attribute.getY( index ); | |
this.z = attribute.getZ( index ); | |
return this; | |
} | |
} ); | |
var _v1 = new Vector3(); | |
var _m1 = new Matrix4(); | |
var _zero = new Vector3( 0, 0, 0 ); | |
var _one = new Vector3( 1, 1, 1 ); | |
var _x = new Vector3(); | |
var _y = new Vector3(); | |
var _z = new Vector3(); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author supereggbert / http://www.paulbrunt.co.uk/ | |
* @author philogb / http://blog.thejit.org/ | |
* @author jordi_ros / http://plattsoft.com | |
* @author D1plo1d / http://github.com/D1plo1d | |
* @author alteredq / http://alteredqualia.com/ | |
* @author mikael emtinger / http://gomo.se/ | |
* @author timknip / http://www.floorplanner.com/ | |
* @author bhouston / http://clara.io | |
* @author WestLangley / http://github.com/WestLangley | |
*/ | |
function Matrix4() { | |
this.elements = [ | |
1, 0, 0, 0, | |
0, 1, 0, 0, | |
0, 0, 1, 0, | |
0, 0, 0, 1 | |
]; | |
if ( arguments.length > 0 ) { | |
console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); | |
} | |
} | |
Object.assign( Matrix4.prototype, { | |
isMatrix4: true, | |
set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { | |
var te = this.elements; | |
te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; | |
te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; | |
te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; | |
te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; | |
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 Matrix4().fromArray( this.elements ); | |
}, | |
copy: function ( m ) { | |
var te = this.elements; | |
var me = m.elements; | |
te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; | |
te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; | |
te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; | |
te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; | |
return this; | |
}, | |
copyPosition: function ( m ) { | |
var te = this.elements, me = m.elements; | |
te[ 12 ] = me[ 12 ]; | |
te[ 13 ] = me[ 13 ]; | |
te[ 14 ] = me[ 14 ]; | |
return this; | |
}, | |
extractBasis: function ( xAxis, yAxis, zAxis ) { | |
xAxis.setFromMatrixColumn( this, 0 ); | |
yAxis.setFromMatrixColumn( this, 1 ); | |
zAxis.setFromMatrixColumn( this, 2 ); | |
return this; | |
}, | |
makeBasis: function ( xAxis, yAxis, zAxis ) { | |
this.set( | |
xAxis.x, yAxis.x, zAxis.x, 0, | |
xAxis.y, yAxis.y, zAxis.y, 0, | |
xAxis.z, yAxis.z, zAxis.z, 0, | |
0, 0, 0, 1 | |
); | |
return this; | |
}, | |
extractRotation: function ( m ) { | |
// this method does not support reflection matrices | |
var te = this.elements; | |
var me = m.elements; | |
var scaleX = 1 / _v1.setFromMatrixColumn( m, 0 ).length(); | |
var scaleY = 1 / _v1.setFromMatrixColumn( m, 1 ).length(); | |
var scaleZ = 1 / _v1.setFromMatrixColumn( m, 2 ).length(); | |
te[ 0 ] = me[ 0 ] * scaleX; | |
te[ 1 ] = me[ 1 ] * scaleX; | |
te[ 2 ] = me[ 2 ] * scaleX; | |
te[ 3 ] = 0; | |
te[ 4 ] = me[ 4 ] * scaleY; | |
te[ 5 ] = me[ 5 ] * scaleY; | |
te[ 6 ] = me[ 6 ] * scaleY; | |
te[ 7 ] = 0; | |
te[ 8 ] = me[ 8 ] * scaleZ; | |
te[ 9 ] = me[ 9 ] * scaleZ; | |
te[ 10 ] = me[ 10 ] * scaleZ; | |
te[ 11 ] = 0; | |
te[ 12 ] = 0; | |
te[ 13 ] = 0; | |
te[ 14 ] = 0; | |
te[ 15 ] = 1; | |
return this; | |
}, | |
makeRotationFromEuler: function ( euler ) { | |
if ( ! ( euler && euler.isEuler ) ) { | |
console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); | |
} | |
var te = this.elements; | |
var x = euler.x, y = euler.y, z = euler.z; | |
var a = Math.cos( x ), b = Math.sin( x ); | |
var c = Math.cos( y ), d = Math.sin( y ); | |
var e = Math.cos( z ), f = Math.sin( z ); | |
if ( euler.order === 'XYZ' ) { | |
var ae = a * e, af = a * f, be = b * e, bf = b * f; | |
te[ 0 ] = c * e; | |
te[ 4 ] = - c * f; | |
te[ 8 ] = d; | |
te[ 1 ] = af + be * d; | |
te[ 5 ] = ae - bf * d; | |
te[ 9 ] = - b * c; | |
te[ 2 ] = bf - ae * d; | |
te[ 6 ] = be + af * d; | |
te[ 10 ] = a * c; | |
} else if ( euler.order === 'YXZ' ) { | |
var ce = c * e, cf = c * f, de = d * e, df = d * f; | |
te[ 0 ] = ce + df * b; | |
te[ 4 ] = de * b - cf; | |
te[ 8 ] = a * d; | |
te[ 1 ] = a * f; | |
te[ 5 ] = a * e; | |
te[ 9 ] = - b; | |
te[ 2 ] = cf * b - de; | |
te[ 6 ] = df + ce * b; | |
te[ 10 ] = a * c; | |
} else if ( euler.order === 'ZXY' ) { | |
var ce = c * e, cf = c * f, de = d * e, df = d * f; | |
te[ 0 ] = ce - df * b; | |
te[ 4 ] = - a * f; | |
te[ 8 ] = de + cf * b; | |
te[ 1 ] = cf + de * b; | |
te[ 5 ] = a * e; | |
te[ 9 ] = df - ce * b; | |
te[ 2 ] = - a * d; | |
te[ 6 ] = b; | |
te[ 10 ] = a * c; | |
} else if ( euler.order === 'ZYX' ) { | |
var ae = a * e, af = a * f, be = b * e, bf = b * f; | |
te[ 0 ] = c * e; | |
te[ 4 ] = be * d - af; | |
te[ 8 ] = ae * d + bf; | |
te[ 1 ] = c * f; | |
te[ 5 ] = bf * d + ae; | |
te[ 9 ] = af * d - be; | |
te[ 2 ] = - d; | |
te[ 6 ] = b * c; | |
te[ 10 ] = a * c; | |
} else if ( euler.order === 'YZX' ) { | |
var ac = a * c, ad = a * d, bc = b * c, bd = b * d; | |
te[ 0 ] = c * e; | |
te[ 4 ] = bd - ac * f; | |
te[ 8 ] = bc * f + ad; | |
te[ 1 ] = f; | |
te[ 5 ] = a * e; | |
te[ 9 ] = - b * e; | |
te[ 2 ] = - d * e; | |
te[ 6 ] = ad * f + bc; | |
te[ 10 ] = ac - bd * f; | |
} else if ( euler.order === 'XZY' ) { | |
var ac = a * c, ad = a * d, bc = b * c, bd = b * d; | |
te[ 0 ] = c * e; | |
te[ 4 ] = - f; | |
te[ 8 ] = d * e; | |
te[ 1 ] = ac * f + bd; | |
te[ 5 ] = a * e; | |
te[ 9 ] = ad * f - bc; | |
te[ 2 ] = bc * f - ad; | |
te[ 6 ] = b * e; | |
te[ 10 ] = bd * f + ac; | |
} | |
// bottom row | |
te[ 3 ] = 0; | |
te[ 7 ] = 0; | |
te[ 11 ] = 0; | |
// last column | |
te[ 12 ] = 0; | |
te[ 13 ] = 0; | |
te[ 14 ] = 0; | |
te[ 15 ] = 1; | |
return this; | |
}, | |
makeRotationFromQuaternion: function ( q ) { | |
return this.compose( _zero, q, _one ); | |
}, | |
lookAt: function ( eye, target, up ) { | |
var te = this.elements; | |
_z.subVectors( eye, target ); | |
if ( _z.lengthSq() === 0 ) { | |
// eye and target are in the same position | |
_z.z = 1; | |
} | |
_z.normalize(); | |
_x.crossVectors( up, _z ); | |
if ( _x.lengthSq() === 0 ) { | |
// up and z are parallel | |
if ( Math.abs( up.z ) === 1 ) { | |
_z.x += 0.0001; | |
} else { | |
_z.z += 0.0001; | |
} | |
_z.normalize(); | |
_x.crossVectors( up, _z ); | |
} | |
_x.normalize(); | |
_y.crossVectors( _z, _x ); | |
te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x; | |
te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y; | |
te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z; | |
return this; | |
}, | |
multiply: function ( m, n ) { | |
if ( n !== undefined ) { | |
console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); | |
return this.multiplyMatrices( m, n ); | |
} | |
return this.multiplyMatrices( this, m ); | |
}, | |
premultiply: function ( m ) { | |
return this.multiplyMatrices( m, this ); | |
}, | |
multiplyMatrices: function ( a, b ) { | |
var ae = a.elements; | |
var be = b.elements; | |
var te = this.elements; | |
var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; | |
var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; | |
var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; | |
var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; | |
var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; | |
var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; | |
var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; | |
var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; | |
te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; | |
te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; | |
te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; | |
te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; | |
te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; | |
te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; | |
te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; | |
te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; | |
te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; | |
te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; | |
te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; | |
te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; | |
te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; | |
te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; | |
te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; | |
te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; | |
return this; | |
}, | |
multiplyScalar: function ( s ) { | |
var te = this.elements; | |
te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; | |
te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; | |
te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; | |
te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; | |
return this; | |
}, | |
determinant: function () { | |
var te = this.elements; | |
var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; | |
var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; | |
var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; | |
var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; | |
//TODO: make this more efficient | |
//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) | |
return ( | |
n41 * ( | |
+ n14 * n23 * n32 | |
- n13 * n24 * n32 | |
- n14 * n22 * n33 | |
+ n12 * n24 * n33 | |
+ n13 * n22 * n34 | |
- n12 * n23 * n34 | |
) + | |
n42 * ( | |
+ n11 * n23 * n34 | |
- n11 * n24 * n33 | |
+ n14 * n21 * n33 | |
- n13 * n21 * n34 | |
+ n13 * n24 * n31 | |
- n14 * n23 * n31 | |
) + | |
n43 * ( | |
+ n11 * n24 * n32 | |
- n11 * n22 * n34 | |
- n14 * n21 * n32 | |
+ n12 * n21 * n34 | |
+ n14 * n22 * n31 | |
- n12 * n24 * n31 | |
) + | |
n44 * ( | |
- n13 * n22 * n31 | |
- n11 * n23 * n32 | |
+ n11 * n22 * n33 | |
+ n13 * n21 * n32 | |
- n12 * n21 * n33 | |
+ n12 * n23 * n31 | |
) | |
); | |
}, | |
transpose: function () { | |
var te = this.elements; | |
var tmp; | |
tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; | |
tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; | |
tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; | |
tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; | |
tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; | |
tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; | |
return this; | |
}, | |
setPosition: function ( x, y, z ) { | |
var te = this.elements; | |
if ( x.isVector3 ) { | |
te[ 12 ] = x.x; | |
te[ 13 ] = x.y; | |
te[ 14 ] = x.z; | |
} else { | |
te[ 12 ] = x; | |
te[ 13 ] = y; | |
te[ 14 ] = z; | |
} | |
return this; | |
}, | |
getInverse: function ( m, throwOnDegenerate ) { | |
if ( throwOnDegenerate !== undefined ) { | |
console.warn( "THREE.Matrix4: .getInverse() can no longer be configured to throw on degenerate." ); | |
} | |
// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm | |
var te = this.elements, | |
me = m.elements, | |
n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ], | |
n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ], | |
n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ], | |
n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ], | |
t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, | |
t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, | |
t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, | |
t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; | |
var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; | |
if ( det === 0 ) { return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); } | |
var detInv = 1 / det; | |
te[ 0 ] = t11 * detInv; | |
te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv; | |
te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv; | |
te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv; | |
te[ 4 ] = t12 * detInv; | |
te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv; | |
te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv; | |
te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv; | |
te[ 8 ] = t13 * detInv; | |
te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv; | |
te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv; | |
te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv; | |
te[ 12 ] = t14 * detInv; | |
te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv; | |
te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv; | |
te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv; | |
return this; | |
}, | |
scale: function ( v ) { | |
var te = this.elements; | |
var x = v.x, y = v.y, z = v.z; | |
te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; | |
te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; | |
te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; | |
te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; | |
return this; | |
}, | |
getMaxScaleOnAxis: function () { | |
var te = this.elements; | |
var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; | |
var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; | |
var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; | |
return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); | |
}, | |
makeTranslation: function ( x, y, z ) { | |
this.set( | |
1, 0, 0, x, | |
0, 1, 0, y, | |
0, 0, 1, z, | |
0, 0, 0, 1 | |
); | |
return this; | |
}, | |
makeRotationX: function ( theta ) { | |
var c = Math.cos( theta ), s = Math.sin( theta ); | |
this.set( | |
1, 0, 0, 0, | |
0, c, - s, 0, | |
0, s, c, 0, | |
0, 0, 0, 1 | |
); | |
return this; | |
}, | |
makeRotationY: function ( theta ) { | |
var c = Math.cos( theta ), s = Math.sin( theta ); | |
this.set( | |
c, 0, s, 0, | |
0, 1, 0, 0, | |
- s, 0, c, 0, | |
0, 0, 0, 1 | |
); | |
return this; | |
}, | |
makeRotationZ: function ( theta ) { | |
var c = Math.cos( theta ), s = Math.sin( theta ); | |
this.set( | |
c, - s, 0, 0, | |
s, c, 0, 0, | |
0, 0, 1, 0, | |
0, 0, 0, 1 | |
); | |
return this; | |
}, | |
makeRotationAxis: function ( axis, angle ) { | |
// Based on http://www.gamedev.net/reference/articles/article1199.asp | |
var c = Math.cos( angle ); | |
var s = Math.sin( angle ); | |
var t = 1 - c; | |
var x = axis.x, y = axis.y, z = axis.z; | |
var tx = t * x, ty = t * y; | |
this.set( | |
tx * x + c, tx * y - s * z, tx * z + s * y, 0, | |
tx * y + s * z, ty * y + c, ty * z - s * x, 0, | |
tx * z - s * y, ty * z + s * x, t * z * z + c, 0, | |
0, 0, 0, 1 | |
); | |
return this; | |
}, | |
makeScale: function ( x, y, z ) { | |
this.set( | |
x, 0, 0, 0, | |
0, y, 0, 0, | |
0, 0, z, 0, | |
0, 0, 0, 1 | |
); | |
return this; | |
}, | |
makeShear: function ( x, y, z ) { | |
this.set( | |
1, y, z, 0, | |
x, 1, z, 0, | |
x, y, 1, 0, | |
0, 0, 0, 1 | |
); | |
return this; | |
}, | |
compose: function ( position, quaternion, scale ) { | |
var te = this.elements; | |
var x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; | |
var x2 = x + x, y2 = y + y, z2 = z + z; | |
var xx = x * x2, xy = x * y2, xz = x * z2; | |
var yy = y * y2, yz = y * z2, zz = z * z2; | |
var wx = w * x2, wy = w * y2, wz = w * z2; | |
var sx = scale.x, sy = scale.y, sz = scale.z; | |
te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; | |
te[ 1 ] = ( xy + wz ) * sx; | |
te[ 2 ] = ( xz - wy ) * sx; | |
te[ 3 ] = 0; | |
te[ 4 ] = ( xy - wz ) * sy; | |
te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; | |
te[ 6 ] = ( yz + wx ) * sy; | |
te[ 7 ] = 0; | |
te[ 8 ] = ( xz + wy ) * sz; | |
te[ 9 ] = ( yz - wx ) * sz; | |
te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; | |
te[ 11 ] = 0; | |
te[ 12 ] = position.x; | |
te[ 13 ] = position.y; | |
te[ 14 ] = position.z; | |
te[ 15 ] = 1; | |
return this; | |
}, | |
decompose: function ( position, quaternion, scale ) { | |
var te = this.elements; | |
var sx = _v1.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); | |
var sy = _v1.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); | |
var sz = _v1.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); | |
// if determine is negative, we need to invert one scale | |
var det = this.determinant(); | |
if ( det < 0 ) { sx = - sx; } | |
position.x = te[ 12 ]; | |
position.y = te[ 13 ]; | |
position.z = te[ 14 ]; | |
// scale the rotation part | |
_m1.copy( this ); | |
var invSX = 1 / sx; | |
var invSY = 1 / sy; | |
var invSZ = 1 / sz; | |
_m1.elements[ 0 ] *= invSX; | |
_m1.elements[ 1 ] *= invSX; | |
_m1.elements[ 2 ] *= invSX; | |
_m1.elements[ 4 ] *= invSY; | |
_m1.elements[ 5 ] *= invSY; | |
_m1.elements[ 6 ] *= invSY; | |
_m1.elements[ 8 ] *= invSZ; | |
_m1.elements[ 9 ] *= invSZ; | |
_m1.elements[ 10 ] *= invSZ; | |
quaternion.setFromRotationMatrix( _m1 ); | |
scale.x = sx; | |
scale.y = sy; | |
scale.z = sz; | |
return this; | |
}, | |
makePerspective: function ( left, right, top, bottom, near, far ) { | |
if ( far === undefined ) { | |
console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' ); | |
} | |
var te = this.elements; | |
var x = 2 * near / ( right - left ); | |
var y = 2 * near / ( top - bottom ); | |
var a = ( right + left ) / ( right - left ); | |
var b = ( top + bottom ) / ( top - bottom ); | |
var c = - ( far + near ) / ( far - near ); | |
var d = - 2 * far * near / ( far - near ); | |
te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; | |
te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; | |
te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; | |
te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0; | |
return this; | |
}, | |
makeOrthographic: function ( left, right, top, bottom, near, far ) { | |
var te = this.elements; | |
var w = 1.0 / ( right - left ); | |
var h = 1.0 / ( top - bottom ); | |
var p = 1.0 / ( far - near ); | |
var x = ( right + left ) * w; | |
var y = ( top + bottom ) * h; | |
var z = ( far + near ) * p; | |
te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x; | |
te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y; | |
te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z; | |
te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; | |
return this; | |
}, | |
equals: function ( matrix ) { | |
var te = this.elements; | |
var me = matrix.elements; | |
for ( var i = 0; i < 16; i ++ ) { | |
if ( te[ i ] !== me[ i ] ) { return false; } | |
} | |
return true; | |
}, | |
fromArray: function ( array, offset ) { | |
if ( offset === undefined ) { offset = 0; } | |
for ( var i = 0; i < 16; i ++ ) { | |
this.elements[ i ] = array[ i + offset ]; | |
} | |
return this; | |
}, | |
toArray: function ( array, offset ) { | |
if ( array === undefined ) { array = []; } | |
if ( offset === undefined ) { offset = 0; } | |
var te = this.elements; | |
array[ offset ] = te[ 0 ]; | |
array[ offset + 1 ] = te[ 1 ]; | |
array[ offset + 2 ] = te[ 2 ]; | |
array[ offset + 3 ] = te[ 3 ]; | |
array[ offset + 4 ] = te[ 4 ]; | |
array[ offset + 5 ] = te[ 5 ]; | |
array[ offset + 6 ] = te[ 6 ]; | |
array[ offset + 7 ] = te[ 7 ]; | |
array[ offset + 8 ] = te[ 8 ]; | |
array[ offset + 9 ] = te[ 9 ]; | |
array[ offset + 10 ] = te[ 10 ]; | |
array[ offset + 11 ] = te[ 11 ]; | |
array[ offset + 12 ] = te[ 12 ]; | |
array[ offset + 13 ] = te[ 13 ]; | |
array[ offset + 14 ] = te[ 14 ]; | |
array[ offset + 15 ] = te[ 15 ]; | |
return array; | |
} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author WestLangley / http://github.com/WestLangley | |
* @author bhouston / http://clara.io | |
*/ | |
var _matrix = new Matrix4(); | |
var _quaternion$1 = new Quaternion(); | |
function Euler( x, y, z, order ) { | |
this._x = x || 0; | |
this._y = y || 0; | |
this._z = z || 0; | |
this._order = order || Euler.DefaultOrder; | |
} | |
Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]; | |
Euler.DefaultOrder = 'XYZ'; | |
Object.defineProperties( Euler.prototype, { | |
x: { | |
get: function () { | |
return this._x; | |
}, | |
set: function ( value ) { | |
this._x = value; | |
this._onChangeCallback(); | |
} | |
}, | |
y: { | |
get: function () { | |
return this._y; | |
}, | |
set: function ( value ) { | |
this._y = value; | |
this._onChangeCallback(); | |
} | |
}, | |
z: { | |
get: function () { | |
return this._z; | |
}, | |
set: function ( value ) { | |
this._z = value; | |
this._onChangeCallback(); | |
} | |
}, | |
order: { | |
get: function () { | |
return this._order; | |
}, | |
set: function ( value ) { | |
this._order = value; | |
this._onChangeCallback(); | |
} | |
} | |
} ); | |
Object.assign( Euler.prototype, { | |
isEuler: true, | |
set: function ( x, y, z, order ) { | |
this._x = x; | |
this._y = y; | |
this._z = z; | |
this._order = order || this._order; | |
this._onChangeCallback(); | |
return this; | |
}, | |
clone: function () { | |
return new this.constructor( this._x, this._y, this._z, this._order ); | |
}, | |
copy: function ( euler ) { | |
this._x = euler._x; | |
this._y = euler._y; | |
this._z = euler._z; | |
this._order = euler._order; | |
this._onChangeCallback(); | |
return this; | |
}, | |
setFromRotationMatrix: function ( m, order, update ) { | |
var clamp = MathUtils.clamp; | |
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) | |
var te = m.elements; | |
var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; | |
var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; | |
var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; | |
order = order || this._order; | |
if ( order === 'XYZ' ) { | |
this._y = Math.asin( clamp( m13, - 1, 1 ) ); | |
if ( Math.abs( m13 ) < 0.9999999 ) { | |
this._x = Math.atan2( - m23, m33 ); | |
this._z = Math.atan2( - m12, m11 ); | |
} else { | |
this._x = Math.atan2( m32, m22 ); | |
this._z = 0; | |
} | |
} else if ( order === 'YXZ' ) { | |
this._x = Math.asin( - clamp( m23, - 1, 1 ) ); | |
if ( Math.abs( m23 ) < 0.9999999 ) { | |
this._y = Math.atan2( m13, m33 ); | |
this._z = Math.atan2( m21, m22 ); | |
} else { | |
this._y = Math.atan2( - m31, m11 ); | |
this._z = 0; | |
} | |
} else if ( order === 'ZXY' ) { | |
this._x = Math.asin( clamp( m32, - 1, 1 ) ); | |
if ( Math.abs( m32 ) < 0.9999999 ) { | |
this._y = Math.atan2( - m31, m33 ); | |
this._z = Math.atan2( - m12, m22 ); | |
} else { | |
this._y = 0; | |
this._z = Math.atan2( m21, m11 ); | |
} | |
} else if ( order === 'ZYX' ) { | |
this._y = Math.asin( - clamp( m31, - 1, 1 ) ); | |
if ( Math.abs( m31 ) < 0.9999999 ) { | |
this._x = Math.atan2( m32, m33 ); | |
this._z = Math.atan2( m21, m11 ); | |
} else { | |
this._x = 0; | |
this._z = Math.atan2( - m12, m22 ); | |
} | |
} else if ( order === 'YZX' ) { | |
this._z = Math.asin( clamp( m21, - 1, 1 ) ); | |
if ( Math.abs( m21 ) < 0.9999999 ) { | |
this._x = Math.atan2( - m23, m22 ); | |
this._y = Math.atan2( - m31, m11 ); | |
} else { | |
this._x = 0; | |
this._y = Math.atan2( m13, m33 ); | |
} | |
} else if ( order === 'XZY' ) { | |
this._z = Math.asin( - clamp( m12, - 1, 1 ) ); | |
if ( Math.abs( m12 ) < 0.9999999 ) { | |
this._x = Math.atan2( m32, m22 ); | |
this._y = Math.atan2( m13, m11 ); | |
} else { | |
this._x = Math.atan2( - m23, m33 ); | |
this._y = 0; | |
} | |
} else { | |
console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ); | |
} | |
this._order = order; | |
if ( update !== false ) { this._onChangeCallback(); } | |
return this; | |
}, | |
setFromQuaternion: function ( q, order, update ) { | |
_matrix.makeRotationFromQuaternion( q ); | |
return this.setFromRotationMatrix( _matrix, order, update ); | |
}, | |
setFromVector3: function ( v, order ) { | |
return this.set( v.x, v.y, v.z, order || this._order ); | |
}, | |
reorder: function ( newOrder ) { | |
// WARNING: this discards revolution information -bhouston | |
_quaternion$1.setFromEuler( this ); | |
return this.setFromQuaternion( _quaternion$1, newOrder ); | |
}, | |
equals: function ( euler ) { | |
return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); | |
}, | |
fromArray: function ( array ) { | |
this._x = array[ 0 ]; | |
this._y = array[ 1 ]; | |
this._z = array[ 2 ]; | |
if ( array[ 3 ] !== undefined ) { this._order = array[ 3 ]; } | |
this._onChangeCallback(); | |
return this; | |
}, | |
toArray: function ( array, offset ) { | |
if ( array === undefined ) { array = []; } | |
if ( offset === undefined ) { offset = 0; } | |
array[ offset ] = this._x; | |
array[ offset + 1 ] = this._y; | |
array[ offset + 2 ] = this._z; | |
array[ offset + 3 ] = this._order; | |
return array; | |
}, | |
toVector3: function ( optionalResult ) { | |
if ( optionalResult ) { | |
return optionalResult.set( this._x, this._y, this._z ); | |
} else { | |
return new Vector3( this._x, this._y, this._z ); | |
} | |
}, | |
_onChange: function ( callback ) { | |
this._onChangeCallback = callback; | |
return this; | |
}, | |
_onChangeCallback: function () {} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function Layers() { | |
this.mask = 1 | 0; | |
} | |
Object.assign( Layers.prototype, { | |
set: function ( channel ) { | |
this.mask = 1 << channel | 0; | |
}, | |
enable: function ( channel ) { | |
this.mask |= 1 << channel | 0; | |
}, | |
enableAll: function () { | |
this.mask = 0xffffffff | 0; | |
}, | |
toggle: function ( channel ) { | |
this.mask ^= 1 << channel | 0; | |
}, | |
disable: function ( channel ) { | |
this.mask &= ~ ( 1 << channel | 0 ); | |
}, | |
disableAll: function () { | |
this.mask = 0; | |
}, | |
test: function ( layers ) { | |
return ( this.mask & layers.mask ) !== 0; | |
} | |
} ); | |
var _object3DId = 0; | |
var _v1$1 = new Vector3(); | |
var _q1 = new Quaternion(); | |
var _m1$1 = new Matrix4(); | |
var _target = new Vector3(); | |
var _position = new Vector3(); | |
var _scale = new Vector3(); | |
var _quaternion$2 = new Quaternion(); | |
var _xAxis = new Vector3( 1, 0, 0 ); | |
var _yAxis = new Vector3( 0, 1, 0 ); | |
var _zAxis = new Vector3( 0, 0, 1 ); | |
var _addedEvent = { type: 'added' }; | |
var _removedEvent = { type: 'removed' }; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author mikael emtinger / http://gomo.se/ | |
* @author alteredq / http://alteredqualia.com/ | |
* @author WestLangley / http://github.com/WestLangley | |
* @author elephantatwork / www.elephantatwork.ch | |
*/ | |
function Object3D() { | |
Object.defineProperty( this, 'id', { value: _object3DId ++ } ); | |
this.uuid = MathUtils.generateUUID(); | |
this.name = ''; | |
this.type = 'Object3D'; | |
this.parent = null; | |
this.children = []; | |
this.up = Object3D.DefaultUp.clone(); | |
var position = new Vector3(); | |
var rotation = new Euler(); | |
var quaternion = new Quaternion(); | |
var scale = new Vector3( 1, 1, 1 ); | |
function onRotationChange() { | |
quaternion.setFromEuler( rotation, false ); | |
} | |
function onQuaternionChange() { | |
rotation.setFromQuaternion( quaternion, undefined, false ); | |
} | |
rotation._onChange( onRotationChange ); | |
quaternion._onChange( onQuaternionChange ); | |
Object.defineProperties( this, { | |
position: { | |
configurable: true, | |
enumerable: true, | |
value: position | |
}, | |
rotation: { | |
configurable: true, | |
enumerable: true, | |
value: rotation | |
}, | |
quaternion: { | |
configurable: true, | |
enumerable: true, | |
value: quaternion | |
}, | |
scale: { | |
configurable: true, | |
enumerable: true, | |
value: scale | |
}, | |
modelViewMatrix: { | |
value: new Matrix4() | |
}, | |
normalMatrix: { | |
value: new Matrix3() | |
} | |
} ); | |
this.matrix = new Matrix4(); | |
this.matrixWorld = new Matrix4(); | |
this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; | |
this.matrixWorldNeedsUpdate = false; | |
this.layers = new Layers(); | |
this.visible = true; | |
this.castShadow = false; | |
this.receiveShadow = false; | |
this.frustumCulled = true; | |
this.renderOrder = 0; | |
this.userData = {}; | |
} | |
Object3D.DefaultUp = new Vector3( 0, 1, 0 ); | |
Object3D.DefaultMatrixAutoUpdate = true; | |
Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { | |
constructor: Object3D, | |
isObject3D: true, | |
onBeforeRender: function () {}, | |
onAfterRender: function () {}, | |
applyMatrix4: function ( matrix ) { | |
if ( this.matrixAutoUpdate ) { this.updateMatrix(); } | |
this.matrix.premultiply( matrix ); | |
this.matrix.decompose( this.position, this.quaternion, this.scale ); | |
}, | |
applyQuaternion: function ( q ) { | |
this.quaternion.premultiply( q ); | |
return this; | |
}, | |
setRotationFromAxisAngle: function ( axis, angle ) { | |
// assumes axis is normalized | |
this.quaternion.setFromAxisAngle( axis, angle ); | |
}, | |
setRotationFromEuler: function ( euler ) { | |
this.quaternion.setFromEuler( euler, true ); | |
}, | |
setRotationFromMatrix: function ( m ) { | |
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) | |
this.quaternion.setFromRotationMatrix( m ); | |
}, | |
setRotationFromQuaternion: function ( q ) { | |
// assumes q is normalized | |
this.quaternion.copy( q ); | |
}, | |
rotateOnAxis: function ( axis, angle ) { | |
// rotate object on axis in object space | |
// axis is assumed to be normalized | |
_q1.setFromAxisAngle( axis, angle ); | |
this.quaternion.multiply( _q1 ); | |
return this; | |
}, | |
rotateOnWorldAxis: function ( axis, angle ) { | |
// rotate object on axis in world space | |
// axis is assumed to be normalized | |
// method assumes no rotated parent | |
_q1.setFromAxisAngle( axis, angle ); | |
this.quaternion.premultiply( _q1 ); | |
return this; | |
}, | |
rotateX: function ( angle ) { | |
return this.rotateOnAxis( _xAxis, angle ); | |
}, | |
rotateY: function ( angle ) { | |
return this.rotateOnAxis( _yAxis, angle ); | |
}, | |
rotateZ: function ( angle ) { | |
return this.rotateOnAxis( _zAxis, angle ); | |
}, | |
translateOnAxis: function ( axis, distance ) { | |
// translate object by distance along axis in object space | |
// axis is assumed to be normalized | |
_v1$1.copy( axis ).applyQuaternion( this.quaternion ); | |
this.position.add( _v1$1.multiplyScalar( distance ) ); | |
return this; | |
}, | |
translateX: function ( distance ) { | |
return this.translateOnAxis( _xAxis, distance ); | |
}, | |
translateY: function ( distance ) { | |
return this.translateOnAxis( _yAxis, distance ); | |
}, | |
translateZ: function ( distance ) { | |
return this.translateOnAxis( _zAxis, distance ); | |
}, | |
localToWorld: function ( vector ) { | |
return vector.applyMatrix4( this.matrixWorld ); | |
}, | |
worldToLocal: function ( vector ) { | |
return vector.applyMatrix4( _m1$1.getInverse( this.matrixWorld ) ); | |
}, | |
lookAt: function ( x, y, z ) { | |
// This method does not support objects having non-uniformly-scaled parent(s) | |
if ( x.isVector3 ) { | |
_target.copy( x ); | |
} else { | |
_target.set( x, y, z ); | |
} | |
var parent = this.parent; | |
this.updateWorldMatrix( true, false ); | |
_position.setFromMatrixPosition( this.matrixWorld ); | |
if ( this.isCamera || this.isLight ) { | |
_m1$1.lookAt( _position, _target, this.up ); | |
} else { | |
_m1$1.lookAt( _target, _position, this.up ); | |
} | |
this.quaternion.setFromRotationMatrix( _m1$1 ); | |
if ( parent ) { | |
_m1$1.extractRotation( parent.matrixWorld ); | |
_q1.setFromRotationMatrix( _m1$1 ); | |
this.quaternion.premultiply( _q1.inverse() ); | |
} | |
}, | |
add: function ( object ) { | |
if ( arguments.length > 1 ) { | |
for ( var i = 0; i < arguments.length; i ++ ) { | |
this.add( arguments[ i ] ); | |
} | |
return this; | |
} | |
if ( object === this ) { | |
console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object ); | |
return this; | |
} | |
if ( ( object && object.isObject3D ) ) { | |
if ( object.parent !== null ) { | |
object.parent.remove( object ); | |
} | |
object.parent = this; | |
this.children.push( object ); | |
object.dispatchEvent( _addedEvent ); | |
} else { | |
console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object ); | |
} | |
return this; | |
}, | |
remove: function ( object ) { | |
if ( arguments.length > 1 ) { | |
for ( var i = 0; i < arguments.length; i ++ ) { | |
this.remove( arguments[ i ] ); | |
} | |
return this; | |
} | |
var index = this.children.indexOf( object ); | |
if ( index !== - 1 ) { | |
object.parent = null; | |
this.children.splice( index, 1 ); | |
object.dispatchEvent( _removedEvent ); | |
} | |
return this; | |
}, | |
attach: function ( object ) { | |
// adds object as a child of this, while maintaining the object's world transform | |
this.updateWorldMatrix( true, false ); | |
_m1$1.getInverse( this.matrixWorld ); | |
if ( object.parent !== null ) { | |
object.parent.updateWorldMatrix( true, false ); | |
_m1$1.multiply( object.parent.matrixWorld ); | |
} | |
object.applyMatrix4( _m1$1 ); | |
object.updateWorldMatrix( false, false ); | |
this.add( object ); | |
return this; | |
}, | |
getObjectById: function ( id ) { | |
return this.getObjectByProperty( 'id', id ); | |
}, | |
getObjectByName: function ( name ) { | |
return this.getObjectByProperty( 'name', name ); | |
}, | |
getObjectByProperty: function ( name, value ) { | |
if ( this[ name ] === value ) { return this; } | |
for ( var i = 0, l = this.children.length; i < l; i ++ ) { | |
var child = this.children[ i ]; | |
var object = child.getObjectByProperty( name, value ); | |
if ( object !== undefined ) { | |
return object; | |
} | |
} | |
return undefined; | |
}, | |
getWorldPosition: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' ); | |
target = new Vector3(); | |
} | |
this.updateMatrixWorld( true ); | |
return target.setFromMatrixPosition( this.matrixWorld ); | |
}, | |
getWorldQuaternion: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' ); | |
target = new Quaternion(); | |
} | |
this.updateMatrixWorld( true ); | |
this.matrixWorld.decompose( _position, target, _scale ); | |
return target; | |
}, | |
getWorldScale: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Object3D: .getWorldScale() target is now required' ); | |
target = new Vector3(); | |
} | |
this.updateMatrixWorld( true ); | |
this.matrixWorld.decompose( _position, _quaternion$2, target ); | |
return target; | |
}, | |
getWorldDirection: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' ); | |
target = new Vector3(); | |
} | |
this.updateMatrixWorld( true ); | |
var e = this.matrixWorld.elements; | |
return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); | |
}, | |
raycast: function () {}, | |
traverse: function ( callback ) { | |
callback( this ); | |
var children = this.children; | |
for ( var i = 0, l = children.length; i < l; i ++ ) { | |
children[ i ].traverse( callback ); | |
} | |
}, | |
traverseVisible: function ( callback ) { | |
if ( this.visible === false ) { return; } | |
callback( this ); | |
var children = this.children; | |
for ( var i = 0, l = children.length; i < l; i ++ ) { | |
children[ i ].traverseVisible( callback ); | |
} | |
}, | |
traverseAncestors: function ( callback ) { | |
var parent = this.parent; | |
if ( parent !== null ) { | |
callback( parent ); | |
parent.traverseAncestors( callback ); | |
} | |
}, | |
updateMatrix: function () { | |
this.matrix.compose( this.position, this.quaternion, this.scale ); | |
this.matrixWorldNeedsUpdate = true; | |
}, | |
updateMatrixWorld: function ( force ) { | |
if ( this.matrixAutoUpdate ) { this.updateMatrix(); } | |
if ( this.matrixWorldNeedsUpdate || force ) { | |
if ( this.parent === null ) { | |
this.matrixWorld.copy( this.matrix ); | |
} else { | |
this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); | |
} | |
this.matrixWorldNeedsUpdate = false; | |
force = true; | |
} | |
// update children | |
var children = this.children; | |
for ( var i = 0, l = children.length; i < l; i ++ ) { | |
children[ i ].updateMatrixWorld( force ); | |
} | |
}, | |
updateWorldMatrix: function ( updateParents, updateChildren ) { | |
var parent = this.parent; | |
if ( updateParents === true && parent !== null ) { | |
parent.updateWorldMatrix( true, false ); | |
} | |
if ( this.matrixAutoUpdate ) { this.updateMatrix(); } | |
if ( this.parent === null ) { | |
this.matrixWorld.copy( this.matrix ); | |
} else { | |
this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); | |
} | |
// update children | |
if ( updateChildren === true ) { | |
var children = this.children; | |
for ( var i = 0, l = children.length; i < l; i ++ ) { | |
children[ i ].updateWorldMatrix( false, true ); | |
} | |
} | |
}, | |
toJSON: function ( meta ) { | |
// meta is a string when called from JSON.stringify | |
var isRootObject = ( meta === undefined || typeof meta === 'string' ); | |
var output = {}; | |
// meta is a hash used to collect geometries, materials. | |
// not providing it implies that this is the root object | |
// being serialized. | |
if ( isRootObject ) { | |
// initialize meta obj | |
meta = { | |
geometries: {}, | |
materials: {}, | |
textures: {}, | |
images: {}, | |
shapes: {} | |
}; | |
output.metadata = { | |
version: 4.5, | |
type: 'Object', | |
generator: 'Object3D.toJSON' | |
}; | |
} | |
// standard Object3D serialization | |
var object = {}; | |
object.uuid = this.uuid; | |
object.type = this.type; | |
if ( this.name !== '' ) { object.name = this.name; } | |
if ( this.castShadow === true ) { object.castShadow = true; } | |
if ( this.receiveShadow === true ) { object.receiveShadow = true; } | |
if ( this.visible === false ) { object.visible = false; } | |
if ( this.frustumCulled === false ) { object.frustumCulled = false; } | |
if ( this.renderOrder !== 0 ) { object.renderOrder = this.renderOrder; } | |
if ( JSON.stringify( this.userData ) !== '{}' ) { object.userData = this.userData; } | |
object.layers = this.layers.mask; | |
object.matrix = this.matrix.toArray(); | |
if ( this.matrixAutoUpdate === false ) { object.matrixAutoUpdate = false; } | |
// object specific properties | |
if ( this.isInstancedMesh ) { | |
object.type = 'InstancedMesh'; | |
object.count = this.count; | |
object.instanceMatrix = this.instanceMatrix.toJSON(); | |
} | |
// | |
function serialize( library, element ) { | |
if ( library[ element.uuid ] === undefined ) { | |
library[ element.uuid ] = element.toJSON( meta ); | |
} | |
return element.uuid; | |
} | |
if ( this.isMesh || this.isLine || this.isPoints ) { | |
object.geometry = serialize( meta.geometries, this.geometry ); | |
var parameters = this.geometry.parameters; | |
if ( parameters !== undefined && parameters.shapes !== undefined ) { | |
var shapes = parameters.shapes; | |
if ( Array.isArray( shapes ) ) { | |
for ( var i = 0, l = shapes.length; i < l; i ++ ) { | |
var shape = shapes[ i ]; | |
serialize( meta.shapes, shape ); | |
} | |
} else { | |
serialize( meta.shapes, shapes ); | |
} | |
} | |
} | |
if ( this.material !== undefined ) { | |
if ( Array.isArray( this.material ) ) { | |
var uuids = []; | |
for ( var i = 0, l = this.material.length; i < l; i ++ ) { | |
uuids.push( serialize( meta.materials, this.material[ i ] ) ); | |
} | |
object.material = uuids; | |
} else { | |
object.material = serialize( meta.materials, this.material ); | |
} | |
} | |
// | |
if ( this.children.length > 0 ) { | |
object.children = []; | |
for ( var i = 0; i < this.children.length; i ++ ) { | |
object.children.push( this.children[ i ].toJSON( meta ).object ); | |
} | |
} | |
if ( isRootObject ) { | |
var geometries = extractFromCache( meta.geometries ); | |
var materials = extractFromCache( meta.materials ); | |
var textures = extractFromCache( meta.textures ); | |
var images = extractFromCache( meta.images ); | |
var shapes = extractFromCache( meta.shapes ); | |
if ( geometries.length > 0 ) { output.geometries = geometries; } | |
if ( materials.length > 0 ) { output.materials = materials; } | |
if ( textures.length > 0 ) { output.textures = textures; } | |
if ( images.length > 0 ) { output.images = images; } | |
if ( shapes.length > 0 ) { output.shapes = shapes; } | |
} | |
output.object = object; | |
return output; | |
// extract data from the cache hash | |
// remove metadata on each item | |
// and return as array | |
function extractFromCache( cache ) { | |
var values = []; | |
for ( var key in cache ) { | |
var data = cache[ key ]; | |
delete data.metadata; | |
values.push( data ); | |
} | |
return values; | |
} | |
}, | |
clone: function ( recursive ) { | |
return new this.constructor().copy( this, recursive ); | |
}, | |
copy: function ( source, recursive ) { | |
if ( recursive === undefined ) { recursive = true; } | |
this.name = source.name; | |
this.up.copy( source.up ); | |
this.position.copy( source.position ); | |
this.quaternion.copy( source.quaternion ); | |
this.scale.copy( source.scale ); | |
this.matrix.copy( source.matrix ); | |
this.matrixWorld.copy( source.matrixWorld ); | |
this.matrixAutoUpdate = source.matrixAutoUpdate; | |
this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; | |
this.layers.mask = source.layers.mask; | |
this.visible = source.visible; | |
this.castShadow = source.castShadow; | |
this.receiveShadow = source.receiveShadow; | |
this.frustumCulled = source.frustumCulled; | |
this.renderOrder = source.renderOrder; | |
this.userData = JSON.parse( JSON.stringify( source.userData ) ); | |
if ( recursive === true ) { | |
for ( var i = 0; i < source.children.length; i ++ ) { | |
var child = source.children[ i ]; | |
this.add( child.clone() ); | |
} | |
} | |
return this; | |
} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function Scene() { | |
Object3D.call( this ); | |
this.type = 'Scene'; | |
this.background = null; | |
this.environment = null; | |
this.fog = null; | |
this.overrideMaterial = null; | |
this.autoUpdate = true; // checked by the renderer | |
if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { | |
__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef | |
} | |
} | |
Scene.prototype = Object.assign( Object.create( Object3D.prototype ), { | |
constructor: Scene, | |
isScene: true, | |
copy: function ( source, recursive ) { | |
Object3D.prototype.copy.call( this, source, recursive ); | |
if ( source.background !== null ) { this.background = source.background.clone(); } | |
if ( source.environment !== null ) { this.environment = source.environment.clone(); } | |
if ( source.fog !== null ) { this.fog = source.fog.clone(); } | |
if ( source.overrideMaterial !== null ) { this.overrideMaterial = source.overrideMaterial.clone(); } | |
this.autoUpdate = source.autoUpdate; | |
this.matrixAutoUpdate = source.matrixAutoUpdate; | |
return this; | |
}, | |
toJSON: function ( meta ) { | |
var data = Object3D.prototype.toJSON.call( this, meta ); | |
if ( this.background !== null ) { data.object.background = this.background.toJSON( meta ); } | |
if ( this.environment !== null ) { data.object.environment = this.environment.toJSON( meta ); } | |
if ( this.fog !== null ) { data.object.fog = this.fog.toJSON(); } | |
return data; | |
}, | |
dispose: function () { | |
this.dispatchEvent( { type: 'dispose' } ); | |
} | |
} ); | |
var _points = [ | |
new Vector3(), | |
new Vector3(), | |
new Vector3(), | |
new Vector3(), | |
new Vector3(), | |
new Vector3(), | |
new Vector3(), | |
new Vector3() | |
]; | |
var _vector$1 = new Vector3(); | |
var _box = new Box3(); | |
// triangle centered vertices | |
var _v0 = new Vector3(); | |
var _v1$2 = new Vector3(); | |
var _v2 = new Vector3(); | |
// triangle edge vectors | |
var _f0 = new Vector3(); | |
var _f1 = new Vector3(); | |
var _f2 = new Vector3(); | |
var _center = new Vector3(); | |
var _extents = new Vector3(); | |
var _triangleNormal = new Vector3(); | |
var _testAxis = new Vector3(); | |
/** | |
* @author bhouston / http://clara.io | |
* @author WestLangley / http://github.com/WestLangley | |
*/ | |
function Box3( min, max ) { | |
this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity ); | |
this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity ); | |
} | |
Object.assign( Box3.prototype, { | |
isBox3: true, | |
set: function ( min, max ) { | |
this.min.copy( min ); | |
this.max.copy( max ); | |
return this; | |
}, | |
setFromArray: function ( array ) { | |
var minX = + Infinity; | |
var minY = + Infinity; | |
var minZ = + Infinity; | |
var maxX = - Infinity; | |
var maxY = - Infinity; | |
var maxZ = - Infinity; | |
for ( var i = 0, l = array.length; i < l; i += 3 ) { | |
var x = array[ i ]; | |
var y = array[ i + 1 ]; | |
var z = array[ i + 2 ]; | |
if ( x < minX ) { minX = x; } | |
if ( y < minY ) { minY = y; } | |
if ( z < minZ ) { minZ = z; } | |
if ( x > maxX ) { maxX = x; } | |
if ( y > maxY ) { maxY = y; } | |
if ( z > maxZ ) { maxZ = z; } | |
} | |
this.min.set( minX, minY, minZ ); | |
this.max.set( maxX, maxY, maxZ ); | |
return this; | |
}, | |
setFromBufferAttribute: function ( attribute ) { | |
var minX = + Infinity; | |
var minY = + Infinity; | |
var minZ = + Infinity; | |
var maxX = - Infinity; | |
var maxY = - Infinity; | |
var maxZ = - Infinity; | |
for ( var i = 0, l = attribute.count; i < l; i ++ ) { | |
var x = attribute.getX( i ); | |
var y = attribute.getY( i ); | |
var z = attribute.getZ( i ); | |
if ( x < minX ) { minX = x; } | |
if ( y < minY ) { minY = y; } | |
if ( z < minZ ) { minZ = z; } | |
if ( x > maxX ) { maxX = x; } | |
if ( y > maxY ) { maxY = y; } | |
if ( z > maxZ ) { maxZ = z; } | |
} | |
this.min.set( minX, minY, minZ ); | |
this.max.set( maxX, maxY, maxZ ); | |
return this; | |
}, | |
setFromPoints: function ( points ) { | |
this.makeEmpty(); | |
for ( var i = 0, il = points.length; i < il; i ++ ) { | |
this.expandByPoint( points[ i ] ); | |
} | |
return this; | |
}, | |
setFromCenterAndSize: function ( center, size ) { | |
var halfSize = _vector$1.copy( size ).multiplyScalar( 0.5 ); | |
this.min.copy( center ).sub( halfSize ); | |
this.max.copy( center ).add( halfSize ); | |
return this; | |
}, | |
setFromObject: function ( object ) { | |
this.makeEmpty(); | |
return this.expandByObject( object ); | |
}, | |
clone: function () { | |
return new this.constructor().copy( this ); | |
}, | |
copy: function ( box ) { | |
this.min.copy( box.min ); | |
this.max.copy( box.max ); | |
return this; | |
}, | |
makeEmpty: function () { | |
this.min.x = this.min.y = this.min.z = + Infinity; | |
this.max.x = this.max.y = this.max.z = - Infinity; | |
return this; | |
}, | |
isEmpty: function () { | |
// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes | |
return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); | |
}, | |
getCenter: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Box3: .getCenter() target is now required' ); | |
target = new Vector3(); | |
} | |
return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); | |
}, | |
getSize: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Box3: .getSize() target is now required' ); | |
target = new Vector3(); | |
} | |
return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); | |
}, | |
expandByPoint: function ( point ) { | |
this.min.min( point ); | |
this.max.max( point ); | |
return this; | |
}, | |
expandByVector: function ( vector ) { | |
this.min.sub( vector ); | |
this.max.add( vector ); | |
return this; | |
}, | |
expandByScalar: function ( scalar ) { | |
this.min.addScalar( - scalar ); | |
this.max.addScalar( scalar ); | |
return this; | |
}, | |
expandByObject: function ( object ) { | |
// Computes the world-axis-aligned bounding box of an object (including its children), | |
// accounting for both the object's, and children's, world transforms | |
object.updateWorldMatrix( false, false ); | |
var geometry = object.geometry; | |
if ( geometry !== undefined ) { | |
if ( geometry.boundingBox === null ) { | |
geometry.computeBoundingBox(); | |
} | |
_box.copy( geometry.boundingBox ); | |
_box.applyMatrix4( object.matrixWorld ); | |
this.union( _box ); | |
} | |
var children = object.children; | |
for ( var i = 0, l = children.length; i < l; i ++ ) { | |
this.expandByObject( children[ i ] ); | |
} | |
return this; | |
}, | |
containsPoint: function ( point ) { | |
return point.x < this.min.x || point.x > this.max.x || | |
point.y < this.min.y || point.y > this.max.y || | |
point.z < this.min.z || point.z > this.max.z ? false : true; | |
}, | |
containsBox: function ( box ) { | |
return this.min.x <= box.min.x && box.max.x <= this.max.x && | |
this.min.y <= box.min.y && box.max.y <= this.max.y && | |
this.min.z <= box.min.z && box.max.z <= this.max.z; | |
}, | |
getParameter: function ( point, target ) { | |
// This can potentially have a divide by zero if the box | |
// has a size dimension of 0. | |
if ( target === undefined ) { | |
console.warn( 'THREE.Box3: .getParameter() target is now required' ); | |
target = new Vector3(); | |
} | |
return target.set( | |
( point.x - this.min.x ) / ( this.max.x - this.min.x ), | |
( point.y - this.min.y ) / ( this.max.y - this.min.y ), | |
( point.z - this.min.z ) / ( this.max.z - this.min.z ) | |
); | |
}, | |
intersectsBox: function ( box ) { | |
// using 6 splitting planes to rule out intersections. | |
return box.max.x < this.min.x || box.min.x > this.max.x || | |
box.max.y < this.min.y || box.min.y > this.max.y || | |
box.max.z < this.min.z || box.min.z > this.max.z ? false : true; | |
}, | |
intersectsSphere: function ( sphere ) { | |
// Find the point on the AABB closest to the sphere center. | |
this.clampPoint( sphere.center, _vector$1 ); | |
// If that point is inside the sphere, the AABB and sphere intersect. | |
return _vector$1.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); | |
}, | |
intersectsPlane: function ( plane ) { | |
// We compute the minimum and maximum dot product values. If those values | |
// are on the same side (back or front) of the plane, then there is no intersection. | |
var min, max; | |
if ( plane.normal.x > 0 ) { | |
min = plane.normal.x * this.min.x; | |
max = plane.normal.x * this.max.x; | |
} else { | |
min = plane.normal.x * this.max.x; | |
max = plane.normal.x * this.min.x; | |
} | |
if ( plane.normal.y > 0 ) { | |
min += plane.normal.y * this.min.y; | |
max += plane.normal.y * this.max.y; | |
} else { | |
min += plane.normal.y * this.max.y; | |
max += plane.normal.y * this.min.y; | |
} | |
if ( plane.normal.z > 0 ) { | |
min += plane.normal.z * this.min.z; | |
max += plane.normal.z * this.max.z; | |
} else { | |
min += plane.normal.z * this.max.z; | |
max += plane.normal.z * this.min.z; | |
} | |
return ( min <= - plane.constant && max >= - plane.constant ); | |
}, | |
intersectsTriangle: function ( triangle ) { | |
if ( this.isEmpty() ) { | |
return false; | |
} | |
// compute box center and extents | |
this.getCenter( _center ); | |
_extents.subVectors( this.max, _center ); | |
// translate triangle to aabb origin | |
_v0.subVectors( triangle.a, _center ); | |
_v1$2.subVectors( triangle.b, _center ); | |
_v2.subVectors( triangle.c, _center ); | |
// compute edge vectors for triangle | |
_f0.subVectors( _v1$2, _v0 ); | |
_f1.subVectors( _v2, _v1$2 ); | |
_f2.subVectors( _v0, _v2 ); | |
// test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb | |
// make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation | |
// axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) | |
var axes = [ | |
0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y, | |
_f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x, | |
- _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0 | |
]; | |
if ( ! satForAxes( axes, _v0, _v1$2, _v2, _extents ) ) { | |
return false; | |
} | |
// test 3 face normals from the aabb | |
axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; | |
if ( ! satForAxes( axes, _v0, _v1$2, _v2, _extents ) ) { | |
return false; | |
} | |
// finally testing the face normal of the triangle | |
// use already existing triangle edge vectors here | |
_triangleNormal.crossVectors( _f0, _f1 ); | |
axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ]; | |
return satForAxes( axes, _v0, _v1$2, _v2, _extents ); | |
}, | |
clampPoint: function ( point, target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Box3: .clampPoint() target is now required' ); | |
target = new Vector3(); | |
} | |
return target.copy( point ).clamp( this.min, this.max ); | |
}, | |
distanceToPoint: function ( point ) { | |
var clampedPoint = _vector$1.copy( point ).clamp( this.min, this.max ); | |
return clampedPoint.sub( point ).length(); | |
}, | |
getBoundingSphere: function ( target ) { | |
if ( target === undefined ) { | |
console.error( 'THREE.Box3: .getBoundingSphere() target is now required' ); | |
//target = new Sphere(); // removed to avoid cyclic dependency | |
} | |
this.getCenter( target.center ); | |
target.radius = this.getSize( _vector$1 ).length() * 0.5; | |
return target; | |
}, | |
intersect: function ( box ) { | |
this.min.max( box.min ); | |
this.max.min( box.max ); | |
// ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. | |
if ( this.isEmpty() ) { this.makeEmpty(); } | |
return this; | |
}, | |
union: function ( box ) { | |
this.min.min( box.min ); | |
this.max.max( box.max ); | |
return this; | |
}, | |
applyMatrix4: function ( matrix ) { | |
// transform of empty box is an empty box. | |
if ( this.isEmpty() ) { return this; } | |
// NOTE: I am using a binary pattern to specify all 2^3 combinations below | |
_points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 | |
_points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001 | |
_points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 | |
_points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 | |
_points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 | |
_points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 | |
_points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110 | |
_points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111 | |
this.setFromPoints( _points ); | |
return this; | |
}, | |
translate: function ( offset ) { | |
this.min.add( offset ); | |
this.max.add( offset ); | |
return this; | |
}, | |
equals: function ( box ) { | |
return box.min.equals( this.min ) && box.max.equals( this.max ); | |
} | |
} ); | |
function satForAxes( axes, v0, v1, v2, extents ) { | |
var i, j; | |
for ( i = 0, j = axes.length - 3; i <= j; i += 3 ) { | |
_testAxis.fromArray( axes, i ); | |
// project the aabb onto the seperating axis | |
var r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z ); | |
// project all 3 vertices of the triangle onto the seperating axis | |
var p0 = v0.dot( _testAxis ); | |
var p1 = v1.dot( _testAxis ); | |
var p2 = v2.dot( _testAxis ); | |
// actual test, basically see if either of the most extreme of the triangle points intersects r | |
if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { | |
// points of the projected triangle are outside the projected half-length of the aabb | |
// the axis is seperating and we can exit | |
return false; | |
} | |
} | |
return true; | |
} | |
var _box$1 = new Box3(); | |
/** | |
* @author bhouston / http://clara.io | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function Sphere( center, radius ) { | |
this.center = ( center !== undefined ) ? center : new Vector3(); | |
this.radius = ( radius !== undefined ) ? radius : 0; | |
} | |
Object.assign( Sphere.prototype, { | |
set: function ( center, radius ) { | |
this.center.copy( center ); | |
this.radius = radius; | |
return this; | |
}, | |
setFromPoints: function ( points, optionalCenter ) { | |
var center = this.center; | |
if ( optionalCenter !== undefined ) { | |
center.copy( optionalCenter ); | |
} else { | |
_box$1.setFromPoints( points ).getCenter( center ); | |
} | |
var maxRadiusSq = 0; | |
for ( var i = 0, il = points.length; i < il; i ++ ) { | |
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); | |
} | |
this.radius = Math.sqrt( maxRadiusSq ); | |
return this; | |
}, | |
clone: function () { | |
return new this.constructor().copy( this ); | |
}, | |
copy: function ( sphere ) { | |
this.center.copy( sphere.center ); | |
this.radius = sphere.radius; | |
return this; | |
}, | |
empty: function () { | |
return ( this.radius <= 0 ); | |
}, | |
containsPoint: function ( point ) { | |
return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); | |
}, | |
distanceToPoint: function ( point ) { | |
return ( point.distanceTo( this.center ) - this.radius ); | |
}, | |
intersectsSphere: function ( sphere ) { | |
var radiusSum = this.radius + sphere.radius; | |
return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); | |
}, | |
intersectsBox: function ( box ) { | |
return box.intersectsSphere( this ); | |
}, | |
intersectsPlane: function ( plane ) { | |
return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; | |
}, | |
clampPoint: function ( point, target ) { | |
var deltaLengthSq = this.center.distanceToSquared( point ); | |
if ( target === undefined ) { | |
console.warn( 'THREE.Sphere: .clampPoint() target is now required' ); | |
target = new Vector3(); | |
} | |
target.copy( point ); | |
if ( deltaLengthSq > ( this.radius * this.radius ) ) { | |
target.sub( this.center ).normalize(); | |
target.multiplyScalar( this.radius ).add( this.center ); | |
} | |
return target; | |
}, | |
getBoundingBox: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Sphere: .getBoundingBox() target is now required' ); | |
target = new Box3(); | |
} | |
target.set( this.center, this.center ); | |
target.expandByScalar( this.radius ); | |
return target; | |
}, | |
applyMatrix4: function ( matrix ) { | |
this.center.applyMatrix4( matrix ); | |
this.radius = this.radius * matrix.getMaxScaleOnAxis(); | |
return this; | |
}, | |
translate: function ( offset ) { | |
this.center.add( offset ); | |
return this; | |
}, | |
equals: function ( sphere ) { | |
return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); | |
} | |
} ); | |
var _vector$2 = new Vector3(); | |
var _segCenter = new Vector3(); | |
var _segDir = new Vector3(); | |
var _diff = new Vector3(); | |
var _edge1 = new Vector3(); | |
var _edge2 = new Vector3(); | |
var _normal = new Vector3(); | |
/** | |
* @author bhouston / http://clara.io | |
*/ | |
function Ray( origin, direction ) { | |
this.origin = ( origin !== undefined ) ? origin : new Vector3(); | |
this.direction = ( direction !== undefined ) ? direction : new Vector3( 0, 0, - 1 ); | |
} | |
Object.assign( Ray.prototype, { | |
set: function ( origin, direction ) { | |
this.origin.copy( origin ); | |
this.direction.copy( direction ); | |
return this; | |
}, | |
clone: function () { | |
return new this.constructor().copy( this ); | |
}, | |
copy: function ( ray ) { | |
this.origin.copy( ray.origin ); | |
this.direction.copy( ray.direction ); | |
return this; | |
}, | |
at: function ( t, target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Ray: .at() target is now required' ); | |
target = new Vector3(); | |
} | |
return target.copy( this.direction ).multiplyScalar( t ).add( this.origin ); | |
}, | |
lookAt: function ( v ) { | |
this.direction.copy( v ).sub( this.origin ).normalize(); | |
return this; | |
}, | |
recast: function ( t ) { | |
this.origin.copy( this.at( t, _vector$2 ) ); | |
return this; | |
}, | |
closestPointToPoint: function ( point, target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Ray: .closestPointToPoint() target is now required' ); | |
target = new Vector3(); | |
} | |
target.subVectors( point, this.origin ); | |
var directionDistance = target.dot( this.direction ); | |
if ( directionDistance < 0 ) { | |
return target.copy( this.origin ); | |
} | |
return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); | |
}, | |
distanceToPoint: function ( point ) { | |
return Math.sqrt( this.distanceSqToPoint( point ) ); | |
}, | |
distanceSqToPoint: function ( point ) { | |
var directionDistance = _vector$2.subVectors( point, this.origin ).dot( this.direction ); | |
// point behind the ray | |
if ( directionDistance < 0 ) { | |
return this.origin.distanceToSquared( point ); | |
} | |
_vector$2.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); | |
return _vector$2.distanceToSquared( point ); | |
}, | |
distanceSqToSegment: function ( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { | |
// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h | |
// It returns the min distance between the ray and the segment | |
// defined by v0 and v1 | |
// It can also set two optional targets : | |
// - The closest point on the ray | |
// - The closest point on the segment | |
_segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); | |
_segDir.copy( v1 ).sub( v0 ).normalize(); | |
_diff.copy( this.origin ).sub( _segCenter ); | |
var segExtent = v0.distanceTo( v1 ) * 0.5; | |
var a01 = - this.direction.dot( _segDir ); | |
var b0 = _diff.dot( this.direction ); | |
var b1 = - _diff.dot( _segDir ); | |
var c = _diff.lengthSq(); | |
var det = Math.abs( 1 - a01 * a01 ); | |
var s0, s1, sqrDist, extDet; | |
if ( det > 0 ) { | |
// The ray and segment are not parallel. | |
s0 = a01 * b1 - b0; | |
s1 = a01 * b0 - b1; | |
extDet = segExtent * det; | |
if ( s0 >= 0 ) { | |
if ( s1 >= - extDet ) { | |
if ( s1 <= extDet ) { | |
// region 0 | |
// Minimum at interior points of ray and segment. | |
var invDet = 1 / det; | |
s0 *= invDet; | |
s1 *= invDet; | |
sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; | |
} else { | |
// region 1 | |
s1 = segExtent; | |
s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); | |
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; | |
} | |
} else { | |
// region 5 | |
s1 = - segExtent; | |
s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); | |
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; | |
} | |
} else { | |
if ( s1 <= - extDet ) { | |
// region 4 | |
s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); | |
s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); | |
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; | |
} else if ( s1 <= extDet ) { | |
// region 3 | |
s0 = 0; | |
s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); | |
sqrDist = s1 * ( s1 + 2 * b1 ) + c; | |
} else { | |
// region 2 | |
s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); | |
s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); | |
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; | |
} | |
} | |
} else { | |
// Ray and segment are parallel. | |
s1 = ( a01 > 0 ) ? - segExtent : segExtent; | |
s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); | |
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; | |
} | |
if ( optionalPointOnRay ) { | |
optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); | |
} | |
if ( optionalPointOnSegment ) { | |
optionalPointOnSegment.copy( _segDir ).multiplyScalar( s1 ).add( _segCenter ); | |
} | |
return sqrDist; | |
}, | |
intersectSphere: function ( sphere, target ) { | |
_vector$2.subVectors( sphere.center, this.origin ); | |
var tca = _vector$2.dot( this.direction ); | |
var d2 = _vector$2.dot( _vector$2 ) - tca * tca; | |
var radius2 = sphere.radius * sphere.radius; | |
if ( d2 > radius2 ) { return null; } | |
var thc = Math.sqrt( radius2 - d2 ); | |
// t0 = first intersect point - entrance on front of sphere | |
var t0 = tca - thc; | |
// t1 = second intersect point - exit point on back of sphere | |
var t1 = tca + thc; | |
// test to see if both t0 and t1 are behind the ray - if so, return null | |
if ( t0 < 0 && t1 < 0 ) { return null; } | |
// test to see if t0 is behind the ray: | |
// if it is, the ray is inside the sphere, so return the second exit point scaled by t1, | |
// in order to always return an intersect point that is in front of the ray. | |
if ( t0 < 0 ) { return this.at( t1, target ); } | |
// else t0 is in front of the ray, so return the first collision point scaled by t0 | |
return this.at( t0, target ); | |
}, | |
intersectsSphere: function ( sphere ) { | |
return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius ); | |
}, | |
distanceToPlane: function ( plane ) { | |
var denominator = plane.normal.dot( this.direction ); | |
if ( denominator === 0 ) { | |
// line is coplanar, return origin | |
if ( plane.distanceToPoint( this.origin ) === 0 ) { | |
return 0; | |
} | |
// Null is preferable to undefined since undefined means.... it is undefined | |
return null; | |
} | |
var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; | |
// Return if the ray never intersects the plane | |
return t >= 0 ? t : null; | |
}, | |
intersectPlane: function ( plane, target ) { | |
var t = this.distanceToPlane( plane ); | |
if ( t === null ) { | |
return null; | |
} | |
return this.at( t, target ); | |
}, | |
intersectsPlane: function ( plane ) { | |
// check if the ray lies on the plane first | |
var distToPoint = plane.distanceToPoint( this.origin ); | |
if ( distToPoint === 0 ) { | |
return true; | |
} | |
var denominator = plane.normal.dot( this.direction ); | |
if ( denominator * distToPoint < 0 ) { | |
return true; | |
} | |
// ray origin is behind the plane (and is pointing behind it) | |
return false; | |
}, | |
intersectBox: function ( box, target ) { | |
var tmin, tmax, tymin, tymax, tzmin, tzmax; | |
var invdirx = 1 / this.direction.x, | |
invdiry = 1 / this.direction.y, | |
invdirz = 1 / this.direction.z; | |
var origin = this.origin; | |
if ( invdirx >= 0 ) { | |
tmin = ( box.min.x - origin.x ) * invdirx; | |
tmax = ( box.max.x - origin.x ) * invdirx; | |
} else { | |
tmin = ( box.max.x - origin.x ) * invdirx; | |
tmax = ( box.min.x - origin.x ) * invdirx; | |
} | |
if ( invdiry >= 0 ) { | |
tymin = ( box.min.y - origin.y ) * invdiry; | |
tymax = ( box.max.y - origin.y ) * invdiry; | |
} else { | |
tymin = ( box.max.y - origin.y ) * invdiry; | |
tymax = ( box.min.y - origin.y ) * invdiry; | |
} | |
if ( ( tmin > tymax ) || ( tymin > tmax ) ) { return null; } | |
// These lines also handle the case where tmin or tmax is NaN | |
// (result of 0 * Infinity). x !== x returns true if x is NaN | |
if ( tymin > tmin || tmin !== tmin ) { tmin = tymin; } | |
if ( tymax < tmax || tmax !== tmax ) { tmax = tymax; } | |
if ( invdirz >= 0 ) { | |
tzmin = ( box.min.z - origin.z ) * invdirz; | |
tzmax = ( box.max.z - origin.z ) * invdirz; | |
} else { | |
tzmin = ( box.max.z - origin.z ) * invdirz; | |
tzmax = ( box.min.z - origin.z ) * invdirz; | |
} | |
if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) { return null; } | |
if ( tzmin > tmin || tmin !== tmin ) { tmin = tzmin; } | |
if ( tzmax < tmax || tmax !== tmax ) { tmax = tzmax; } | |
//return point closest to the ray (positive side) | |
if ( tmax < 0 ) { return null; } | |
return this.at( tmin >= 0 ? tmin : tmax, target ); | |
}, | |
intersectsBox: function ( box ) { | |
return this.intersectBox( box, _vector$2 ) !== null; | |
}, | |
intersectTriangle: function ( a, b, c, backfaceCulling, target ) { | |
// Compute the offset origin, edges, and normal. | |
// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h | |
_edge1.subVectors( b, a ); | |
_edge2.subVectors( c, a ); | |
_normal.crossVectors( _edge1, _edge2 ); | |
// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, | |
// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by | |
// |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) | |
// |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) | |
// |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) | |
var DdN = this.direction.dot( _normal ); | |
var sign; | |
if ( DdN > 0 ) { | |
if ( backfaceCulling ) { return null; } | |
sign = 1; | |
} else if ( DdN < 0 ) { | |
sign = - 1; | |
DdN = - DdN; | |
} else { | |
return null; | |
} | |
_diff.subVectors( this.origin, a ); | |
var DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) ); | |
// b1 < 0, no intersection | |
if ( DdQxE2 < 0 ) { | |
return null; | |
} | |
var DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) ); | |
// b2 < 0, no intersection | |
if ( DdE1xQ < 0 ) { | |
return null; | |
} | |
// b1+b2 > 1, no intersection | |
if ( DdQxE2 + DdE1xQ > DdN ) { | |
return null; | |
} | |
// Line intersects triangle, check if ray does. | |
var QdN = - sign * _diff.dot( _normal ); | |
// t < 0, no intersection | |
if ( QdN < 0 ) { | |
return null; | |
} | |
// Ray intersects triangle. | |
return this.at( QdN / DdN, target ); | |
}, | |
applyMatrix4: function ( matrix4 ) { | |
this.origin.applyMatrix4( matrix4 ); | |
this.direction.transformDirection( matrix4 ); | |
return this; | |
}, | |
equals: function ( ray ) { | |
return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); | |
} | |
} ); | |
/** | |
* @author bhouston / http://clara.io | |
*/ | |
var _vector1 = new Vector3(); | |
var _vector2 = new Vector3(); | |
var _normalMatrix = new Matrix3(); | |
function Plane( normal, constant ) { | |
// normal is assumed to be normalized | |
this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); | |
this.constant = ( constant !== undefined ) ? constant : 0; | |
} | |
Object.assign( Plane.prototype, { | |
isPlane: true, | |
set: function ( normal, constant ) { | |
this.normal.copy( normal ); | |
this.constant = constant; | |
return this; | |
}, | |
setComponents: function ( x, y, z, w ) { | |
this.normal.set( x, y, z ); | |
this.constant = w; | |
return this; | |
}, | |
setFromNormalAndCoplanarPoint: function ( normal, point ) { | |
this.normal.copy( normal ); | |
this.constant = - point.dot( this.normal ); | |
return this; | |
}, | |
setFromCoplanarPoints: function ( a, b, c ) { | |
var normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize(); | |
// Q: should an error be thrown if normal is zero (e.g. degenerate plane)? | |
this.setFromNormalAndCoplanarPoint( normal, a ); | |
return this; | |
}, | |
clone: function () { | |
return new this.constructor().copy( this ); | |
}, | |
copy: function ( plane ) { | |
this.normal.copy( plane.normal ); | |
this.constant = plane.constant; | |
return this; | |
}, | |
normalize: function () { | |
// Note: will lead to a divide by zero if the plane is invalid. | |
var inverseNormalLength = 1.0 / this.normal.length(); | |
this.normal.multiplyScalar( inverseNormalLength ); | |
this.constant *= inverseNormalLength; | |
return this; | |
}, | |
negate: function () { | |
this.constant *= - 1; | |
this.normal.negate(); | |
return this; | |
}, | |
distanceToPoint: function ( point ) { | |
return this.normal.dot( point ) + this.constant; | |
}, | |
distanceToSphere: function ( sphere ) { | |
return this.distanceToPoint( sphere.center ) - sphere.radius; | |
}, | |
projectPoint: function ( point, target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Plane: .projectPoint() target is now required' ); | |
target = new Vector3(); | |
} | |
return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); | |
}, | |
intersectLine: function ( line, target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Plane: .intersectLine() target is now required' ); | |
target = new Vector3(); | |
} | |
var direction = line.delta( _vector1 ); | |
var denominator = this.normal.dot( direction ); | |
if ( denominator === 0 ) { | |
// line is coplanar, return origin | |
if ( this.distanceToPoint( line.start ) === 0 ) { | |
return target.copy( line.start ); | |
} | |
// Unsure if this is the correct method to handle this case. | |
return undefined; | |
} | |
var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; | |
if ( t < 0 || t > 1 ) { | |
return undefined; | |
} | |
return target.copy( direction ).multiplyScalar( t ).add( line.start ); | |
}, | |
intersectsLine: function ( line ) { | |
// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. | |
var startSign = this.distanceToPoint( line.start ); | |
var endSign = this.distanceToPoint( line.end ); | |
return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); | |
}, | |
intersectsBox: function ( box ) { | |
return box.intersectsPlane( this ); | |
}, | |
intersectsSphere: function ( sphere ) { | |
return sphere.intersectsPlane( this ); | |
}, | |
coplanarPoint: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); | |
target = new Vector3(); | |
} | |
return target.copy( this.normal ).multiplyScalar( - this.constant ); | |
}, | |
applyMatrix4: function ( matrix, optionalNormalMatrix ) { | |
var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix ); | |
var referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix ); | |
var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); | |
this.constant = - referencePoint.dot( normal ); | |
return this; | |
}, | |
translate: function ( offset ) { | |
this.constant -= offset.dot( this.normal ); | |
return this; | |
}, | |
equals: function ( plane ) { | |
return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); | |
} | |
} ); | |
/** | |
* @author bhouston / http://clara.io | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
var _v0$1 = new Vector3(); | |
var _v1$3 = new Vector3(); | |
var _v2$1 = new Vector3(); | |
var _v3 = new Vector3(); | |
var _vab = new Vector3(); | |
var _vac = new Vector3(); | |
var _vbc = new Vector3(); | |
var _vap = new Vector3(); | |
var _vbp = new Vector3(); | |
var _vcp = new Vector3(); | |
function Triangle( a, b, c ) { | |
this.a = ( a !== undefined ) ? a : new Vector3(); | |
this.b = ( b !== undefined ) ? b : new Vector3(); | |
this.c = ( c !== undefined ) ? c : new Vector3(); | |
} | |
Object.assign( Triangle, { | |
getNormal: function ( a, b, c, target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Triangle: .getNormal() target is now required' ); | |
target = new Vector3(); | |
} | |
target.subVectors( c, b ); | |
_v0$1.subVectors( a, b ); | |
target.cross( _v0$1 ); | |
var targetLengthSq = target.lengthSq(); | |
if ( targetLengthSq > 0 ) { | |
return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); | |
} | |
return target.set( 0, 0, 0 ); | |
}, | |
// static/instance method to calculate barycentric coordinates | |
// based on: http://www.blackpawn.com/texts/pointinpoly/default.html | |
getBarycoord: function ( point, a, b, c, target ) { | |
_v0$1.subVectors( c, a ); | |
_v1$3.subVectors( b, a ); | |
_v2$1.subVectors( point, a ); | |
var dot00 = _v0$1.dot( _v0$1 ); | |
var dot01 = _v0$1.dot( _v1$3 ); | |
var dot02 = _v0$1.dot( _v2$1 ); | |
var dot11 = _v1$3.dot( _v1$3 ); | |
var dot12 = _v1$3.dot( _v2$1 ); | |
var denom = ( dot00 * dot11 - dot01 * dot01 ); | |
if ( target === undefined ) { | |
console.warn( 'THREE.Triangle: .getBarycoord() target is now required' ); | |
target = new Vector3(); | |
} | |
// collinear or singular triangle | |
if ( denom === 0 ) { | |
// arbitrary location outside of triangle? | |
// not sure if this is the best idea, maybe should be returning undefined | |
return target.set( - 2, - 1, - 1 ); | |
} | |
var invDenom = 1 / denom; | |
var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; | |
var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; | |
// barycentric coordinates must always sum to 1 | |
return target.set( 1 - u - v, v, u ); | |
}, | |
containsPoint: function ( point, a, b, c ) { | |
Triangle.getBarycoord( point, a, b, c, _v3 ); | |
return ( _v3.x >= 0 ) && ( _v3.y >= 0 ) && ( ( _v3.x + _v3.y ) <= 1 ); | |
}, | |
getUV: function ( point, p1, p2, p3, uv1, uv2, uv3, target ) { | |
this.getBarycoord( point, p1, p2, p3, _v3 ); | |
target.set( 0, 0 ); | |
target.addScaledVector( uv1, _v3.x ); | |
target.addScaledVector( uv2, _v3.y ); | |
target.addScaledVector( uv3, _v3.z ); | |
return target; | |
}, | |
isFrontFacing: function ( a, b, c, direction ) { | |
_v0$1.subVectors( c, b ); | |
_v1$3.subVectors( a, b ); | |
// strictly front facing | |
return ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false; | |
} | |
} ); | |
Object.assign( Triangle.prototype, { | |
set: function ( a, b, c ) { | |
this.a.copy( a ); | |
this.b.copy( b ); | |
this.c.copy( c ); | |
return this; | |
}, | |
setFromPointsAndIndices: function ( points, i0, i1, i2 ) { | |
this.a.copy( points[ i0 ] ); | |
this.b.copy( points[ i1 ] ); | |
this.c.copy( points[ i2 ] ); | |
return this; | |
}, | |
clone: function () { | |
return new this.constructor().copy( this ); | |
}, | |
copy: function ( triangle ) { | |
this.a.copy( triangle.a ); | |
this.b.copy( triangle.b ); | |
this.c.copy( triangle.c ); | |
return this; | |
}, | |
getArea: function () { | |
_v0$1.subVectors( this.c, this.b ); | |
_v1$3.subVectors( this.a, this.b ); | |
return _v0$1.cross( _v1$3 ).length() * 0.5; | |
}, | |
getMidpoint: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Triangle: .getMidpoint() target is now required' ); | |
target = new Vector3(); | |
} | |
return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); | |
}, | |
getNormal: function ( target ) { | |
return Triangle.getNormal( this.a, this.b, this.c, target ); | |
}, | |
getPlane: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Triangle: .getPlane() target is now required' ); | |
target = new Plane(); | |
} | |
return target.setFromCoplanarPoints( this.a, this.b, this.c ); | |
}, | |
getBarycoord: function ( point, target ) { | |
return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); | |
}, | |
getUV: function ( point, uv1, uv2, uv3, target ) { | |
return Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target ); | |
}, | |
containsPoint: function ( point ) { | |
return Triangle.containsPoint( point, this.a, this.b, this.c ); | |
}, | |
isFrontFacing: function ( direction ) { | |
return Triangle.isFrontFacing( this.a, this.b, this.c, direction ); | |
}, | |
intersectsBox: function ( box ) { | |
return box.intersectsTriangle( this ); | |
}, | |
closestPointToPoint: function ( p, target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' ); | |
target = new Vector3(); | |
} | |
var a = this.a, b = this.b, c = this.c; | |
var v, w; | |
// algorithm thanks to Real-Time Collision Detection by Christer Ericson, | |
// published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., | |
// under the accompanying license; see chapter 5.1.5 for detailed explanation. | |
// basically, we're distinguishing which of the voronoi regions of the triangle | |
// the point lies in with the minimum amount of redundant computation. | |
_vab.subVectors( b, a ); | |
_vac.subVectors( c, a ); | |
_vap.subVectors( p, a ); | |
var d1 = _vab.dot( _vap ); | |
var d2 = _vac.dot( _vap ); | |
if ( d1 <= 0 && d2 <= 0 ) { | |
// vertex region of A; barycentric coords (1, 0, 0) | |
return target.copy( a ); | |
} | |
_vbp.subVectors( p, b ); | |
var d3 = _vab.dot( _vbp ); | |
var d4 = _vac.dot( _vbp ); | |
if ( d3 >= 0 && d4 <= d3 ) { | |
// vertex region of B; barycentric coords (0, 1, 0) | |
return target.copy( b ); | |
} | |
var vc = d1 * d4 - d3 * d2; | |
if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { | |
v = d1 / ( d1 - d3 ); | |
// edge region of AB; barycentric coords (1-v, v, 0) | |
return target.copy( a ).addScaledVector( _vab, v ); | |
} | |
_vcp.subVectors( p, c ); | |
var d5 = _vab.dot( _vcp ); | |
var d6 = _vac.dot( _vcp ); | |
if ( d6 >= 0 && d5 <= d6 ) { | |
// vertex region of C; barycentric coords (0, 0, 1) | |
return target.copy( c ); | |
} | |
var vb = d5 * d2 - d1 * d6; | |
if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { | |
w = d2 / ( d2 - d6 ); | |
// edge region of AC; barycentric coords (1-w, 0, w) | |
return target.copy( a ).addScaledVector( _vac, w ); | |
} | |
var va = d3 * d6 - d5 * d4; | |
if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { | |
_vbc.subVectors( c, b ); | |
w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); | |
// edge region of BC; barycentric coords (0, 1-w, w) | |
return target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC | |
} | |
// face region | |
var denom = 1 / ( va + vb + vc ); | |
// u = va * denom | |
v = vb * denom; | |
w = vc * denom; | |
return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w ); | |
}, | |
equals: function ( triangle ) { | |
return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); | |
} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
var _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, | |
'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, | |
'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, | |
'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, | |
'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, | |
'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, | |
'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, | |
'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, | |
'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, | |
'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, | |
'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, | |
'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, | |
'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, | |
'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, | |
'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, | |
'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, | |
'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, | |
'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, | |
'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, | |
'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, | |
'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, | |
'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, | |
'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, | |
'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; | |
var _hslA = { h: 0, s: 0, l: 0 }; | |
var _hslB = { h: 0, s: 0, l: 0 }; | |
function Color( r, g, b ) { | |
if ( g === undefined && b === undefined ) { | |
// r is THREE.Color, hex or string | |
return this.set( r ); | |
} | |
return this.setRGB( r, g, b ); | |
} | |
function hue2rgb( p, q, t ) { | |
if ( t < 0 ) { t += 1; } | |
if ( t > 1 ) { t -= 1; } | |
if ( t < 1 / 6 ) { return p + ( q - p ) * 6 * t; } | |
if ( t < 1 / 2 ) { return q; } | |
if ( t < 2 / 3 ) { return p + ( q - p ) * 6 * ( 2 / 3 - t ); } | |
return p; | |
} | |
function SRGBToLinear( c ) { | |
return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 ); | |
} | |
function LinearToSRGB( c ) { | |
return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055; | |
} | |
Object.assign( Color.prototype, { | |
isColor: true, | |
r: 1, g: 1, b: 1, | |
set: function ( value ) { | |
if ( value && value.isColor ) { | |
this.copy( value ); | |
} else if ( typeof value === 'number' ) { | |
this.setHex( value ); | |
} else if ( typeof value === 'string' ) { | |
this.setStyle( value ); | |
} | |
return this; | |
}, | |
setScalar: function ( scalar ) { | |
this.r = scalar; | |
this.g = scalar; | |
this.b = scalar; | |
return this; | |
}, | |
setHex: function ( hex ) { | |
hex = Math.floor( hex ); | |
this.r = ( hex >> 16 & 255 ) / 255; | |
this.g = ( hex >> 8 & 255 ) / 255; | |
this.b = ( hex & 255 ) / 255; | |
return this; | |
}, | |
setRGB: function ( r, g, b ) { | |
this.r = r; | |
this.g = g; | |
this.b = b; | |
return this; | |
}, | |
setHSL: function ( h, s, l ) { | |
// h,s,l ranges are in 0.0 - 1.0 | |
h = MathUtils.euclideanModulo( h, 1 ); | |
s = MathUtils.clamp( s, 0, 1 ); | |
l = MathUtils.clamp( l, 0, 1 ); | |
if ( s === 0 ) { | |
this.r = this.g = this.b = l; | |
} else { | |
var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); | |
var q = ( 2 * l ) - p; | |
this.r = hue2rgb( q, p, h + 1 / 3 ); | |
this.g = hue2rgb( q, p, h ); | |
this.b = hue2rgb( q, p, h - 1 / 3 ); | |
} | |
return this; | |
}, | |
setStyle: function ( style ) { | |
function handleAlpha( string ) { | |
if ( string === undefined ) { return; } | |
if ( parseFloat( string ) < 1 ) { | |
console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' ); | |
} | |
} | |
var m; | |
if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) { | |
// rgb / hsl | |
var color; | |
var name = m[ 1 ]; | |
var components = m[ 2 ]; | |
switch ( name ) { | |
case 'rgb': | |
case 'rgba': | |
if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { | |
// rgb(255,0,0) rgba(255,0,0,0.5) | |
this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; | |
this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; | |
this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; | |
handleAlpha( color[ 5 ] ); | |
return this; | |
} | |
if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { | |
// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) | |
this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; | |
this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; | |
this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; | |
handleAlpha( color[ 5 ] ); | |
return this; | |
} | |
break; | |
case 'hsl': | |
case 'hsla': | |
if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { | |
// hsl(120,50%,50%) hsla(120,50%,50%,0.5) | |
var h = parseFloat( color[ 1 ] ) / 360; | |
var s = parseInt( color[ 2 ], 10 ) / 100; | |
var l = parseInt( color[ 3 ], 10 ) / 100; | |
handleAlpha( color[ 5 ] ); | |
return this.setHSL( h, s, l ); | |
} | |
break; | |
} | |
} else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) { | |
// hex color | |
var hex = m[ 1 ]; | |
var size = hex.length; | |
if ( size === 3 ) { | |
// #ff0 | |
this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255; | |
this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255; | |
this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255; | |
return this; | |
} else if ( size === 6 ) { | |
// #ff0000 | |
this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255; | |
this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255; | |
this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255; | |
return this; | |
} | |
} | |
if ( style && style.length > 0 ) { | |
return this.setColorName( style ); | |
} | |
return this; | |
}, | |
setColorName: function ( style ) { | |
// color keywords | |
var hex = _colorKeywords[ style ]; | |
if ( hex !== undefined ) { | |
// red | |
this.setHex( hex ); | |
} else { | |
// unknown color | |
console.warn( 'THREE.Color: Unknown color ' + style ); | |
} | |
return this; | |
}, | |
clone: function () { | |
return new this.constructor( this.r, this.g, this.b ); | |
}, | |
copy: function ( color ) { | |
this.r = color.r; | |
this.g = color.g; | |
this.b = color.b; | |
return this; | |
}, | |
copyGammaToLinear: function ( color, gammaFactor ) { | |
if ( gammaFactor === undefined ) { gammaFactor = 2.0; } | |
this.r = Math.pow( color.r, gammaFactor ); | |
this.g = Math.pow( color.g, gammaFactor ); | |
this.b = Math.pow( color.b, gammaFactor ); | |
return this; | |
}, | |
copyLinearToGamma: function ( color, gammaFactor ) { | |
if ( gammaFactor === undefined ) { gammaFactor = 2.0; } | |
var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; | |
this.r = Math.pow( color.r, safeInverse ); | |
this.g = Math.pow( color.g, safeInverse ); | |
this.b = Math.pow( color.b, safeInverse ); | |
return this; | |
}, | |
convertGammaToLinear: function ( gammaFactor ) { | |
this.copyGammaToLinear( this, gammaFactor ); | |
return this; | |
}, | |
convertLinearToGamma: function ( gammaFactor ) { | |
this.copyLinearToGamma( this, gammaFactor ); | |
return this; | |
}, | |
copySRGBToLinear: function ( color ) { | |
this.r = SRGBToLinear( color.r ); | |
this.g = SRGBToLinear( color.g ); | |
this.b = SRGBToLinear( color.b ); | |
return this; | |
}, | |
copyLinearToSRGB: function ( color ) { | |
this.r = LinearToSRGB( color.r ); | |
this.g = LinearToSRGB( color.g ); | |
this.b = LinearToSRGB( color.b ); | |
return this; | |
}, | |
convertSRGBToLinear: function () { | |
this.copySRGBToLinear( this ); | |
return this; | |
}, | |
convertLinearToSRGB: function () { | |
this.copyLinearToSRGB( this ); | |
return this; | |
}, | |
getHex: function () { | |
return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0; | |
}, | |
getHexString: function () { | |
return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 ); | |
}, | |
getHSL: function ( target ) { | |
// h,s,l ranges are in 0.0 - 1.0 | |
if ( target === undefined ) { | |
console.warn( 'THREE.Color: .getHSL() target is now required' ); | |
target = { h: 0, s: 0, l: 0 }; | |
} | |
var r = this.r, g = this.g, b = this.b; | |
var max = Math.max( r, g, b ); | |
var min = Math.min( r, g, b ); | |
var hue, saturation; | |
var lightness = ( min + max ) / 2.0; | |
if ( min === max ) { | |
hue = 0; | |
saturation = 0; | |
} else { | |
var delta = max - min; | |
saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); | |
switch ( max ) { | |
case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; | |
case g: hue = ( b - r ) / delta + 2; break; | |
case b: hue = ( r - g ) / delta + 4; break; | |
} | |
hue /= 6; | |
} | |
target.h = hue; | |
target.s = saturation; | |
target.l = lightness; | |
return target; | |
}, | |
getStyle: function () { | |
return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')'; | |
}, | |
offsetHSL: function ( h, s, l ) { | |
this.getHSL( _hslA ); | |
_hslA.h += h; _hslA.s += s; _hslA.l += l; | |
this.setHSL( _hslA.h, _hslA.s, _hslA.l ); | |
return this; | |
}, | |
add: function ( color ) { | |
this.r += color.r; | |
this.g += color.g; | |
this.b += color.b; | |
return this; | |
}, | |
addColors: function ( color1, color2 ) { | |
this.r = color1.r + color2.r; | |
this.g = color1.g + color2.g; | |
this.b = color1.b + color2.b; | |
return this; | |
}, | |
addScalar: function ( s ) { | |
this.r += s; | |
this.g += s; | |
this.b += s; | |
return this; | |
}, | |
sub: function ( color ) { | |
this.r = Math.max( 0, this.r - color.r ); | |
this.g = Math.max( 0, this.g - color.g ); | |
this.b = Math.max( 0, this.b - color.b ); | |
return this; | |
}, | |
multiply: function ( color ) { | |
this.r *= color.r; | |
this.g *= color.g; | |
this.b *= color.b; | |
return this; | |
}, | |
multiplyScalar: function ( s ) { | |
this.r *= s; | |
this.g *= s; | |
this.b *= s; | |
return this; | |
}, | |
lerp: function ( color, alpha ) { | |
this.r += ( color.r - this.r ) * alpha; | |
this.g += ( color.g - this.g ) * alpha; | |
this.b += ( color.b - this.b ) * alpha; | |
return this; | |
}, | |
lerpHSL: function ( color, alpha ) { | |
this.getHSL( _hslA ); | |
color.getHSL( _hslB ); | |
var h = MathUtils.lerp( _hslA.h, _hslB.h, alpha ); | |
var s = MathUtils.lerp( _hslA.s, _hslB.s, alpha ); | |
var l = MathUtils.lerp( _hslA.l, _hslB.l, alpha ); | |
this.setHSL( h, s, l ); | |
return this; | |
}, | |
equals: function ( c ) { | |
return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); | |
}, | |
fromArray: function ( array, offset ) { | |
if ( offset === undefined ) { offset = 0; } | |
this.r = array[ offset ]; | |
this.g = array[ offset + 1 ]; | |
this.b = array[ offset + 2 ]; | |
return this; | |
}, | |
toArray: function ( array, offset ) { | |
if ( array === undefined ) { array = []; } | |
if ( offset === undefined ) { offset = 0; } | |
array[ offset ] = this.r; | |
array[ offset + 1 ] = this.g; | |
array[ offset + 2 ] = this.b; | |
return array; | |
}, | |
toJSON: function () { | |
return this.getHex(); | |
} | |
} ); | |
Color.NAMES = _colorKeywords; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author alteredq / http://alteredqualia.com/ | |
*/ | |
function Face3( a, b, c, normal, color, materialIndex ) { | |
this.a = a; | |
this.b = b; | |
this.c = c; | |
this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3(); | |
this.vertexNormals = Array.isArray( normal ) ? normal : []; | |
this.color = ( color && color.isColor ) ? color : new Color(); | |
this.vertexColors = Array.isArray( color ) ? color : []; | |
this.materialIndex = materialIndex !== undefined ? materialIndex : 0; | |
} | |
Object.assign( Face3.prototype, { | |
clone: function () { | |
return new this.constructor().copy( this ); | |
}, | |
copy: function ( source ) { | |
this.a = source.a; | |
this.b = source.b; | |
this.c = source.c; | |
this.normal.copy( source.normal ); | |
this.color.copy( source.color ); | |
this.materialIndex = source.materialIndex; | |
for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) { | |
this.vertexNormals[ i ] = source.vertexNormals[ i ].clone(); | |
} | |
for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) { | |
this.vertexColors[ i ] = source.vertexColors[ i ].clone(); | |
} | |
return this; | |
} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author alteredq / http://alteredqualia.com/ | |
*/ | |
var materialId = 0; | |
function Material() { | |
Object.defineProperty( this, 'id', { value: materialId ++ } ); | |
this.uuid = MathUtils.generateUUID(); | |
this.name = ''; | |
this.type = 'Material'; | |
this.fog = true; | |
this.blending = NormalBlending; | |
this.side = FrontSide; | |
this.flatShading = false; | |
this.vertexColors = false; | |
this.opacity = 1; | |
this.transparent = false; | |
this.blendSrc = SrcAlphaFactor; | |
this.blendDst = OneMinusSrcAlphaFactor; | |
this.blendEquation = AddEquation; | |
this.blendSrcAlpha = null; | |
this.blendDstAlpha = null; | |
this.blendEquationAlpha = null; | |
this.depthFunc = LessEqualDepth; | |
this.depthTest = true; | |
this.depthWrite = true; | |
this.stencilWriteMask = 0xff; | |
this.stencilFunc = AlwaysStencilFunc; | |
this.stencilRef = 0; | |
this.stencilFuncMask = 0xff; | |
this.stencilFail = KeepStencilOp; | |
this.stencilZFail = KeepStencilOp; | |
this.stencilZPass = KeepStencilOp; | |
this.stencilWrite = false; | |
this.clippingPlanes = null; | |
this.clipIntersection = false; | |
this.clipShadows = false; | |
this.shadowSide = null; | |
this.colorWrite = true; | |
this.precision = null; // override the renderer's default precision for this material | |
this.polygonOffset = false; | |
this.polygonOffsetFactor = 0; | |
this.polygonOffsetUnits = 0; | |
this.dithering = false; | |
this.alphaTest = 0; | |
this.premultipliedAlpha = false; | |
this.visible = true; | |
this.toneMapped = true; | |
this.userData = {}; | |
this.version = 0; | |
} | |
Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { | |
constructor: Material, | |
isMaterial: true, | |
onBeforeCompile: function () {}, | |
setValues: function ( values ) { | |
if ( values === undefined ) { return; } | |
for ( var key in values ) { | |
var newValue = values[ key ]; | |
if ( newValue === undefined ) { | |
console.warn( "THREE.Material: '" + key + "' parameter is undefined." ); | |
continue; | |
} | |
// for backward compatability if shading is set in the constructor | |
if ( key === 'shading' ) { | |
console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); | |
this.flatShading = ( newValue === FlatShading ) ? true : false; | |
continue; | |
} | |
var currentValue = this[ key ]; | |
if ( currentValue === undefined ) { | |
console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." ); | |
continue; | |
} | |
if ( currentValue && currentValue.isColor ) { | |
currentValue.set( newValue ); | |
} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { | |
currentValue.copy( newValue ); | |
} else { | |
this[ key ] = newValue; | |
} | |
} | |
}, | |
toJSON: function ( meta ) { | |
var isRoot = ( meta === undefined || typeof meta === 'string' ); | |
if ( isRoot ) { | |
meta = { | |
textures: {}, | |
images: {} | |
}; | |
} | |
var data = { | |
metadata: { | |
version: 4.5, | |
type: 'Material', | |
generator: 'Material.toJSON' | |
} | |
}; | |
// standard Material serialization | |
data.uuid = this.uuid; | |
data.type = this.type; | |
if ( this.name !== '' ) { data.name = this.name; } | |
if ( this.color && this.color.isColor ) { data.color = this.color.getHex(); } | |
if ( this.roughness !== undefined ) { data.roughness = this.roughness; } | |
if ( this.metalness !== undefined ) { data.metalness = this.metalness; } | |
if ( this.sheen && this.sheen.isColor ) { data.sheen = this.sheen.getHex(); } | |
if ( this.emissive && this.emissive.isColor ) { data.emissive = this.emissive.getHex(); } | |
if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) { data.emissiveIntensity = this.emissiveIntensity; } | |
if ( this.specular && this.specular.isColor ) { data.specular = this.specular.getHex(); } | |
if ( this.shininess !== undefined ) { data.shininess = this.shininess; } | |
if ( this.clearcoat !== undefined ) { data.clearcoat = this.clearcoat; } | |
if ( this.clearcoatRoughness !== undefined ) { data.clearcoatRoughness = this.clearcoatRoughness; } | |
if ( this.clearcoatMap && this.clearcoatMap.isTexture ) { | |
data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid; | |
} | |
if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) { | |
data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid; | |
} | |
if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { | |
data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; | |
data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); | |
} | |
if ( this.map && this.map.isTexture ) { data.map = this.map.toJSON( meta ).uuid; } | |
if ( this.matcap && this.matcap.isTexture ) { data.matcap = this.matcap.toJSON( meta ).uuid; } | |
if ( this.alphaMap && this.alphaMap.isTexture ) { data.alphaMap = this.alphaMap.toJSON( meta ).uuid; } | |
if ( this.lightMap && this.lightMap.isTexture ) { data.lightMap = this.lightMap.toJSON( meta ).uuid; } | |
if ( this.aoMap && this.aoMap.isTexture ) { | |
data.aoMap = this.aoMap.toJSON( meta ).uuid; | |
data.aoMapIntensity = this.aoMapIntensity; | |
} | |
if ( this.bumpMap && this.bumpMap.isTexture ) { | |
data.bumpMap = this.bumpMap.toJSON( meta ).uuid; | |
data.bumpScale = this.bumpScale; | |
} | |
if ( this.normalMap && this.normalMap.isTexture ) { | |
data.normalMap = this.normalMap.toJSON( meta ).uuid; | |
data.normalMapType = this.normalMapType; | |
data.normalScale = this.normalScale.toArray(); | |
} | |
if ( this.displacementMap && this.displacementMap.isTexture ) { | |
data.displacementMap = this.displacementMap.toJSON( meta ).uuid; | |
data.displacementScale = this.displacementScale; | |
data.displacementBias = this.displacementBias; | |
} | |
if ( this.roughnessMap && this.roughnessMap.isTexture ) { data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; } | |
if ( this.metalnessMap && this.metalnessMap.isTexture ) { data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; } | |
if ( this.emissiveMap && this.emissiveMap.isTexture ) { data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; } | |
if ( this.specularMap && this.specularMap.isTexture ) { data.specularMap = this.specularMap.toJSON( meta ).uuid; } | |
if ( this.envMap && this.envMap.isTexture ) { | |
data.envMap = this.envMap.toJSON( meta ).uuid; | |
data.reflectivity = this.reflectivity; // Scale behind envMap | |
data.refractionRatio = this.refractionRatio; | |
if ( this.combine !== undefined ) { data.combine = this.combine; } | |
if ( this.envMapIntensity !== undefined ) { data.envMapIntensity = this.envMapIntensity; } | |
} | |
if ( this.gradientMap && this.gradientMap.isTexture ) { | |
data.gradientMap = this.gradientMap.toJSON( meta ).uuid; | |
} | |
if ( this.size !== undefined ) { data.size = this.size; } | |
if ( this.sizeAttenuation !== undefined ) { data.sizeAttenuation = this.sizeAttenuation; } | |
if ( this.blending !== NormalBlending ) { data.blending = this.blending; } | |
if ( this.flatShading === true ) { data.flatShading = this.flatShading; } | |
if ( this.side !== FrontSide ) { data.side = this.side; } | |
if ( this.vertexColors ) { data.vertexColors = true; } | |
if ( this.opacity < 1 ) { data.opacity = this.opacity; } | |
if ( this.transparent === true ) { data.transparent = this.transparent; } | |
data.depthFunc = this.depthFunc; | |
data.depthTest = this.depthTest; | |
data.depthWrite = this.depthWrite; | |
data.stencilWrite = this.stencilWrite; | |
data.stencilWriteMask = this.stencilWriteMask; | |
data.stencilFunc = this.stencilFunc; | |
data.stencilRef = this.stencilRef; | |
data.stencilFuncMask = this.stencilFuncMask; | |
data.stencilFail = this.stencilFail; | |
data.stencilZFail = this.stencilZFail; | |
data.stencilZPass = this.stencilZPass; | |
// rotation (SpriteMaterial) | |
if ( this.rotation && this.rotation !== 0 ) { data.rotation = this.rotation; } | |
if ( this.polygonOffset === true ) { data.polygonOffset = true; } | |
if ( this.polygonOffsetFactor !== 0 ) { data.polygonOffsetFactor = this.polygonOffsetFactor; } | |
if ( this.polygonOffsetUnits !== 0 ) { data.polygonOffsetUnits = this.polygonOffsetUnits; } | |
if ( this.linewidth && this.linewidth !== 1 ) { data.linewidth = this.linewidth; } | |
if ( this.dashSize !== undefined ) { data.dashSize = this.dashSize; } | |
if ( this.gapSize !== undefined ) { data.gapSize = this.gapSize; } | |
if ( this.scale !== undefined ) { data.scale = this.scale; } | |
if ( this.dithering === true ) { data.dithering = true; } | |
if ( this.alphaTest > 0 ) { data.alphaTest = this.alphaTest; } | |
if ( this.premultipliedAlpha === true ) { data.premultipliedAlpha = this.premultipliedAlpha; } | |
if ( this.wireframe === true ) { data.wireframe = this.wireframe; } | |
if ( this.wireframeLinewidth > 1 ) { data.wireframeLinewidth = this.wireframeLinewidth; } | |
if ( this.wireframeLinecap !== 'round' ) { data.wireframeLinecap = this.wireframeLinecap; } | |
if ( this.wireframeLinejoin !== 'round' ) { data.wireframeLinejoin = this.wireframeLinejoin; } | |
if ( this.morphTargets === true ) { data.morphTargets = true; } | |
if ( this.morphNormals === true ) { data.morphNormals = true; } | |
if ( this.skinning === true ) { data.skinning = true; } | |
if ( this.visible === false ) { data.visible = false; } | |
if ( this.toneMapped === false ) { data.toneMapped = false; } | |
if ( JSON.stringify( this.userData ) !== '{}' ) { data.userData = this.userData; } | |
// TODO: Copied from Object3D.toJSON | |
function extractFromCache( cache ) { | |
var values = []; | |
for ( var key in cache ) { | |
var data = cache[ key ]; | |
delete data.metadata; | |
values.push( data ); | |
} | |
return values; | |
} | |
if ( isRoot ) { | |
var textures = extractFromCache( meta.textures ); | |
var images = extractFromCache( meta.images ); | |
if ( textures.length > 0 ) { data.textures = textures; } | |
if ( images.length > 0 ) { data.images = images; } | |
} | |
return data; | |
}, | |
clone: function () { | |
return new this.constructor().copy( this ); | |
}, | |
copy: function ( source ) { | |
this.name = source.name; | |
this.fog = source.fog; | |
this.blending = source.blending; | |
this.side = source.side; | |
this.flatShading = source.flatShading; | |
this.vertexColors = source.vertexColors; | |
this.opacity = source.opacity; | |
this.transparent = source.transparent; | |
this.blendSrc = source.blendSrc; | |
this.blendDst = source.blendDst; | |
this.blendEquation = source.blendEquation; | |
this.blendSrcAlpha = source.blendSrcAlpha; | |
this.blendDstAlpha = source.blendDstAlpha; | |
this.blendEquationAlpha = source.blendEquationAlpha; | |
this.depthFunc = source.depthFunc; | |
this.depthTest = source.depthTest; | |
this.depthWrite = source.depthWrite; | |
this.stencilWriteMask = source.stencilWriteMask; | |
this.stencilFunc = source.stencilFunc; | |
this.stencilRef = source.stencilRef; | |
this.stencilFuncMask = source.stencilFuncMask; | |
this.stencilFail = source.stencilFail; | |
this.stencilZFail = source.stencilZFail; | |
this.stencilZPass = source.stencilZPass; | |
this.stencilWrite = source.stencilWrite; | |
var srcPlanes = source.clippingPlanes, | |
dstPlanes = null; | |
if ( srcPlanes !== null ) { | |
var n = srcPlanes.length; | |
dstPlanes = new Array( n ); | |
for ( var i = 0; i !== n; ++ i ) | |
{ dstPlanes[ i ] = srcPlanes[ i ].clone(); } | |
} | |
this.clippingPlanes = dstPlanes; | |
this.clipIntersection = source.clipIntersection; | |
this.clipShadows = source.clipShadows; | |
this.shadowSide = source.shadowSide; | |
this.colorWrite = source.colorWrite; | |
this.precision = source.precision; | |
this.polygonOffset = source.polygonOffset; | |
this.polygonOffsetFactor = source.polygonOffsetFactor; | |
this.polygonOffsetUnits = source.polygonOffsetUnits; | |
this.dithering = source.dithering; | |
this.alphaTest = source.alphaTest; | |
this.premultipliedAlpha = source.premultipliedAlpha; | |
this.visible = source.visible; | |
this.toneMapped = source.toneMapped; | |
this.userData = JSON.parse( JSON.stringify( source.userData ) ); | |
return this; | |
}, | |
dispose: function () { | |
this.dispatchEvent( { type: 'dispose' } ); | |
} | |
} ); | |
Object.defineProperty( Material.prototype, 'needsUpdate', { | |
set: function ( value ) { | |
if ( value === true ) { this.version ++; } | |
} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author alteredq / http://alteredqualia.com/ | |
* | |
* parameters = { | |
* color: <hex>, | |
* opacity: <float>, | |
* map: new THREE.Texture( <Image> ), | |
* | |
* lightMap: new THREE.Texture( <Image> ), | |
* lightMapIntensity: <float> | |
* | |
* aoMap: new THREE.Texture( <Image> ), | |
* aoMapIntensity: <float> | |
* | |
* specularMap: new THREE.Texture( <Image> ), | |
* | |
* alphaMap: new THREE.Texture( <Image> ), | |
* | |
* envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), | |
* combine: THREE.Multiply, | |
* reflectivity: <float>, | |
* refractionRatio: <float>, | |
* | |
* depthTest: <bool>, | |
* depthWrite: <bool>, | |
* | |
* wireframe: <boolean>, | |
* wireframeLinewidth: <float>, | |
* | |
* skinning: <bool>, | |
* morphTargets: <bool> | |
* } | |
*/ | |
function MeshBasicMaterial( parameters ) { | |
Material.call( this ); | |
this.type = 'MeshBasicMaterial'; | |
this.color = new Color( 0xffffff ); // emissive | |
this.map = null; | |
this.lightMap = null; | |
this.lightMapIntensity = 1.0; | |
this.aoMap = null; | |
this.aoMapIntensity = 1.0; | |
this.specularMap = null; | |
this.alphaMap = null; | |
this.envMap = null; | |
this.combine = MultiplyOperation; | |
this.reflectivity = 1; | |
this.refractionRatio = 0.98; | |
this.wireframe = false; | |
this.wireframeLinewidth = 1; | |
this.wireframeLinecap = 'round'; | |
this.wireframeLinejoin = 'round'; | |
this.skinning = false; | |
this.morphTargets = false; | |
this.setValues( parameters ); | |
} | |
MeshBasicMaterial.prototype = Object.create( Material.prototype ); | |
MeshBasicMaterial.prototype.constructor = MeshBasicMaterial; | |
MeshBasicMaterial.prototype.isMeshBasicMaterial = true; | |
MeshBasicMaterial.prototype.copy = function ( source ) { | |
Material.prototype.copy.call( this, source ); | |
this.color.copy( source.color ); | |
this.map = source.map; | |
this.lightMap = source.lightMap; | |
this.lightMapIntensity = source.lightMapIntensity; | |
this.aoMap = source.aoMap; | |
this.aoMapIntensity = source.aoMapIntensity; | |
this.specularMap = source.specularMap; | |
this.alphaMap = source.alphaMap; | |
this.envMap = source.envMap; | |
this.combine = source.combine; | |
this.reflectivity = source.reflectivity; | |
this.refractionRatio = source.refractionRatio; | |
this.wireframe = source.wireframe; | |
this.wireframeLinewidth = source.wireframeLinewidth; | |
this.wireframeLinecap = source.wireframeLinecap; | |
this.wireframeLinejoin = source.wireframeLinejoin; | |
this.skinning = source.skinning; | |
this.morphTargets = source.morphTargets; | |
return this; | |
}; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
var _vector$3 = new Vector3(); | |
function BufferAttribute( array, itemSize, normalized ) { | |
if ( Array.isArray( array ) ) { | |
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); | |
} | |
this.name = ''; | |
this.array = array; | |
this.itemSize = itemSize; | |
this.count = array !== undefined ? array.length / itemSize : 0; | |
this.normalized = normalized === true; | |
this.usage = StaticDrawUsage; | |
this.updateRange = { offset: 0, count: - 1 }; | |
this.version = 0; | |
} | |
Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', { | |
set: function ( value ) { | |
if ( value === true ) { this.version ++; } | |
} | |
} ); | |
Object.assign( BufferAttribute.prototype, { | |
isBufferAttribute: true, | |
onUploadCallback: function () {}, | |
setUsage: function ( value ) { | |
this.usage = value; | |
return this; | |
}, | |
copy: function ( source ) { | |
this.name = source.name; | |
this.array = new source.array.constructor( source.array ); | |
this.itemSize = source.itemSize; | |
this.count = source.count; | |
this.normalized = source.normalized; | |
this.usage = source.usage; | |
return this; | |
}, | |
copyAt: function ( index1, attribute, index2 ) { | |
index1 *= this.itemSize; | |
index2 *= attribute.itemSize; | |
for ( var i = 0, l = this.itemSize; i < l; i ++ ) { | |
this.array[ index1 + i ] = attribute.array[ index2 + i ]; | |
} | |
return this; | |
}, | |
copyArray: function ( array ) { | |
this.array.set( array ); | |
return this; | |
}, | |
copyColorsArray: function ( colors ) { | |
var array = this.array, offset = 0; | |
for ( var i = 0, l = colors.length; i < l; i ++ ) { | |
var color = colors[ i ]; | |
if ( color === undefined ) { | |
console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i ); | |
color = new Color(); | |
} | |
array[ offset ++ ] = color.r; | |
array[ offset ++ ] = color.g; | |
array[ offset ++ ] = color.b; | |
} | |
return this; | |
}, | |
copyVector2sArray: function ( vectors ) { | |
var array = this.array, offset = 0; | |
for ( var i = 0, l = vectors.length; i < l; i ++ ) { | |
var vector = vectors[ i ]; | |
if ( vector === undefined ) { | |
console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i ); | |
vector = new Vector2(); | |
} | |
array[ offset ++ ] = vector.x; | |
array[ offset ++ ] = vector.y; | |
} | |
return this; | |
}, | |
copyVector3sArray: function ( vectors ) { | |
var array = this.array, offset = 0; | |
for ( var i = 0, l = vectors.length; i < l; i ++ ) { | |
var vector = vectors[ i ]; | |
if ( vector === undefined ) { | |
console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i ); | |
vector = new Vector3(); | |
} | |
array[ offset ++ ] = vector.x; | |
array[ offset ++ ] = vector.y; | |
array[ offset ++ ] = vector.z; | |
} | |
return this; | |
}, | |
copyVector4sArray: function ( vectors ) { | |
var array = this.array, offset = 0; | |
for ( var i = 0, l = vectors.length; i < l; i ++ ) { | |
var vector = vectors[ i ]; | |
if ( vector === undefined ) { | |
console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i ); | |
vector = new Vector4(); | |
} | |
array[ offset ++ ] = vector.x; | |
array[ offset ++ ] = vector.y; | |
array[ offset ++ ] = vector.z; | |
array[ offset ++ ] = vector.w; | |
} | |
return this; | |
}, | |
applyMatrix3: function ( m ) { | |
for ( var i = 0, l = this.count; i < l; i ++ ) { | |
_vector$3.x = this.getX( i ); | |
_vector$3.y = this.getY( i ); | |
_vector$3.z = this.getZ( i ); | |
_vector$3.applyMatrix3( m ); | |
this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); | |
} | |
return this; | |
}, | |
applyMatrix4: function ( m ) { | |
for ( var i = 0, l = this.count; i < l; i ++ ) { | |
_vector$3.x = this.getX( i ); | |
_vector$3.y = this.getY( i ); | |
_vector$3.z = this.getZ( i ); | |
_vector$3.applyMatrix4( m ); | |
this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); | |
} | |
return this; | |
}, | |
applyNormalMatrix: function ( m ) { | |
for ( var i = 0, l = this.count; i < l; i ++ ) { | |
_vector$3.x = this.getX( i ); | |
_vector$3.y = this.getY( i ); | |
_vector$3.z = this.getZ( i ); | |
_vector$3.applyNormalMatrix( m ); | |
this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); | |
} | |
return this; | |
}, | |
transformDirection: function ( m ) { | |
for ( var i = 0, l = this.count; i < l; i ++ ) { | |
_vector$3.x = this.getX( i ); | |
_vector$3.y = this.getY( i ); | |
_vector$3.z = this.getZ( i ); | |
_vector$3.transformDirection( m ); | |
this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); | |
} | |
return this; | |
}, | |
set: function ( value, offset ) { | |
if ( offset === undefined ) { offset = 0; } | |
this.array.set( value, offset ); | |
return this; | |
}, | |
getX: function ( index ) { | |
return this.array[ index * this.itemSize ]; | |
}, | |
setX: function ( index, x ) { | |
this.array[ index * this.itemSize ] = x; | |
return this; | |
}, | |
getY: function ( index ) { | |
return this.array[ index * this.itemSize + 1 ]; | |
}, | |
setY: function ( index, y ) { | |
this.array[ index * this.itemSize + 1 ] = y; | |
return this; | |
}, | |
getZ: function ( index ) { | |
return this.array[ index * this.itemSize + 2 ]; | |
}, | |
setZ: function ( index, z ) { | |
this.array[ index * this.itemSize + 2 ] = z; | |
return this; | |
}, | |
getW: function ( index ) { | |
return this.array[ index * this.itemSize + 3 ]; | |
}, | |
setW: function ( index, w ) { | |
this.array[ index * this.itemSize + 3 ] = w; | |
return this; | |
}, | |
setXY: function ( index, x, y ) { | |
index *= this.itemSize; | |
this.array[ index + 0 ] = x; | |
this.array[ index + 1 ] = y; | |
return this; | |
}, | |
setXYZ: function ( index, x, y, z ) { | |
index *= this.itemSize; | |
this.array[ index + 0 ] = x; | |
this.array[ index + 1 ] = y; | |
this.array[ index + 2 ] = z; | |
return this; | |
}, | |
setXYZW: function ( index, x, y, z, w ) { | |
index *= this.itemSize; | |
this.array[ index + 0 ] = x; | |
this.array[ index + 1 ] = y; | |
this.array[ index + 2 ] = z; | |
this.array[ index + 3 ] = w; | |
return this; | |
}, | |
onUpload: function ( callback ) { | |
this.onUploadCallback = callback; | |
return this; | |
}, | |
clone: function () { | |
return new this.constructor( this.array, this.itemSize ).copy( this ); | |
}, | |
toJSON: function () { | |
return { | |
itemSize: this.itemSize, | |
type: this.array.constructor.name, | |
array: Array.prototype.slice.call( this.array ), | |
normalized: this.normalized | |
}; | |
} | |
} ); | |
// | |
function Int8BufferAttribute( array, itemSize, normalized ) { | |
BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized ); | |
} | |
Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); | |
Int8BufferAttribute.prototype.constructor = Int8BufferAttribute; | |
function Uint8BufferAttribute( array, itemSize, normalized ) { | |
BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized ); | |
} | |
Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); | |
Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute; | |
function Uint8ClampedBufferAttribute( array, itemSize, normalized ) { | |
BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized ); | |
} | |
Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype ); | |
Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute; | |
function Int16BufferAttribute( array, itemSize, normalized ) { | |
BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized ); | |
} | |
Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); | |
Int16BufferAttribute.prototype.constructor = Int16BufferAttribute; | |
function Uint16BufferAttribute( array, itemSize, normalized ) { | |
BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized ); | |
} | |
Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); | |
Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute; | |
function Int32BufferAttribute( array, itemSize, normalized ) { | |
BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized ); | |
} | |
Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); | |
Int32BufferAttribute.prototype.constructor = Int32BufferAttribute; | |
function Uint32BufferAttribute( array, itemSize, normalized ) { | |
BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized ); | |
} | |
Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); | |
Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute; | |
function Float32BufferAttribute( array, itemSize, normalized ) { | |
BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized ); | |
} | |
Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); | |
Float32BufferAttribute.prototype.constructor = Float32BufferAttribute; | |
function Float64BufferAttribute( array, itemSize, normalized ) { | |
BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized ); | |
} | |
Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); | |
Float64BufferAttribute.prototype.constructor = Float64BufferAttribute; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function DirectGeometry() { | |
this.vertices = []; | |
this.normals = []; | |
this.colors = []; | |
this.uvs = []; | |
this.uvs2 = []; | |
this.groups = []; | |
this.morphTargets = {}; | |
this.skinWeights = []; | |
this.skinIndices = []; | |
// this.lineDistances = []; | |
this.boundingBox = null; | |
this.boundingSphere = null; | |
// update flags | |
this.verticesNeedUpdate = false; | |
this.normalsNeedUpdate = false; | |
this.colorsNeedUpdate = false; | |
this.uvsNeedUpdate = false; | |
this.groupsNeedUpdate = false; | |
} | |
Object.assign( DirectGeometry.prototype, { | |
computeGroups: function ( geometry ) { | |
var group; | |
var groups = []; | |
var materialIndex = undefined; | |
var faces = geometry.faces; | |
for ( var i = 0; i < faces.length; i ++ ) { | |
var face = faces[ i ]; | |
// materials | |
if ( face.materialIndex !== materialIndex ) { | |
materialIndex = face.materialIndex; | |
if ( group !== undefined ) { | |
group.count = ( i * 3 ) - group.start; | |
groups.push( group ); | |
} | |
group = { | |
start: i * 3, | |
materialIndex: materialIndex | |
}; | |
} | |
} | |
if ( group !== undefined ) { | |
group.count = ( i * 3 ) - group.start; | |
groups.push( group ); | |
} | |
this.groups = groups; | |
}, | |
fromGeometry: function ( geometry ) { | |
var faces = geometry.faces; | |
var vertices = geometry.vertices; | |
var faceVertexUvs = geometry.faceVertexUvs; | |
var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0; | |
var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0; | |
// morphs | |
var morphTargets = geometry.morphTargets; | |
var morphTargetsLength = morphTargets.length; | |
var morphTargetsPosition; | |
if ( morphTargetsLength > 0 ) { | |
morphTargetsPosition = []; | |
for ( var i = 0; i < morphTargetsLength; i ++ ) { | |
morphTargetsPosition[ i ] = { | |
name: morphTargets[ i ].name, | |
data: [] | |
}; | |
} | |
this.morphTargets.position = morphTargetsPosition; | |
} | |
var morphNormals = geometry.morphNormals; | |
var morphNormalsLength = morphNormals.length; | |
var morphTargetsNormal; | |
if ( morphNormalsLength > 0 ) { | |
morphTargetsNormal = []; | |
for ( var i = 0; i < morphNormalsLength; i ++ ) { | |
morphTargetsNormal[ i ] = { | |
name: morphNormals[ i ].name, | |
data: [] | |
}; | |
} | |
this.morphTargets.normal = morphTargetsNormal; | |
} | |
// skins | |
var skinIndices = geometry.skinIndices; | |
var skinWeights = geometry.skinWeights; | |
var hasSkinIndices = skinIndices.length === vertices.length; | |
var hasSkinWeights = skinWeights.length === vertices.length; | |
// | |
if ( vertices.length > 0 && faces.length === 0 ) { | |
console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' ); | |
} | |
for ( var i = 0; i < faces.length; i ++ ) { | |
var face = faces[ i ]; | |
this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] ); | |
var vertexNormals = face.vertexNormals; | |
if ( vertexNormals.length === 3 ) { | |
this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] ); | |
} else { | |
var normal = face.normal; | |
this.normals.push( normal, normal, normal ); | |
} | |
var vertexColors = face.vertexColors; | |
if ( vertexColors.length === 3 ) { | |
this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] ); | |
} else { | |
var color = face.color; | |
this.colors.push( color, color, color ); | |
} | |
if ( hasFaceVertexUv === true ) { | |
var vertexUvs = faceVertexUvs[ 0 ][ i ]; | |
if ( vertexUvs !== undefined ) { | |
this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); | |
} else { | |
console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i ); | |
this.uvs.push( new Vector2(), new Vector2(), new Vector2() ); | |
} | |
} | |
if ( hasFaceVertexUv2 === true ) { | |
var vertexUvs = faceVertexUvs[ 1 ][ i ]; | |
if ( vertexUvs !== undefined ) { | |
this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); | |
} else { | |
console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i ); | |
this.uvs2.push( new Vector2(), new Vector2(), new Vector2() ); | |
} | |
} | |
// morphs | |
for ( var j = 0; j < morphTargetsLength; j ++ ) { | |
var morphTarget = morphTargets[ j ].vertices; | |
morphTargetsPosition[ j ].data.push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] ); | |
} | |
for ( var j = 0; j < morphNormalsLength; j ++ ) { | |
var morphNormal = morphNormals[ j ].vertexNormals[ i ]; | |
morphTargetsNormal[ j ].data.push( morphNormal.a, morphNormal.b, morphNormal.c ); | |
} | |
// skins | |
if ( hasSkinIndices ) { | |
this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] ); | |
} | |
if ( hasSkinWeights ) { | |
this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] ); | |
} | |
} | |
this.computeGroups( geometry ); | |
this.verticesNeedUpdate = geometry.verticesNeedUpdate; | |
this.normalsNeedUpdate = geometry.normalsNeedUpdate; | |
this.colorsNeedUpdate = geometry.colorsNeedUpdate; | |
this.uvsNeedUpdate = geometry.uvsNeedUpdate; | |
this.groupsNeedUpdate = geometry.groupsNeedUpdate; | |
if ( geometry.boundingSphere !== null ) { | |
this.boundingSphere = geometry.boundingSphere.clone(); | |
} | |
if ( geometry.boundingBox !== null ) { | |
this.boundingBox = geometry.boundingBox.clone(); | |
} | |
return this; | |
} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function arrayMax( array ) { | |
if ( array.length === 0 ) { return - Infinity; } | |
var max = array[ 0 ]; | |
for ( var i = 1, l = array.length; i < l; ++ i ) { | |
if ( array[ i ] > max ) { max = array[ i ]; } | |
} | |
return max; | |
} | |
/** | |
* @author alteredq / http://alteredqualia.com/ | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
var _bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id | |
var _m1$2 = new Matrix4(); | |
var _obj = new Object3D(); | |
var _offset = new Vector3(); | |
var _box$2 = new Box3(); | |
var _boxMorphTargets = new Box3(); | |
var _vector$4 = new Vector3(); | |
function BufferGeometry() { | |
Object.defineProperty( this, 'id', { value: _bufferGeometryId += 2 } ); | |
this.uuid = MathUtils.generateUUID(); | |
this.name = ''; | |
this.type = 'BufferGeometry'; | |
this.index = null; | |
this.attributes = {}; | |
this.morphAttributes = {}; | |
this.morphTargetsRelative = false; | |
this.groups = []; | |
this.boundingBox = null; | |
this.boundingSphere = null; | |
this.drawRange = { start: 0, count: Infinity }; | |
this.userData = {}; | |
} | |
BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { | |
constructor: BufferGeometry, | |
isBufferGeometry: true, | |
getIndex: function () { | |
return this.index; | |
}, | |
setIndex: function ( index ) { | |
if ( Array.isArray( index ) ) { | |
this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 ); | |
} else { | |
this.index = index; | |
} | |
}, | |
getAttribute: function ( name ) { | |
return this.attributes[ name ]; | |
}, | |
setAttribute: function ( name, attribute ) { | |
this.attributes[ name ] = attribute; | |
return this; | |
}, | |
deleteAttribute: function ( name ) { | |
delete this.attributes[ name ]; | |
return this; | |
}, | |
addGroup: function ( start, count, materialIndex ) { | |
this.groups.push( { | |
start: start, | |
count: count, | |
materialIndex: materialIndex !== undefined ? materialIndex : 0 | |
} ); | |
}, | |
clearGroups: function () { | |
this.groups = []; | |
}, | |
setDrawRange: function ( start, count ) { | |
this.drawRange.start = start; | |
this.drawRange.count = count; | |
}, | |
applyMatrix4: function ( matrix ) { | |
var position = this.attributes.position; | |
if ( position !== undefined ) { | |
position.applyMatrix4( matrix ); | |
position.needsUpdate = true; | |
} | |
var normal = this.attributes.normal; | |
if ( normal !== undefined ) { | |
var normalMatrix = new Matrix3().getNormalMatrix( matrix ); | |
normal.applyNormalMatrix( normalMatrix ); | |
normal.needsUpdate = true; | |
} | |
var tangent = this.attributes.tangent; | |
if ( tangent !== undefined ) { | |
tangent.transformDirection( matrix ); | |
tangent.needsUpdate = true; | |
} | |
if ( this.boundingBox !== null ) { | |
this.computeBoundingBox(); | |
} | |
if ( this.boundingSphere !== null ) { | |
this.computeBoundingSphere(); | |
} | |
return this; | |
}, | |
rotateX: function ( angle ) { | |
// rotate geometry around world x-axis | |
_m1$2.makeRotationX( angle ); | |
this.applyMatrix4( _m1$2 ); | |
return this; | |
}, | |
rotateY: function ( angle ) { | |
// rotate geometry around world y-axis | |
_m1$2.makeRotationY( angle ); | |
this.applyMatrix4( _m1$2 ); | |
return this; | |
}, | |
rotateZ: function ( angle ) { | |
// rotate geometry around world z-axis | |
_m1$2.makeRotationZ( angle ); | |
this.applyMatrix4( _m1$2 ); | |
return this; | |
}, | |
translate: function ( x, y, z ) { | |
// translate geometry | |
_m1$2.makeTranslation( x, y, z ); | |
this.applyMatrix4( _m1$2 ); | |
return this; | |
}, | |
scale: function ( x, y, z ) { | |
// scale geometry | |
_m1$2.makeScale( x, y, z ); | |
this.applyMatrix4( _m1$2 ); | |
return this; | |
}, | |
lookAt: function ( vector ) { | |
_obj.lookAt( vector ); | |
_obj.updateMatrix(); | |
this.applyMatrix4( _obj.matrix ); | |
return this; | |
}, | |
center: function () { | |
this.computeBoundingBox(); | |
this.boundingBox.getCenter( _offset ).negate(); | |
this.translate( _offset.x, _offset.y, _offset.z ); | |
return this; | |
}, | |
setFromObject: function ( object ) { | |
// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this ); | |
var geometry = object.geometry; | |
if ( object.isPoints || object.isLine ) { | |
var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 ); | |
var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 ); | |
this.setAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); | |
this.setAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); | |
if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) { | |
var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 ); | |
this.setAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); | |
} | |
if ( geometry.boundingSphere !== null ) { | |
this.boundingSphere = geometry.boundingSphere.clone(); | |
} | |
if ( geometry.boundingBox !== null ) { | |
this.boundingBox = geometry.boundingBox.clone(); | |
} | |
} else if ( object.isMesh ) { | |
if ( geometry && geometry.isGeometry ) { | |
this.fromGeometry( geometry ); | |
} | |
} | |
return this; | |
}, | |
setFromPoints: function ( points ) { | |
var position = []; | |
for ( var i = 0, l = points.length; i < l; i ++ ) { | |
var point = points[ i ]; | |
position.push( point.x, point.y, point.z || 0 ); | |
} | |
this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); | |
return this; | |
}, | |
updateFromObject: function ( object ) { | |
var geometry = object.geometry; | |
if ( object.isMesh ) { | |
var direct = geometry.__directGeometry; | |
if ( geometry.elementsNeedUpdate === true ) { | |
direct = undefined; | |
geometry.elementsNeedUpdate = false; | |
} | |
if ( direct === undefined ) { | |
return this.fromGeometry( geometry ); | |
} | |
direct.verticesNeedUpdate = geometry.verticesNeedUpdate; | |
direct.normalsNeedUpdate = geometry.normalsNeedUpdate; | |
direct.colorsNeedUpdate = geometry.colorsNeedUpdate; | |
direct.uvsNeedUpdate = geometry.uvsNeedUpdate; | |
direct.groupsNeedUpdate = geometry.groupsNeedUpdate; | |
geometry.verticesNeedUpdate = false; | |
geometry.normalsNeedUpdate = false; | |
geometry.colorsNeedUpdate = false; | |
geometry.uvsNeedUpdate = false; | |
geometry.groupsNeedUpdate = false; | |
geometry = direct; | |
} | |
var attribute; | |
if ( geometry.verticesNeedUpdate === true ) { | |
attribute = this.attributes.position; | |
if ( attribute !== undefined ) { | |
attribute.copyVector3sArray( geometry.vertices ); | |
attribute.needsUpdate = true; | |
} | |
geometry.verticesNeedUpdate = false; | |
} | |
if ( geometry.normalsNeedUpdate === true ) { | |
attribute = this.attributes.normal; | |
if ( attribute !== undefined ) { | |
attribute.copyVector3sArray( geometry.normals ); | |
attribute.needsUpdate = true; | |
} | |
geometry.normalsNeedUpdate = false; | |
} | |
if ( geometry.colorsNeedUpdate === true ) { | |
attribute = this.attributes.color; | |
if ( attribute !== undefined ) { | |
attribute.copyColorsArray( geometry.colors ); | |
attribute.needsUpdate = true; | |
} | |
geometry.colorsNeedUpdate = false; | |
} | |
if ( geometry.uvsNeedUpdate ) { | |
attribute = this.attributes.uv; | |
if ( attribute !== undefined ) { | |
attribute.copyVector2sArray( geometry.uvs ); | |
attribute.needsUpdate = true; | |
} | |
geometry.uvsNeedUpdate = false; | |
} | |
if ( geometry.lineDistancesNeedUpdate ) { | |
attribute = this.attributes.lineDistance; | |
if ( attribute !== undefined ) { | |
attribute.copyArray( geometry.lineDistances ); | |
attribute.needsUpdate = true; | |
} | |
geometry.lineDistancesNeedUpdate = false; | |
} | |
if ( geometry.groupsNeedUpdate ) { | |
geometry.computeGroups( object.geometry ); | |
this.groups = geometry.groups; | |
geometry.groupsNeedUpdate = false; | |
} | |
return this; | |
}, | |
fromGeometry: function ( geometry ) { | |
geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry ); | |
return this.fromDirectGeometry( geometry.__directGeometry ); | |
}, | |
fromDirectGeometry: function ( geometry ) { | |
var positions = new Float32Array( geometry.vertices.length * 3 ); | |
this.setAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); | |
if ( geometry.normals.length > 0 ) { | |
var normals = new Float32Array( geometry.normals.length * 3 ); | |
this.setAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); | |
} | |
if ( geometry.colors.length > 0 ) { | |
var colors = new Float32Array( geometry.colors.length * 3 ); | |
this.setAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); | |
} | |
if ( geometry.uvs.length > 0 ) { | |
var uvs = new Float32Array( geometry.uvs.length * 2 ); | |
this.setAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); | |
} | |
if ( geometry.uvs2.length > 0 ) { | |
var uvs2 = new Float32Array( geometry.uvs2.length * 2 ); | |
this.setAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); | |
} | |
// groups | |
this.groups = geometry.groups; | |
// morphs | |
for ( var name in geometry.morphTargets ) { | |
var array = []; | |
var morphTargets = geometry.morphTargets[ name ]; | |
for ( var i = 0, l = morphTargets.length; i < l; i ++ ) { | |
var morphTarget = morphTargets[ i ]; | |
var attribute = new Float32BufferAttribute( morphTarget.data.length * 3, 3 ); | |
attribute.name = morphTarget.name; | |
array.push( attribute.copyVector3sArray( morphTarget.data ) ); | |
} | |
this.morphAttributes[ name ] = array; | |
} | |
// skinning | |
if ( geometry.skinIndices.length > 0 ) { | |
var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 ); | |
this.setAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); | |
} | |
if ( geometry.skinWeights.length > 0 ) { | |
var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 ); | |
this.setAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); | |
} | |
// | |
if ( geometry.boundingSphere !== null ) { | |
this.boundingSphere = geometry.boundingSphere.clone(); | |
} | |
if ( geometry.boundingBox !== null ) { | |
this.boundingBox = geometry.boundingBox.clone(); | |
} | |
return this; | |
}, | |
computeBoundingBox: function () { | |
if ( this.boundingBox === null ) { | |
this.boundingBox = new Box3(); | |
} | |
var position = this.attributes.position; | |
var morphAttributesPosition = this.morphAttributes.position; | |
if ( position !== undefined ) { | |
this.boundingBox.setFromBufferAttribute( position ); | |
// process morph attributes if present | |
if ( morphAttributesPosition ) { | |
for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { | |
var morphAttribute = morphAttributesPosition[ i ]; | |
_box$2.setFromBufferAttribute( morphAttribute ); | |
if ( this.morphTargetsRelative ) { | |
_vector$4.addVectors( this.boundingBox.min, _box$2.min ); | |
this.boundingBox.expandByPoint( _vector$4 ); | |
_vector$4.addVectors( this.boundingBox.max, _box$2.max ); | |
this.boundingBox.expandByPoint( _vector$4 ); | |
} else { | |
this.boundingBox.expandByPoint( _box$2.min ); | |
this.boundingBox.expandByPoint( _box$2.max ); | |
} | |
} | |
} | |
} else { | |
this.boundingBox.makeEmpty(); | |
} | |
if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { | |
console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); | |
} | |
}, | |
computeBoundingSphere: function () { | |
if ( this.boundingSphere === null ) { | |
this.boundingSphere = new Sphere(); | |
} | |
var position = this.attributes.position; | |
var morphAttributesPosition = this.morphAttributes.position; | |
if ( position ) { | |
// first, find the center of the bounding sphere | |
var center = this.boundingSphere.center; | |
_box$2.setFromBufferAttribute( position ); | |
// process morph attributes if present | |
if ( morphAttributesPosition ) { | |
for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { | |
var morphAttribute = morphAttributesPosition[ i ]; | |
_boxMorphTargets.setFromBufferAttribute( morphAttribute ); | |
if ( this.morphTargetsRelative ) { | |
_vector$4.addVectors( _box$2.min, _boxMorphTargets.min ); | |
_box$2.expandByPoint( _vector$4 ); | |
_vector$4.addVectors( _box$2.max, _boxMorphTargets.max ); | |
_box$2.expandByPoint( _vector$4 ); | |
} else { | |
_box$2.expandByPoint( _boxMorphTargets.min ); | |
_box$2.expandByPoint( _boxMorphTargets.max ); | |
} | |
} | |
} | |
_box$2.getCenter( center ); | |
// second, try to find a boundingSphere with a radius smaller than the | |
// boundingSphere of the boundingBox: sqrt(3) smaller in the best case | |
var maxRadiusSq = 0; | |
for ( var i = 0, il = position.count; i < il; i ++ ) { | |
_vector$4.fromBufferAttribute( position, i ); | |
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) ); | |
} | |
// process morph attributes if present | |
if ( morphAttributesPosition ) { | |
for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { | |
var morphAttribute = morphAttributesPosition[ i ]; | |
var morphTargetsRelative = this.morphTargetsRelative; | |
for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) { | |
_vector$4.fromBufferAttribute( morphAttribute, j ); | |
if ( morphTargetsRelative ) { | |
_offset.fromBufferAttribute( position, j ); | |
_vector$4.add( _offset ); | |
} | |
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) ); | |
} | |
} | |
} | |
this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); | |
if ( isNaN( this.boundingSphere.radius ) ) { | |
console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); | |
} | |
} | |
}, | |
computeFaceNormals: function () { | |
// backwards compatibility | |
}, | |
computeVertexNormals: function () { | |
var index = this.index; | |
var attributes = this.attributes; | |
if ( attributes.position ) { | |
var positions = attributes.position.array; | |
if ( attributes.normal === undefined ) { | |
this.setAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); | |
} else { | |
// reset existing normals to zero | |
var array = attributes.normal.array; | |
for ( var i = 0, il = array.length; i < il; i ++ ) { | |
array[ i ] = 0; | |
} | |
} | |
var normals = attributes.normal.array; | |
var vA, vB, vC; | |
var pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); | |
var cb = new Vector3(), ab = new Vector3(); | |
// indexed elements | |
if ( index ) { | |
var indices = index.array; | |
for ( var i = 0, il = index.count; i < il; i += 3 ) { | |
vA = indices[ i + 0 ] * 3; | |
vB = indices[ i + 1 ] * 3; | |
vC = indices[ i + 2 ] * 3; | |
pA.fromArray( positions, vA ); | |
pB.fromArray( positions, vB ); | |
pC.fromArray( positions, vC ); | |
cb.subVectors( pC, pB ); | |
ab.subVectors( pA, pB ); | |
cb.cross( ab ); | |
normals[ vA ] += cb.x; | |
normals[ vA + 1 ] += cb.y; | |
normals[ vA + 2 ] += cb.z; | |
normals[ vB ] += cb.x; | |
normals[ vB + 1 ] += cb.y; | |
normals[ vB + 2 ] += cb.z; | |
normals[ vC ] += cb.x; | |
normals[ vC + 1 ] += cb.y; | |
normals[ vC + 2 ] += cb.z; | |
} | |
} else { | |
// non-indexed elements (unconnected triangle soup) | |
for ( var i = 0, il = positions.length; i < il; i += 9 ) { | |
pA.fromArray( positions, i ); | |
pB.fromArray( positions, i + 3 ); | |
pC.fromArray( positions, i + 6 ); | |
cb.subVectors( pC, pB ); | |
ab.subVectors( pA, pB ); | |
cb.cross( ab ); | |
normals[ i ] = cb.x; | |
normals[ i + 1 ] = cb.y; | |
normals[ i + 2 ] = cb.z; | |
normals[ i + 3 ] = cb.x; | |
normals[ i + 4 ] = cb.y; | |
normals[ i + 5 ] = cb.z; | |
normals[ i + 6 ] = cb.x; | |
normals[ i + 7 ] = cb.y; | |
normals[ i + 8 ] = cb.z; | |
} | |
} | |
this.normalizeNormals(); | |
attributes.normal.needsUpdate = true; | |
} | |
}, | |
merge: function ( geometry, offset ) { | |
if ( ! ( geometry && geometry.isBufferGeometry ) ) { | |
console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); | |
return; | |
} | |
if ( offset === undefined ) { | |
offset = 0; | |
console.warn( | |
'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' | |
+ 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.' | |
); | |
} | |
var attributes = this.attributes; | |
for ( var key in attributes ) { | |
if ( geometry.attributes[ key ] === undefined ) { continue; } | |
var attribute1 = attributes[ key ]; | |
var attributeArray1 = attribute1.array; | |
var attribute2 = geometry.attributes[ key ]; | |
var attributeArray2 = attribute2.array; | |
var attributeOffset = attribute2.itemSize * offset; | |
var length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset ); | |
for ( var i = 0, j = attributeOffset; i < length; i ++, j ++ ) { | |
attributeArray1[ j ] = attributeArray2[ i ]; | |
} | |
} | |
return this; | |
}, | |
normalizeNormals: function () { | |
var normals = this.attributes.normal; | |
for ( var i = 0, il = normals.count; i < il; i ++ ) { | |
_vector$4.x = normals.getX( i ); | |
_vector$4.y = normals.getY( i ); | |
_vector$4.z = normals.getZ( i ); | |
_vector$4.normalize(); | |
normals.setXYZ( i, _vector$4.x, _vector$4.y, _vector$4.z ); | |
} | |
}, | |
toNonIndexed: function () { | |
function convertBufferAttribute( attribute, indices ) { | |
var array = attribute.array; | |
var itemSize = attribute.itemSize; | |
var array2 = new array.constructor( indices.length * itemSize ); | |
var index = 0, index2 = 0; | |
for ( var i = 0, l = indices.length; i < l; i ++ ) { | |
index = indices[ i ] * itemSize; | |
for ( var j = 0; j < itemSize; j ++ ) { | |
array2[ index2 ++ ] = array[ index ++ ]; | |
} | |
} | |
return new BufferAttribute( array2, itemSize ); | |
} | |
// | |
if ( this.index === null ) { | |
console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' ); | |
return this; | |
} | |
var geometry2 = new BufferGeometry(); | |
var indices = this.index.array; | |
var attributes = this.attributes; | |
// attributes | |
for ( var name in attributes ) { | |
var attribute = attributes[ name ]; | |
var newAttribute = convertBufferAttribute( attribute, indices ); | |
geometry2.setAttribute( name, newAttribute ); | |
} | |
// morph attributes | |
var morphAttributes = this.morphAttributes; | |
for ( name in morphAttributes ) { | |
var morphArray = []; | |
var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes | |
for ( var i = 0, il = morphAttribute.length; i < il; i ++ ) { | |
var attribute = morphAttribute[ i ]; | |
var newAttribute = convertBufferAttribute( attribute, indices ); | |
morphArray.push( newAttribute ); | |
} | |
geometry2.morphAttributes[ name ] = morphArray; | |
} | |
geometry2.morphTargetsRelative = this.morphTargetsRelative; | |
// groups | |
var groups = this.groups; | |
for ( var i = 0, l = groups.length; i < l; i ++ ) { | |
var group = groups[ i ]; | |
geometry2.addGroup( group.start, group.count, group.materialIndex ); | |
} | |
return geometry2; | |
}, | |
toJSON: function () { | |
var data = { | |
metadata: { | |
version: 4.5, | |
type: 'BufferGeometry', | |
generator: 'BufferGeometry.toJSON' | |
} | |
}; | |
// standard BufferGeometry serialization | |
data.uuid = this.uuid; | |
data.type = this.type; | |
if ( this.name !== '' ) { data.name = this.name; } | |
if ( Object.keys( this.userData ).length > 0 ) { data.userData = this.userData; } | |
if ( this.parameters !== undefined ) { | |
var parameters = this.parameters; | |
for ( var key in parameters ) { | |
if ( parameters[ key ] !== undefined ) { data[ key ] = parameters[ key ]; } | |
} | |
return data; | |
} | |
data.data = { attributes: {} }; | |
var index = this.index; | |
if ( index !== null ) { | |
data.data.index = { | |
type: index.array.constructor.name, | |
array: Array.prototype.slice.call( index.array ) | |
}; | |
} | |
var attributes = this.attributes; | |
for ( var key in attributes ) { | |
var attribute = attributes[ key ]; | |
var attributeData = attribute.toJSON(); | |
if ( attribute.name !== '' ) { attributeData.name = attribute.name; } | |
data.data.attributes[ key ] = attributeData; | |
} | |
var morphAttributes = {}; | |
var hasMorphAttributes = false; | |
for ( var key in this.morphAttributes ) { | |
var attributeArray = this.morphAttributes[ key ]; | |
var array = []; | |
for ( var i = 0, il = attributeArray.length; i < il; i ++ ) { | |
var attribute = attributeArray[ i ]; | |
var attributeData = attribute.toJSON(); | |
if ( attribute.name !== '' ) { attributeData.name = attribute.name; } | |
array.push( attributeData ); | |
} | |
if ( array.length > 0 ) { | |
morphAttributes[ key ] = array; | |
hasMorphAttributes = true; | |
} | |
} | |
if ( hasMorphAttributes ) { | |
data.data.morphAttributes = morphAttributes; | |
data.data.morphTargetsRelative = this.morphTargetsRelative; | |
} | |
var groups = this.groups; | |
if ( groups.length > 0 ) { | |
data.data.groups = JSON.parse( JSON.stringify( groups ) ); | |
} | |
var boundingSphere = this.boundingSphere; | |
if ( boundingSphere !== null ) { | |
data.data.boundingSphere = { | |
center: boundingSphere.center.toArray(), | |
radius: boundingSphere.radius | |
}; | |
} | |
return data; | |
}, | |
clone: function () { | |
/* | |
// Handle primitives | |
var parameters = this.parameters; | |
if ( parameters !== undefined ) { | |
var values = []; | |
for ( var key in parameters ) { | |
values.push( parameters[ key ] ); | |
} | |
var geometry = Object.create( this.constructor.prototype ); | |
this.constructor.apply( geometry, values ); | |
return geometry; | |
} | |
return new this.constructor().copy( this ); | |
*/ | |
return new BufferGeometry().copy( this ); | |
}, | |
copy: function ( source ) { | |
var name, i, l; | |
// reset | |
this.index = null; | |
this.attributes = {}; | |
this.morphAttributes = {}; | |
this.groups = []; | |
this.boundingBox = null; | |
this.boundingSphere = null; | |
// name | |
this.name = source.name; | |
// index | |
var index = source.index; | |
if ( index !== null ) { | |
this.setIndex( index.clone() ); | |
} | |
// attributes | |
var attributes = source.attributes; | |
for ( name in attributes ) { | |
var attribute = attributes[ name ]; | |
this.setAttribute( name, attribute.clone() ); | |
} | |
// morph attributes | |
var morphAttributes = source.morphAttributes; | |
for ( name in morphAttributes ) { | |
var array = []; | |
var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes | |
for ( i = 0, l = morphAttribute.length; i < l; i ++ ) { | |
array.push( morphAttribute[ i ].clone() ); | |
} | |
this.morphAttributes[ name ] = array; | |
} | |
this.morphTargetsRelative = source.morphTargetsRelative; | |
// groups | |
var groups = source.groups; | |
for ( i = 0, l = groups.length; i < l; i ++ ) { | |
var group = groups[ i ]; | |
this.addGroup( group.start, group.count, group.materialIndex ); | |
} | |
// bounding box | |
var boundingBox = source.boundingBox; | |
if ( boundingBox !== null ) { | |
this.boundingBox = boundingBox.clone(); | |
} | |
// bounding sphere | |
var boundingSphere = source.boundingSphere; | |
if ( boundingSphere !== null ) { | |
this.boundingSphere = boundingSphere.clone(); | |
} | |
// draw range | |
this.drawRange.start = source.drawRange.start; | |
this.drawRange.count = source.drawRange.count; | |
// user data | |
this.userData = source.userData; | |
return this; | |
}, | |
dispose: function () { | |
this.dispatchEvent( { type: 'dispose' } ); | |
} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author alteredq / http://alteredqualia.com/ | |
* @author mikael emtinger / http://gomo.se/ | |
* @author jonobr1 / http://jonobr1.com/ | |
*/ | |
var _inverseMatrix = new Matrix4(); | |
var _ray = new Ray(); | |
var _sphere = new Sphere(); | |
var _vA = new Vector3(); | |
var _vB = new Vector3(); | |
var _vC = new Vector3(); | |
var _tempA = new Vector3(); | |
var _tempB = new Vector3(); | |
var _tempC = new Vector3(); | |
var _morphA = new Vector3(); | |
var _morphB = new Vector3(); | |
var _morphC = new Vector3(); | |
var _uvA = new Vector2(); | |
var _uvB = new Vector2(); | |
var _uvC = new Vector2(); | |
var _intersectionPoint = new Vector3(); | |
var _intersectionPointWorld = new Vector3(); | |
function Mesh( geometry, material ) { | |
Object3D.call( this ); | |
this.type = 'Mesh'; | |
this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); | |
this.material = material !== undefined ? material : new MeshBasicMaterial(); | |
this.updateMorphTargets(); | |
} | |
Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { | |
constructor: Mesh, | |
isMesh: true, | |
copy: function ( source ) { | |
Object3D.prototype.copy.call( this, source ); | |
if ( source.morphTargetInfluences !== undefined ) { | |
this.morphTargetInfluences = source.morphTargetInfluences.slice(); | |
} | |
if ( source.morphTargetDictionary !== undefined ) { | |
this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); | |
} | |
return this; | |
}, | |
updateMorphTargets: function () { | |
var geometry = this.geometry; | |
var m, ml, name; | |
if ( geometry.isBufferGeometry ) { | |
var morphAttributes = geometry.morphAttributes; | |
var keys = Object.keys( morphAttributes ); | |
if ( keys.length > 0 ) { | |
var morphAttribute = morphAttributes[ keys[ 0 ] ]; | |
if ( morphAttribute !== undefined ) { | |
this.morphTargetInfluences = []; | |
this.morphTargetDictionary = {}; | |
for ( m = 0, ml = morphAttribute.length; m < ml; m ++ ) { | |
name = morphAttribute[ m ].name || String( m ); | |
this.morphTargetInfluences.push( 0 ); | |
this.morphTargetDictionary[ name ] = m; | |
} | |
} | |
} | |
} else { | |
var morphTargets = geometry.morphTargets; | |
if ( morphTargets !== undefined && morphTargets.length > 0 ) { | |
console.error( 'THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' ); | |
} | |
} | |
}, | |
raycast: function ( raycaster, intersects ) { | |
var geometry = this.geometry; | |
var material = this.material; | |
var matrixWorld = this.matrixWorld; | |
if ( material === undefined ) { return; } | |
// Checking boundingSphere distance to ray | |
if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); } | |
_sphere.copy( geometry.boundingSphere ); | |
_sphere.applyMatrix4( matrixWorld ); | |
if ( raycaster.ray.intersectsSphere( _sphere ) === false ) { return; } | |
// | |
_inverseMatrix.getInverse( matrixWorld ); | |
_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix ); | |
// Check boundingBox before continuing | |
if ( geometry.boundingBox !== null ) { | |
if ( _ray.intersectsBox( geometry.boundingBox ) === false ) { return; } | |
} | |
var intersection; | |
if ( geometry.isBufferGeometry ) { | |
var a, b, c; | |
var index = geometry.index; | |
var position = geometry.attributes.position; | |
var morphPosition = geometry.morphAttributes.position; | |
var morphTargetsRelative = geometry.morphTargetsRelative; | |
var uv = geometry.attributes.uv; | |
var uv2 = geometry.attributes.uv2; | |
var groups = geometry.groups; | |
var drawRange = geometry.drawRange; | |
var i, j, il, jl; | |
var group, groupMaterial; | |
var start, end; | |
if ( index !== null ) { | |
// indexed buffer geometry | |
if ( Array.isArray( material ) ) { | |
for ( i = 0, il = groups.length; i < il; i ++ ) { | |
group = groups[ i ]; | |
groupMaterial = material[ group.materialIndex ]; | |
start = Math.max( group.start, drawRange.start ); | |
end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); | |
for ( j = start, jl = end; j < jl; j += 3 ) { | |
a = index.getX( j ); | |
b = index.getX( j + 1 ); | |
c = index.getX( j + 2 ); | |
intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); | |
if ( intersection ) { | |
intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics | |
intersection.face.materialIndex = group.materialIndex; | |
intersects.push( intersection ); | |
} | |
} | |
} | |
} else { | |
start = Math.max( 0, drawRange.start ); | |
end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); | |
for ( i = start, il = end; i < il; i += 3 ) { | |
a = index.getX( i ); | |
b = index.getX( i + 1 ); | |
c = index.getX( i + 2 ); | |
intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); | |
if ( intersection ) { | |
intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics | |
intersects.push( intersection ); | |
} | |
} | |
} | |
} else if ( position !== undefined ) { | |
// non-indexed buffer geometry | |
if ( Array.isArray( material ) ) { | |
for ( i = 0, il = groups.length; i < il; i ++ ) { | |
group = groups[ i ]; | |
groupMaterial = material[ group.materialIndex ]; | |
start = Math.max( group.start, drawRange.start ); | |
end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); | |
for ( j = start, jl = end; j < jl; j += 3 ) { | |
a = j; | |
b = j + 1; | |
c = j + 2; | |
intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); | |
if ( intersection ) { | |
intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics | |
intersection.face.materialIndex = group.materialIndex; | |
intersects.push( intersection ); | |
} | |
} | |
} | |
} else { | |
start = Math.max( 0, drawRange.start ); | |
end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); | |
for ( i = start, il = end; i < il; i += 3 ) { | |
a = i; | |
b = i + 1; | |
c = i + 2; | |
intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); | |
if ( intersection ) { | |
intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics | |
intersects.push( intersection ); | |
} | |
} | |
} | |
} | |
} else if ( geometry.isGeometry ) { | |
var fvA, fvB, fvC; | |
var isMultiMaterial = Array.isArray( material ); | |
var vertices = geometry.vertices; | |
var faces = geometry.faces; | |
var uvs; | |
var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; | |
if ( faceVertexUvs.length > 0 ) { uvs = faceVertexUvs; } | |
for ( var f = 0, fl = faces.length; f < fl; f ++ ) { | |
var face = faces[ f ]; | |
var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material; | |
if ( faceMaterial === undefined ) { continue; } | |
fvA = vertices[ face.a ]; | |
fvB = vertices[ face.b ]; | |
fvC = vertices[ face.c ]; | |
intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint ); | |
if ( intersection ) { | |
if ( uvs && uvs[ f ] ) { | |
var uvs_f = uvs[ f ]; | |
_uvA.copy( uvs_f[ 0 ] ); | |
_uvB.copy( uvs_f[ 1 ] ); | |
_uvC.copy( uvs_f[ 2 ] ); | |
intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() ); | |
} | |
intersection.face = face; | |
intersection.faceIndex = f; | |
intersects.push( intersection ); | |
} | |
} | |
} | |
}, | |
clone: function () { | |
return new this.constructor( this.geometry, this.material ).copy( this ); | |
} | |
} ); | |
function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { | |
var intersect; | |
if ( material.side === BackSide ) { | |
intersect = ray.intersectTriangle( pC, pB, pA, true, point ); | |
} else { | |
intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point ); | |
} | |
if ( intersect === null ) { return null; } | |
_intersectionPointWorld.copy( point ); | |
_intersectionPointWorld.applyMatrix4( object.matrixWorld ); | |
var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld ); | |
if ( distance < raycaster.near || distance > raycaster.far ) { return null; } | |
return { | |
distance: distance, | |
point: _intersectionPointWorld.clone(), | |
object: object | |
}; | |
} | |
function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) { | |
_vA.fromBufferAttribute( position, a ); | |
_vB.fromBufferAttribute( position, b ); | |
_vC.fromBufferAttribute( position, c ); | |
var morphInfluences = object.morphTargetInfluences; | |
if ( material.morphTargets && morphPosition && morphInfluences ) { | |
_morphA.set( 0, 0, 0 ); | |
_morphB.set( 0, 0, 0 ); | |
_morphC.set( 0, 0, 0 ); | |
for ( var i = 0, il = morphPosition.length; i < il; i ++ ) { | |
var influence = morphInfluences[ i ]; | |
var morphAttribute = morphPosition[ i ]; | |
if ( influence === 0 ) { continue; } | |
_tempA.fromBufferAttribute( morphAttribute, a ); | |
_tempB.fromBufferAttribute( morphAttribute, b ); | |
_tempC.fromBufferAttribute( morphAttribute, c ); | |
if ( morphTargetsRelative ) { | |
_morphA.addScaledVector( _tempA, influence ); | |
_morphB.addScaledVector( _tempB, influence ); | |
_morphC.addScaledVector( _tempC, influence ); | |
} else { | |
_morphA.addScaledVector( _tempA.sub( _vA ), influence ); | |
_morphB.addScaledVector( _tempB.sub( _vB ), influence ); | |
_morphC.addScaledVector( _tempC.sub( _vC ), influence ); | |
} | |
} | |
_vA.add( _morphA ); | |
_vB.add( _morphB ); | |
_vC.add( _morphC ); | |
} | |
var intersection = checkIntersection( object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint ); | |
if ( intersection ) { | |
if ( uv ) { | |
_uvA.fromBufferAttribute( uv, a ); | |
_uvB.fromBufferAttribute( uv, b ); | |
_uvC.fromBufferAttribute( uv, c ); | |
intersection.uv = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ); | |
} | |
if ( uv2 ) { | |
_uvA.fromBufferAttribute( uv2, a ); | |
_uvB.fromBufferAttribute( uv2, b ); | |
_uvC.fromBufferAttribute( uv2, c ); | |
intersection.uv2 = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ); | |
} | |
var face = new Face3( a, b, c ); | |
Triangle.getNormal( _vA, _vB, _vC, face.normal ); | |
intersection.face = face; | |
} | |
return intersection; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author kile / http://kile.stravaganza.org/ | |
* @author alteredq / http://alteredqualia.com/ | |
* @author mikael emtinger / http://gomo.se/ | |
* @author zz85 / http://www.lab4games.net/zz85/blog | |
* @author bhouston / http://clara.io | |
*/ | |
var _geometryId = 0; // Geometry uses even numbers as Id | |
var _m1$3 = new Matrix4(); | |
var _obj$1 = new Object3D(); | |
var _offset$1 = new Vector3(); | |
function Geometry() { | |
Object.defineProperty( this, 'id', { value: _geometryId += 2 } ); | |
this.uuid = MathUtils.generateUUID(); | |
this.name = ''; | |
this.type = 'Geometry'; | |
this.vertices = []; | |
this.colors = []; | |
this.faces = []; | |
this.faceVertexUvs = [[]]; | |
this.morphTargets = []; | |
this.morphNormals = []; | |
this.skinWeights = []; | |
this.skinIndices = []; | |
this.lineDistances = []; | |
this.boundingBox = null; | |
this.boundingSphere = null; | |
// update flags | |
this.elementsNeedUpdate = false; | |
this.verticesNeedUpdate = false; | |
this.uvsNeedUpdate = false; | |
this.normalsNeedUpdate = false; | |
this.colorsNeedUpdate = false; | |
this.lineDistancesNeedUpdate = false; | |
this.groupsNeedUpdate = false; | |
} | |
Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { | |
constructor: Geometry, | |
isGeometry: true, | |
applyMatrix4: function ( matrix ) { | |
var normalMatrix = new Matrix3().getNormalMatrix( matrix ); | |
for ( var i = 0, il = this.vertices.length; i < il; i ++ ) { | |
var vertex = this.vertices[ i ]; | |
vertex.applyMatrix4( matrix ); | |
} | |
for ( var i = 0, il = this.faces.length; i < il; i ++ ) { | |
var face = this.faces[ i ]; | |
face.normal.applyMatrix3( normalMatrix ).normalize(); | |
for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { | |
face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize(); | |
} | |
} | |
if ( this.boundingBox !== null ) { | |
this.computeBoundingBox(); | |
} | |
if ( this.boundingSphere !== null ) { | |
this.computeBoundingSphere(); | |
} | |
this.verticesNeedUpdate = true; | |
this.normalsNeedUpdate = true; | |
return this; | |
}, | |
rotateX: function ( angle ) { | |
// rotate geometry around world x-axis | |
_m1$3.makeRotationX( angle ); | |
this.applyMatrix4( _m1$3 ); | |
return this; | |
}, | |
rotateY: function ( angle ) { | |
// rotate geometry around world y-axis | |
_m1$3.makeRotationY( angle ); | |
this.applyMatrix4( _m1$3 ); | |
return this; | |
}, | |
rotateZ: function ( angle ) { | |
// rotate geometry around world z-axis | |
_m1$3.makeRotationZ( angle ); | |
this.applyMatrix4( _m1$3 ); | |
return this; | |
}, | |
translate: function ( x, y, z ) { | |
// translate geometry | |
_m1$3.makeTranslation( x, y, z ); | |
this.applyMatrix4( _m1$3 ); | |
return this; | |
}, | |
scale: function ( x, y, z ) { | |
// scale geometry | |
_m1$3.makeScale( x, y, z ); | |
this.applyMatrix4( _m1$3 ); | |
return this; | |
}, | |
lookAt: function ( vector ) { | |
_obj$1.lookAt( vector ); | |
_obj$1.updateMatrix(); | |
this.applyMatrix4( _obj$1.matrix ); | |
return this; | |
}, | |
fromBufferGeometry: function ( geometry ) { | |
var scope = this; | |
var indices = geometry.index !== null ? geometry.index.array : undefined; | |
var attributes = geometry.attributes; | |
if ( attributes.position === undefined ) { | |
console.error( 'THREE.Geometry.fromBufferGeometry(): Position attribute required for conversion.' ); | |
return this; | |
} | |
var positions = attributes.position.array; | |
var normals = attributes.normal !== undefined ? attributes.normal.array : undefined; | |
var colors = attributes.color !== undefined ? attributes.color.array : undefined; | |
var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined; | |
var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined; | |
if ( uvs2 !== undefined ) { this.faceVertexUvs[ 1 ] = []; } | |
for ( var i = 0; i < positions.length; i += 3 ) { | |
scope.vertices.push( new Vector3().fromArray( positions, i ) ); | |
if ( colors !== undefined ) { | |
scope.colors.push( new Color().fromArray( colors, i ) ); | |
} | |
} | |
function addFace( a, b, c, materialIndex ) { | |
var vertexColors = ( colors === undefined ) ? [] : [ | |
scope.colors[ a ].clone(), | |
scope.colors[ b ].clone(), | |
scope.colors[ c ].clone() ]; | |
var vertexNormals = ( normals === undefined ) ? [] : [ | |
new Vector3().fromArray( normals, a * 3 ), | |
new Vector3().fromArray( normals, b * 3 ), | |
new Vector3().fromArray( normals, c * 3 ) | |
]; | |
var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex ); | |
scope.faces.push( face ); | |
if ( uvs !== undefined ) { | |
scope.faceVertexUvs[ 0 ].push( [ | |
new Vector2().fromArray( uvs, a * 2 ), | |
new Vector2().fromArray( uvs, b * 2 ), | |
new Vector2().fromArray( uvs, c * 2 ) | |
] ); | |
} | |
if ( uvs2 !== undefined ) { | |
scope.faceVertexUvs[ 1 ].push( [ | |
new Vector2().fromArray( uvs2, a * 2 ), | |
new Vector2().fromArray( uvs2, b * 2 ), | |
new Vector2().fromArray( uvs2, c * 2 ) | |
] ); | |
} | |
} | |
var groups = geometry.groups; | |
if ( groups.length > 0 ) { | |
for ( var i = 0; i < groups.length; i ++ ) { | |
var group = groups[ i ]; | |
var start = group.start; | |
var count = group.count; | |
for ( var j = start, jl = start + count; j < jl; j += 3 ) { | |
if ( indices !== undefined ) { | |
addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex ); | |
} else { | |
addFace( j, j + 1, j + 2, group.materialIndex ); | |
} | |
} | |
} | |
} else { | |
if ( indices !== undefined ) { | |
for ( var i = 0; i < indices.length; i += 3 ) { | |
addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); | |
} | |
} else { | |
for ( var i = 0; i < positions.length / 3; i += 3 ) { | |
addFace( i, i + 1, i + 2 ); | |
} | |
} | |
} | |
this.computeFaceNormals(); | |
if ( geometry.boundingBox !== null ) { | |
this.boundingBox = geometry.boundingBox.clone(); | |
} | |
if ( geometry.boundingSphere !== null ) { | |
this.boundingSphere = geometry.boundingSphere.clone(); | |
} | |
return this; | |
}, | |
center: function () { | |
this.computeBoundingBox(); | |
this.boundingBox.getCenter( _offset$1 ).negate(); | |
this.translate( _offset$1.x, _offset$1.y, _offset$1.z ); | |
return this; | |
}, | |
normalize: function () { | |
this.computeBoundingSphere(); | |
var center = this.boundingSphere.center; | |
var radius = this.boundingSphere.radius; | |
var s = radius === 0 ? 1 : 1.0 / radius; | |
var matrix = new Matrix4(); | |
matrix.set( | |
s, 0, 0, - s * center.x, | |
0, s, 0, - s * center.y, | |
0, 0, s, - s * center.z, | |
0, 0, 0, 1 | |
); | |
this.applyMatrix4( matrix ); | |
return this; | |
}, | |
computeFaceNormals: function () { | |
var cb = new Vector3(), ab = new Vector3(); | |
for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) { | |
var face = this.faces[ f ]; | |
var vA = this.vertices[ face.a ]; | |
var vB = this.vertices[ face.b ]; | |
var vC = this.vertices[ face.c ]; | |
cb.subVectors( vC, vB ); | |
ab.subVectors( vA, vB ); | |
cb.cross( ab ); | |
cb.normalize(); | |
face.normal.copy( cb ); | |
} | |
}, | |
computeVertexNormals: function ( areaWeighted ) { | |
if ( areaWeighted === undefined ) { areaWeighted = true; } | |
var v, vl, f, fl, face, vertices; | |
vertices = new Array( this.vertices.length ); | |
for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { | |
vertices[ v ] = new Vector3(); | |
} | |
if ( areaWeighted ) { | |
// vertex normals weighted by triangle areas | |
// http://www.iquilezles.org/www/articles/normals/normals.htm | |
var vA, vB, vC; | |
var cb = new Vector3(), ab = new Vector3(); | |
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { | |
face = this.faces[ f ]; | |
vA = this.vertices[ face.a ]; | |
vB = this.vertices[ face.b ]; | |
vC = this.vertices[ face.c ]; | |
cb.subVectors( vC, vB ); | |
ab.subVectors( vA, vB ); | |
cb.cross( ab ); | |
vertices[ face.a ].add( cb ); | |
vertices[ face.b ].add( cb ); | |
vertices[ face.c ].add( cb ); | |
} | |
} else { | |
this.computeFaceNormals(); | |
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { | |
face = this.faces[ f ]; | |
vertices[ face.a ].add( face.normal ); | |
vertices[ face.b ].add( face.normal ); | |
vertices[ face.c ].add( face.normal ); | |
} | |
} | |
for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { | |
vertices[ v ].normalize(); | |
} | |
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { | |
face = this.faces[ f ]; | |
var vertexNormals = face.vertexNormals; | |
if ( vertexNormals.length === 3 ) { | |
vertexNormals[ 0 ].copy( vertices[ face.a ] ); | |
vertexNormals[ 1 ].copy( vertices[ face.b ] ); | |
vertexNormals[ 2 ].copy( vertices[ face.c ] ); | |
} else { | |
vertexNormals[ 0 ] = vertices[ face.a ].clone(); | |
vertexNormals[ 1 ] = vertices[ face.b ].clone(); | |
vertexNormals[ 2 ] = vertices[ face.c ].clone(); | |
} | |
} | |
if ( this.faces.length > 0 ) { | |
this.normalsNeedUpdate = true; | |
} | |
}, | |
computeFlatVertexNormals: function () { | |
var f, fl, face; | |
this.computeFaceNormals(); | |
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { | |
face = this.faces[ f ]; | |
var vertexNormals = face.vertexNormals; | |
if ( vertexNormals.length === 3 ) { | |
vertexNormals[ 0 ].copy( face.normal ); | |
vertexNormals[ 1 ].copy( face.normal ); | |
vertexNormals[ 2 ].copy( face.normal ); | |
} else { | |
vertexNormals[ 0 ] = face.normal.clone(); | |
vertexNormals[ 1 ] = face.normal.clone(); | |
vertexNormals[ 2 ] = face.normal.clone(); | |
} | |
} | |
if ( this.faces.length > 0 ) { | |
this.normalsNeedUpdate = true; | |
} | |
}, | |
computeMorphNormals: function () { | |
var i, il, f, fl, face; | |
// save original normals | |
// - create temp variables on first access | |
// otherwise just copy (for faster repeated calls) | |
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { | |
face = this.faces[ f ]; | |
if ( ! face.__originalFaceNormal ) { | |
face.__originalFaceNormal = face.normal.clone(); | |
} else { | |
face.__originalFaceNormal.copy( face.normal ); | |
} | |
if ( ! face.__originalVertexNormals ) { face.__originalVertexNormals = []; } | |
for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) { | |
if ( ! face.__originalVertexNormals[ i ] ) { | |
face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone(); | |
} else { | |
face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] ); | |
} | |
} | |
} | |
// use temp geometry to compute face and vertex normals for each morph | |
var tmpGeo = new Geometry(); | |
tmpGeo.faces = this.faces; | |
for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) { | |
// create on first access | |
if ( ! this.morphNormals[ i ] ) { | |
this.morphNormals[ i ] = {}; | |
this.morphNormals[ i ].faceNormals = []; | |
this.morphNormals[ i ].vertexNormals = []; | |
var dstNormalsFace = this.morphNormals[ i ].faceNormals; | |
var dstNormalsVertex = this.morphNormals[ i ].vertexNormals; | |
var faceNormal, vertexNormals; | |
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { | |
faceNormal = new Vector3(); | |
vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() }; | |
dstNormalsFace.push( faceNormal ); | |
dstNormalsVertex.push( vertexNormals ); | |
} | |
} | |
var morphNormals = this.morphNormals[ i ]; | |
// set vertices to morph target | |
tmpGeo.vertices = this.morphTargets[ i ].vertices; | |
// compute morph normals | |
tmpGeo.computeFaceNormals(); | |
tmpGeo.computeVertexNormals(); | |
// store morph normals | |
var faceNormal, vertexNormals; | |
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { | |
face = this.faces[ f ]; | |
faceNormal = morphNormals.faceNormals[ f ]; | |
vertexNormals = morphNormals.vertexNormals[ f ]; | |
faceNormal.copy( face.normal ); | |
vertexNormals.a.copy( face.vertexNormals[ 0 ] ); | |
vertexNormals.b.copy( face.vertexNormals[ 1 ] ); | |
vertexNormals.c.copy( face.vertexNormals[ 2 ] ); | |
} | |
} | |
// restore original normals | |
for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { | |
face = this.faces[ f ]; | |
face.normal = face.__originalFaceNormal; | |
face.vertexNormals = face.__originalVertexNormals; | |
} | |
}, | |
computeBoundingBox: function () { | |
if ( this.boundingBox === null ) { | |
this.boundingBox = new Box3(); | |
} | |
this.boundingBox.setFromPoints( this.vertices ); | |
}, | |
computeBoundingSphere: function () { | |
if ( this.boundingSphere === null ) { | |
this.boundingSphere = new Sphere(); | |
} | |
this.boundingSphere.setFromPoints( this.vertices ); | |
}, | |
merge: function ( geometry, matrix, materialIndexOffset ) { | |
if ( ! ( geometry && geometry.isGeometry ) ) { | |
console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); | |
return; | |
} | |
var normalMatrix, | |
vertexOffset = this.vertices.length, | |
vertices1 = this.vertices, | |
vertices2 = geometry.vertices, | |
faces1 = this.faces, | |
faces2 = geometry.faces, | |
colors1 = this.colors, | |
colors2 = geometry.colors; | |
if ( materialIndexOffset === undefined ) { materialIndexOffset = 0; } | |
if ( matrix !== undefined ) { | |
normalMatrix = new Matrix3().getNormalMatrix( matrix ); | |
} | |
// vertices | |
for ( var i = 0, il = vertices2.length; i < il; i ++ ) { | |
var vertex = vertices2[ i ]; | |
var vertexCopy = vertex.clone(); | |
if ( matrix !== undefined ) { vertexCopy.applyMatrix4( matrix ); } | |
vertices1.push( vertexCopy ); | |
} | |
// colors | |
for ( var i = 0, il = colors2.length; i < il; i ++ ) { | |
colors1.push( colors2[ i ].clone() ); | |
} | |
// faces | |
for ( i = 0, il = faces2.length; i < il; i ++ ) { | |
var face = faces2[ i ], faceCopy, normal, color, | |
faceVertexNormals = face.vertexNormals, | |
faceVertexColors = face.vertexColors; | |
faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset ); | |
faceCopy.normal.copy( face.normal ); | |
if ( normalMatrix !== undefined ) { | |
faceCopy.normal.applyMatrix3( normalMatrix ).normalize(); | |
} | |
for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) { | |
normal = faceVertexNormals[ j ].clone(); | |
if ( normalMatrix !== undefined ) { | |
normal.applyMatrix3( normalMatrix ).normalize(); | |
} | |
faceCopy.vertexNormals.push( normal ); | |
} | |
faceCopy.color.copy( face.color ); | |
for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) { | |
color = faceVertexColors[ j ]; | |
faceCopy.vertexColors.push( color.clone() ); | |
} | |
faceCopy.materialIndex = face.materialIndex + materialIndexOffset; | |
faces1.push( faceCopy ); | |
} | |
// uvs | |
for ( var i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) { | |
var faceVertexUvs2 = geometry.faceVertexUvs[ i ]; | |
if ( this.faceVertexUvs[ i ] === undefined ) { this.faceVertexUvs[ i ] = []; } | |
for ( var j = 0, jl = faceVertexUvs2.length; j < jl; j ++ ) { | |
var uvs2 = faceVertexUvs2[ j ], uvsCopy = []; | |
for ( var k = 0, kl = uvs2.length; k < kl; k ++ ) { | |
uvsCopy.push( uvs2[ k ].clone() ); | |
} | |
this.faceVertexUvs[ i ].push( uvsCopy ); | |
} | |
} | |
}, | |
mergeMesh: function ( mesh ) { | |
if ( ! ( mesh && mesh.isMesh ) ) { | |
console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); | |
return; | |
} | |
if ( mesh.matrixAutoUpdate ) { mesh.updateMatrix(); } | |
this.merge( mesh.geometry, mesh.matrix ); | |
}, | |
/* | |
* Checks for duplicate vertices with hashmap. | |
* Duplicated vertices are removed | |
* and faces' vertices are updated. | |
*/ | |
mergeVertices: function () { | |
var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique) | |
var unique = [], changes = []; | |
var v, key; | |
var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001 | |
var precision = Math.pow( 10, precisionPoints ); | |
var i, il, face; | |
var indices, j, jl; | |
for ( i = 0, il = this.vertices.length; i < il; i ++ ) { | |
v = this.vertices[ i ]; | |
key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision ); | |
if ( verticesMap[ key ] === undefined ) { | |
verticesMap[ key ] = i; | |
unique.push( this.vertices[ i ] ); | |
changes[ i ] = unique.length - 1; | |
} else { | |
//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]); | |
changes[ i ] = changes[ verticesMap[ key ] ]; | |
} | |
} | |
// if faces are completely degenerate after merging vertices, we | |
// have to remove them from the geometry. | |
var faceIndicesToRemove = []; | |
for ( i = 0, il = this.faces.length; i < il; i ++ ) { | |
face = this.faces[ i ]; | |
face.a = changes[ face.a ]; | |
face.b = changes[ face.b ]; | |
face.c = changes[ face.c ]; | |
indices = [ face.a, face.b, face.c ]; | |
// if any duplicate vertices are found in a Face3 | |
// we have to remove the face as nothing can be saved | |
for ( var n = 0; n < 3; n ++ ) { | |
if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) { | |
faceIndicesToRemove.push( i ); | |
break; | |
} | |
} | |
} | |
for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) { | |
var idx = faceIndicesToRemove[ i ]; | |
this.faces.splice( idx, 1 ); | |
for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) { | |
this.faceVertexUvs[ j ].splice( idx, 1 ); | |
} | |
} | |
// Use unique set of vertices | |
var diff = this.vertices.length - unique.length; | |
this.vertices = unique; | |
return diff; | |
}, | |
setFromPoints: function ( points ) { | |
this.vertices = []; | |
for ( var i = 0, l = points.length; i < l; i ++ ) { | |
var point = points[ i ]; | |
this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); | |
} | |
return this; | |
}, | |
sortFacesByMaterialIndex: function () { | |
var faces = this.faces; | |
var length = faces.length; | |
// tag faces | |
for ( var i = 0; i < length; i ++ ) { | |
faces[ i ]._id = i; | |
} | |
// sort faces | |
function materialIndexSort( a, b ) { | |
return a.materialIndex - b.materialIndex; | |
} | |
faces.sort( materialIndexSort ); | |
// sort uvs | |
var uvs1 = this.faceVertexUvs[ 0 ]; | |
var uvs2 = this.faceVertexUvs[ 1 ]; | |
var newUvs1, newUvs2; | |
if ( uvs1 && uvs1.length === length ) { newUvs1 = []; } | |
if ( uvs2 && uvs2.length === length ) { newUvs2 = []; } | |
for ( var i = 0; i < length; i ++ ) { | |
var id = faces[ i ]._id; | |
if ( newUvs1 ) { newUvs1.push( uvs1[ id ] ); } | |
if ( newUvs2 ) { newUvs2.push( uvs2[ id ] ); } | |
} | |
if ( newUvs1 ) { this.faceVertexUvs[ 0 ] = newUvs1; } | |
if ( newUvs2 ) { this.faceVertexUvs[ 1 ] = newUvs2; } | |
}, | |
toJSON: function () { | |
var data = { | |
metadata: { | |
version: 4.5, | |
type: 'Geometry', | |
generator: 'Geometry.toJSON' | |
} | |
}; | |
// standard Geometry serialization | |
data.uuid = this.uuid; | |
data.type = this.type; | |
if ( this.name !== '' ) { data.name = this.name; } | |
if ( this.parameters !== undefined ) { | |
var parameters = this.parameters; | |
for ( var key in parameters ) { | |
if ( parameters[ key ] !== undefined ) { data[ key ] = parameters[ key ]; } | |
} | |
return data; | |
} | |
var vertices = []; | |
for ( var i = 0; i < this.vertices.length; i ++ ) { | |
var vertex = this.vertices[ i ]; | |
vertices.push( vertex.x, vertex.y, vertex.z ); | |
} | |
var faces = []; | |
var normals = []; | |
var normalsHash = {}; | |
var colors = []; | |
var colorsHash = {}; | |
var uvs = []; | |
var uvsHash = {}; | |
for ( var i = 0; i < this.faces.length; i ++ ) { | |
var face = this.faces[ i ]; | |
var hasMaterial = true; | |
var hasFaceUv = false; // deprecated | |
var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined; | |
var hasFaceNormal = face.normal.length() > 0; | |
var hasFaceVertexNormal = face.vertexNormals.length > 0; | |
var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1; | |
var hasFaceVertexColor = face.vertexColors.length > 0; | |
var faceType = 0; | |
faceType = setBit( faceType, 0, 0 ); // isQuad | |
faceType = setBit( faceType, 1, hasMaterial ); | |
faceType = setBit( faceType, 2, hasFaceUv ); | |
faceType = setBit( faceType, 3, hasFaceVertexUv ); | |
faceType = setBit( faceType, 4, hasFaceNormal ); | |
faceType = setBit( faceType, 5, hasFaceVertexNormal ); | |
faceType = setBit( faceType, 6, hasFaceColor ); | |
faceType = setBit( faceType, 7, hasFaceVertexColor ); | |
faces.push( faceType ); | |
faces.push( face.a, face.b, face.c ); | |
faces.push( face.materialIndex ); | |
if ( hasFaceVertexUv ) { | |
var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ]; | |
faces.push( | |
getUvIndex( faceVertexUvs[ 0 ] ), | |
getUvIndex( faceVertexUvs[ 1 ] ), | |
getUvIndex( faceVertexUvs[ 2 ] ) | |
); | |
} | |
if ( hasFaceNormal ) { | |
faces.push( getNormalIndex( face.normal ) ); | |
} | |
if ( hasFaceVertexNormal ) { | |
var vertexNormals = face.vertexNormals; | |
faces.push( | |
getNormalIndex( vertexNormals[ 0 ] ), | |
getNormalIndex( vertexNormals[ 1 ] ), | |
getNormalIndex( vertexNormals[ 2 ] ) | |
); | |
} | |
if ( hasFaceColor ) { | |
faces.push( getColorIndex( face.color ) ); | |
} | |
if ( hasFaceVertexColor ) { | |
var vertexColors = face.vertexColors; | |
faces.push( | |
getColorIndex( vertexColors[ 0 ] ), | |
getColorIndex( vertexColors[ 1 ] ), | |
getColorIndex( vertexColors[ 2 ] ) | |
); | |
} | |
} | |
function setBit( value, position, enabled ) { | |
return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) ); | |
} | |
function getNormalIndex( normal ) { | |
var hash = normal.x.toString() + normal.y.toString() + normal.z.toString(); | |
if ( normalsHash[ hash ] !== undefined ) { | |
return normalsHash[ hash ]; | |
} | |
normalsHash[ hash ] = normals.length / 3; | |
normals.push( normal.x, normal.y, normal.z ); | |
return normalsHash[ hash ]; | |
} | |
function getColorIndex( color ) { | |
var hash = color.r.toString() + color.g.toString() + color.b.toString(); | |
if ( colorsHash[ hash ] !== undefined ) { | |
return colorsHash[ hash ]; | |
} | |
colorsHash[ hash ] = colors.length; | |
colors.push( color.getHex() ); | |
return colorsHash[ hash ]; | |
} | |
function getUvIndex( uv ) { | |
var hash = uv.x.toString() + uv.y.toString(); | |
if ( uvsHash[ hash ] !== undefined ) { | |
return uvsHash[ hash ]; | |
} | |
uvsHash[ hash ] = uvs.length / 2; | |
uvs.push( uv.x, uv.y ); | |
return uvsHash[ hash ]; | |
} | |
data.data = {}; | |
data.data.vertices = vertices; | |
data.data.normals = normals; | |
if ( colors.length > 0 ) { data.data.colors = colors; } | |
if ( uvs.length > 0 ) { data.data.uvs = [ uvs ]; } // temporal backward compatibility | |
data.data.faces = faces; | |
return data; | |
}, | |
clone: function () { | |
/* | |
// Handle primitives | |
var parameters = this.parameters; | |
if ( parameters !== undefined ) { | |
var values = []; | |
for ( var key in parameters ) { | |
values.push( parameters[ key ] ); | |
} | |
var geometry = Object.create( this.constructor.prototype ); | |
this.constructor.apply( geometry, values ); | |
return geometry; | |
} | |
return new this.constructor().copy( this ); | |
*/ | |
return new Geometry().copy( this ); | |
}, | |
copy: function ( source ) { | |
var i, il, j, jl, k, kl; | |
// reset | |
this.vertices = []; | |
this.colors = []; | |
this.faces = []; | |
this.faceVertexUvs = [[]]; | |
this.morphTargets = []; | |
this.morphNormals = []; | |
this.skinWeights = []; | |
this.skinIndices = []; | |
this.lineDistances = []; | |
this.boundingBox = null; | |
this.boundingSphere = null; | |
// name | |
this.name = source.name; | |
// vertices | |
var vertices = source.vertices; | |
for ( i = 0, il = vertices.length; i < il; i ++ ) { | |
this.vertices.push( vertices[ i ].clone() ); | |
} | |
// colors | |
var colors = source.colors; | |
for ( i = 0, il = colors.length; i < il; i ++ ) { | |
this.colors.push( colors[ i ].clone() ); | |
} | |
// faces | |
var faces = source.faces; | |
for ( i = 0, il = faces.length; i < il; i ++ ) { | |
this.faces.push( faces[ i ].clone() ); | |
} | |
// face vertex uvs | |
for ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) { | |
var faceVertexUvs = source.faceVertexUvs[ i ]; | |
if ( this.faceVertexUvs[ i ] === undefined ) { | |
this.faceVertexUvs[ i ] = []; | |
} | |
for ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) { | |
var uvs = faceVertexUvs[ j ], uvsCopy = []; | |
for ( k = 0, kl = uvs.length; k < kl; k ++ ) { | |
var uv = uvs[ k ]; | |
uvsCopy.push( uv.clone() ); | |
} | |
this.faceVertexUvs[ i ].push( uvsCopy ); | |
} | |
} | |
// morph targets | |
var morphTargets = source.morphTargets; | |
for ( i = 0, il = morphTargets.length; i < il; i ++ ) { | |
var morphTarget = {}; | |
morphTarget.name = morphTargets[ i ].name; | |
// vertices | |
if ( morphTargets[ i ].vertices !== undefined ) { | |
morphTarget.vertices = []; | |
for ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) { | |
morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() ); | |
} | |
} | |
// normals | |
if ( morphTargets[ i ].normals !== undefined ) { | |
morphTarget.normals = []; | |
for ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) { | |
morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() ); | |
} | |
} | |
this.morphTargets.push( morphTarget ); | |
} | |
// morph normals | |
var morphNormals = source.morphNormals; | |
for ( i = 0, il = morphNormals.length; i < il; i ++ ) { | |
var morphNormal = {}; | |
// vertex normals | |
if ( morphNormals[ i ].vertexNormals !== undefined ) { | |
morphNormal.vertexNormals = []; | |
for ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) { | |
var srcVertexNormal = morphNormals[ i ].vertexNormals[ j ]; | |
var destVertexNormal = {}; | |
destVertexNormal.a = srcVertexNormal.a.clone(); | |
destVertexNormal.b = srcVertexNormal.b.clone(); | |
destVertexNormal.c = srcVertexNormal.c.clone(); | |
morphNormal.vertexNormals.push( destVertexNormal ); | |
} | |
} | |
// face normals | |
if ( morphNormals[ i ].faceNormals !== undefined ) { | |
morphNormal.faceNormals = []; | |
for ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) { | |
morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() ); | |
} | |
} | |
this.morphNormals.push( morphNormal ); | |
} | |
// skin weights | |
var skinWeights = source.skinWeights; | |
for ( i = 0, il = skinWeights.length; i < il; i ++ ) { | |
this.skinWeights.push( skinWeights[ i ].clone() ); | |
} | |
// skin indices | |
var skinIndices = source.skinIndices; | |
for ( i = 0, il = skinIndices.length; i < il; i ++ ) { | |
this.skinIndices.push( skinIndices[ i ].clone() ); | |
} | |
// line distances | |
var lineDistances = source.lineDistances; | |
for ( i = 0, il = lineDistances.length; i < il; i ++ ) { | |
this.lineDistances.push( lineDistances[ i ] ); | |
} | |
// bounding box | |
var boundingBox = source.boundingBox; | |
if ( boundingBox !== null ) { | |
this.boundingBox = boundingBox.clone(); | |
} | |
// bounding sphere | |
var boundingSphere = source.boundingSphere; | |
if ( boundingSphere !== null ) { | |
this.boundingSphere = boundingSphere.clone(); | |
} | |
// update flags | |
this.elementsNeedUpdate = source.elementsNeedUpdate; | |
this.verticesNeedUpdate = source.verticesNeedUpdate; | |
this.uvsNeedUpdate = source.uvsNeedUpdate; | |
this.normalsNeedUpdate = source.normalsNeedUpdate; | |
this.colorsNeedUpdate = source.colorsNeedUpdate; | |
this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate; | |
this.groupsNeedUpdate = source.groupsNeedUpdate; | |
return this; | |
}, | |
dispose: function () { | |
this.dispatchEvent( { type: 'dispose' } ); | |
} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author Mugen87 / https://github.com/Mugen87 | |
*/ | |
// BoxGeometry | |
var BoxGeometry = /*@__PURE__*/(function (Geometry) { | |
function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { | |
Geometry.call(this); | |
this.type = 'BoxGeometry'; | |
this.parameters = { | |
width: width, | |
height: height, | |
depth: depth, | |
widthSegments: widthSegments, | |
heightSegments: heightSegments, | |
depthSegments: depthSegments | |
}; | |
this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) ); | |
this.mergeVertices(); | |
} | |
if ( Geometry ) BoxGeometry.__proto__ = Geometry; | |
BoxGeometry.prototype = Object.create( Geometry && Geometry.prototype ); | |
BoxGeometry.prototype.constructor = BoxGeometry; | |
return BoxGeometry; | |
}(Geometry)); | |
// BoxBufferGeometry | |
var BoxBufferGeometry = /*@__PURE__*/(function (BufferGeometry) { | |
function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { | |
BufferGeometry.call(this); | |
this.type = 'BoxBufferGeometry'; | |
this.parameters = { | |
width: width, | |
height: height, | |
depth: depth, | |
widthSegments: widthSegments, | |
heightSegments: heightSegments, | |
depthSegments: depthSegments | |
}; | |
var scope = this; | |
width = width || 1; | |
height = height || 1; | |
depth = depth || 1; | |
// segments | |
widthSegments = Math.floor( widthSegments ) || 1; | |
heightSegments = Math.floor( heightSegments ) || 1; | |
depthSegments = Math.floor( depthSegments ) || 1; | |
// buffers | |
var indices = []; | |
var vertices = []; | |
var normals = []; | |
var uvs = []; | |
// helper variables | |
var numberOfVertices = 0; | |
var groupStart = 0; | |
// build each side of the box geometry | |
buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px | |
buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx | |
buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py | |
buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny | |
buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz | |
buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz | |
// build geometry | |
this.setIndex( indices ); | |
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); | |
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); | |
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); | |
function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { | |
var segmentWidth = width / gridX; | |
var segmentHeight = height / gridY; | |
var widthHalf = width / 2; | |
var heightHalf = height / 2; | |
var depthHalf = depth / 2; | |
var gridX1 = gridX + 1; | |
var gridY1 = gridY + 1; | |
var vertexCounter = 0; | |
var groupCount = 0; | |
var ix, iy; | |
var vector = new Vector3(); | |
// generate vertices, normals and uvs | |
for ( iy = 0; iy < gridY1; iy ++ ) { | |
var y = iy * segmentHeight - heightHalf; | |
for ( ix = 0; ix < gridX1; ix ++ ) { | |
var x = ix * segmentWidth - widthHalf; | |
// set values to correct vector component | |
vector[ u ] = x * udir; | |
vector[ v ] = y * vdir; | |
vector[ w ] = depthHalf; | |
// now apply vector to vertex buffer | |
vertices.push( vector.x, vector.y, vector.z ); | |
// set values to correct vector component | |
vector[ u ] = 0; | |
vector[ v ] = 0; | |
vector[ w ] = depth > 0 ? 1 : - 1; | |
// now apply vector to normal buffer | |
normals.push( vector.x, vector.y, vector.z ); | |
// uvs | |
uvs.push( ix / gridX ); | |
uvs.push( 1 - ( iy / gridY ) ); | |
// counters | |
vertexCounter += 1; | |
} | |
} | |
// indices | |
// 1. you need three indices to draw a single face | |
// 2. a single segment consists of two faces | |
// 3. so we need to generate six (2*3) indices per segment | |
for ( iy = 0; iy < gridY; iy ++ ) { | |
for ( ix = 0; ix < gridX; ix ++ ) { | |
var a = numberOfVertices + ix + gridX1 * iy; | |
var b = numberOfVertices + ix + gridX1 * ( iy + 1 ); | |
var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); | |
var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; | |
// faces | |
indices.push( a, b, d ); | |
indices.push( b, c, d ); | |
// increase counter | |
groupCount += 6; | |
} | |
} | |
// add a group to the geometry. this will ensure multi material support | |
scope.addGroup( groupStart, groupCount, materialIndex ); | |
// calculate new start value for groups | |
groupStart += groupCount; | |
// update total number of vertices | |
numberOfVertices += vertexCounter; | |
} | |
} | |
if ( BufferGeometry ) BoxBufferGeometry.__proto__ = BufferGeometry; | |
BoxBufferGeometry.prototype = Object.create( BufferGeometry && BufferGeometry.prototype ); | |
BoxBufferGeometry.prototype.constructor = BoxBufferGeometry; | |
return BoxBufferGeometry; | |
}(BufferGeometry)); | |
/** | |
* Uniform Utilities | |
*/ | |
function cloneUniforms( src ) { | |
var dst = {}; | |
for ( var u in src ) { | |
dst[ u ] = {}; | |
for ( var p in src[ u ] ) { | |
var property = src[ u ][ p ]; | |
if ( property && ( property.isColor || | |
property.isMatrix3 || property.isMatrix4 || | |
property.isVector2 || property.isVector3 || property.isVector4 || | |
property.isTexture ) ) { | |
dst[ u ][ p ] = property.clone(); | |
} else if ( Array.isArray( property ) ) { | |
dst[ u ][ p ] = property.slice(); | |
} else { | |
dst[ u ][ p ] = property; | |
} | |
} | |
} | |
return dst; | |
} | |
function mergeUniforms( uniforms ) { | |
var merged = {}; | |
for ( var u = 0; u < uniforms.length; u ++ ) { | |
var tmp = cloneUniforms( uniforms[ u ] ); | |
for ( var p in tmp ) { | |
merged[ p ] = tmp[ p ]; | |
} | |
} | |
return merged; | |
} | |
// Legacy | |
var UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; | |
var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; | |
var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; | |
/** | |
* @author alteredq / http://alteredqualia.com/ | |
* | |
* parameters = { | |
* defines: { "label" : "value" }, | |
* uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } }, | |
* | |
* fragmentShader: <string>, | |
* vertexShader: <string>, | |
* | |
* wireframe: <boolean>, | |
* wireframeLinewidth: <float>, | |
* | |
* lights: <bool>, | |
* | |
* skinning: <bool>, | |
* morphTargets: <bool>, | |
* morphNormals: <bool> | |
* } | |
*/ | |
function ShaderMaterial( parameters ) { | |
Material.call( this ); | |
this.type = 'ShaderMaterial'; | |
this.defines = {}; | |
this.uniforms = {}; | |
this.vertexShader = default_vertex; | |
this.fragmentShader = default_fragment; | |
this.linewidth = 1; | |
this.wireframe = false; | |
this.wireframeLinewidth = 1; | |
this.fog = false; // set to use scene fog | |
this.lights = false; // set to use scene lights | |
this.clipping = false; // set to use user-defined clipping planes | |
this.skinning = false; // set to use skinning attribute streams | |
this.morphTargets = false; // set to use morph targets | |
this.morphNormals = false; // set to use morph normals | |
this.extensions = { | |
derivatives: false, // set to use derivatives | |
fragDepth: false, // set to use fragment depth values | |
drawBuffers: false, // set to use draw buffers | |
shaderTextureLOD: false // set to use shader texture LOD | |
}; | |
// When rendered geometry doesn't include these attributes but the material does, | |
// use these default values in WebGL. This avoids errors when buffer data is missing. | |
this.defaultAttributeValues = { | |
'color': [ 1, 1, 1 ], | |
'uv': [ 0, 0 ], | |
'uv2': [ 0, 0 ] | |
}; | |
this.index0AttributeName = undefined; | |
this.uniformsNeedUpdate = false; | |
if ( parameters !== undefined ) { | |
if ( parameters.attributes !== undefined ) { | |
console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' ); | |
} | |
this.setValues( parameters ); | |
} | |
} | |
ShaderMaterial.prototype = Object.create( Material.prototype ); | |
ShaderMaterial.prototype.constructor = ShaderMaterial; | |
ShaderMaterial.prototype.isShaderMaterial = true; | |
ShaderMaterial.prototype.copy = function ( source ) { | |
Material.prototype.copy.call( this, source ); | |
this.fragmentShader = source.fragmentShader; | |
this.vertexShader = source.vertexShader; | |
this.uniforms = cloneUniforms( source.uniforms ); | |
this.defines = Object.assign( {}, source.defines ); | |
this.wireframe = source.wireframe; | |
this.wireframeLinewidth = source.wireframeLinewidth; | |
this.lights = source.lights; | |
this.clipping = source.clipping; | |
this.skinning = source.skinning; | |
this.morphTargets = source.morphTargets; | |
this.morphNormals = source.morphNormals; | |
this.extensions = source.extensions; | |
return this; | |
}; | |
ShaderMaterial.prototype.toJSON = function ( meta ) { | |
var data = Material.prototype.toJSON.call( this, meta ); | |
data.uniforms = {}; | |
for ( var name in this.uniforms ) { | |
var uniform = this.uniforms[ name ]; | |
var value = uniform.value; | |
if ( value && value.isTexture ) { | |
data.uniforms[ name ] = { | |
type: 't', | |
value: value.toJSON( meta ).uuid | |
}; | |
} else if ( value && value.isColor ) { | |
data.uniforms[ name ] = { | |
type: 'c', | |
value: value.getHex() | |
}; | |
} else if ( value && value.isVector2 ) { | |
data.uniforms[ name ] = { | |
type: 'v2', | |
value: value.toArray() | |
}; | |
} else if ( value && value.isVector3 ) { | |
data.uniforms[ name ] = { | |
type: 'v3', | |
value: value.toArray() | |
}; | |
} else if ( value && value.isVector4 ) { | |
data.uniforms[ name ] = { | |
type: 'v4', | |
value: value.toArray() | |
}; | |
} else if ( value && value.isMatrix3 ) { | |
data.uniforms[ name ] = { | |
type: 'm3', | |
value: value.toArray() | |
}; | |
} else if ( value && value.isMatrix4 ) { | |
data.uniforms[ name ] = { | |
type: 'm4', | |
value: value.toArray() | |
}; | |
} else { | |
data.uniforms[ name ] = { | |
value: value | |
}; | |
// note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far | |
} | |
} | |
if ( Object.keys( this.defines ).length > 0 ) { data.defines = this.defines; } | |
data.vertexShader = this.vertexShader; | |
data.fragmentShader = this.fragmentShader; | |
var extensions = {}; | |
for ( var key in this.extensions ) { | |
if ( this.extensions[ key ] === true ) { extensions[ key ] = true; } | |
} | |
if ( Object.keys( extensions ).length > 0 ) { data.extensions = extensions; } | |
return data; | |
}; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author mikael emtinger / http://gomo.se/ | |
* @author WestLangley / http://github.com/WestLangley | |
*/ | |
function Camera() { | |
Object3D.call( this ); | |
this.type = 'Camera'; | |
this.matrixWorldInverse = new Matrix4(); | |
this.projectionMatrix = new Matrix4(); | |
this.projectionMatrixInverse = new Matrix4(); | |
} | |
Camera.prototype = Object.assign( Object.create( Object3D.prototype ), { | |
constructor: Camera, | |
isCamera: true, | |
copy: function ( source, recursive ) { | |
Object3D.prototype.copy.call( this, source, recursive ); | |
this.matrixWorldInverse.copy( source.matrixWorldInverse ); | |
this.projectionMatrix.copy( source.projectionMatrix ); | |
this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); | |
return this; | |
}, | |
getWorldDirection: function ( target ) { | |
if ( target === undefined ) { | |
console.warn( 'THREE.Camera: .getWorldDirection() target is now required' ); | |
target = new Vector3(); | |
} | |
this.updateMatrixWorld( true ); | |
var e = this.matrixWorld.elements; | |
return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize(); | |
}, | |
updateMatrixWorld: function ( force ) { | |
Object3D.prototype.updateMatrixWorld.call( this, force ); | |
this.matrixWorldInverse.getInverse( this.matrixWorld ); | |
}, | |
updateWorldMatrix: function ( updateParents, updateChildren ) { | |
Object3D.prototype.updateWorldMatrix.call( this, updateParents, updateChildren ); | |
this.matrixWorldInverse.getInverse( this.matrixWorld ); | |
}, | |
clone: function () { | |
return new this.constructor().copy( this ); | |
} | |
} ); | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author greggman / http://games.greggman.com/ | |
* @author zz85 / http://www.lab4games.net/zz85/blog | |
* @author tschw | |
*/ | |
function PerspectiveCamera( fov, aspect, near, far ) { | |
Camera.call( this ); | |
this.type = 'PerspectiveCamera'; | |
this.fov = fov !== undefined ? fov : 50; | |
this.zoom = 1; | |
this.near = near !== undefined ? near : 0.1; | |
this.far = far !== undefined ? far : 2000; | |
this.focus = 10; | |
this.aspect = aspect !== undefined ? aspect : 1; | |
this.view = null; | |
this.filmGauge = 35; // width of the film (default in millimeters) | |
this.filmOffset = 0; // horizontal film offset (same unit as gauge) | |
this.updateProjectionMatrix(); | |
} | |
PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), { | |
constructor: PerspectiveCamera, | |
isPerspectiveCamera: true, | |
copy: function ( source, recursive ) { | |
Camera.prototype.copy.call( this, source, recursive ); | |
this.fov = source.fov; | |
this.zoom = source.zoom; | |
this.near = source.near; | |
this.far = source.far; | |
this.focus = source.focus; | |
this.aspect = source.aspect; | |
this.view = source.view === null ? null : Object.assign( {}, source.view ); | |
this.filmGauge = source.filmGauge; | |
this.filmOffset = source.filmOffset; | |
return this; | |
}, | |
/** | |
* Sets the FOV by focal length in respect to the current .filmGauge. | |
* | |
* The default film gauge is 35, so that the focal length can be specified for | |
* a 35mm (full frame) camera. | |
* | |
* Values for focal length and film gauge must have the same unit. | |
*/ | |
setFocalLength: function ( focalLength ) { | |
// see http://www.bobatkins.com/photography/technical/field_of_view.html | |
var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; | |
this.fov = MathUtils.RAD2DEG * 2 * Math.atan( vExtentSlope ); | |
this.updateProjectionMatrix(); | |
}, | |
/** | |
* Calculates the focal length from the current .fov and .filmGauge. | |
*/ | |
getFocalLength: function () { | |
var vExtentSlope = Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ); | |
return 0.5 * this.getFilmHeight() / vExtentSlope; | |
}, | |
getEffectiveFOV: function () { | |
return MathUtils.RAD2DEG * 2 * Math.atan( | |
Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom ); | |
}, | |
getFilmWidth: function () { | |
// film not completely covered in portrait format (aspect < 1) | |
return this.filmGauge * Math.min( this.aspect, 1 ); | |
}, | |
getFilmHeight: function () { | |
// film not completely covered in landscape format (aspect > 1) | |
return this.filmGauge / Math.max( this.aspect, 1 ); | |
}, | |
/** | |
* Sets an offset in a larger frustum. This is useful for multi-window or | |
* multi-monitor/multi-machine setups. | |
* | |
* For example, if you have 3x2 monitors and each monitor is 1920x1080 and | |
* the monitors are in grid like this | |
* | |
* +---+---+---+ | |
* | A | B | C | | |
* +---+---+---+ | |
* | D | E | F | | |
* +---+---+---+ | |
* | |
* then for each monitor you would call it like this | |
* | |
* var w = 1920; | |
* var h = 1080; | |
* var fullWidth = w * 3; | |
* var fullHeight = h * 2; | |
* | |
* --A-- | |
* camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); | |
* --B-- | |
* camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); | |
* --C-- | |
* camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); | |
* --D-- | |
* camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); | |
* --E-- | |
* camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); | |
* --F-- | |
* camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); | |
* | |
* Note there is no reason monitors have to be the same size or in a grid. | |
*/ | |
setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) { | |
this.aspect = fullWidth / fullHeight; | |
if ( this.view === null ) { | |
this.view = { | |
enabled: true, | |
fullWidth: 1, | |
fullHeight: 1, | |
offsetX: 0, | |
offsetY: 0, | |
width: 1, | |
height: 1 | |
}; | |
} | |
this.view.enabled = true; | |
this.view.fullWidth = fullWidth; | |
this.view.fullHeight = fullHeight; | |
this.view.offsetX = x; | |
this.view.offsetY = y; | |
this.view.width = width; | |
this.view.height = height; | |
this.updateProjectionMatrix(); | |
}, | |
clearViewOffset: function () { | |
if ( this.view !== null ) { | |
this.view.enabled = false; | |
} | |
this.updateProjectionMatrix(); | |
}, | |
updateProjectionMatrix: function () { | |
var near = this.near, | |
top = near * Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom, | |
height = 2 * top, | |
width = this.aspect * height, | |
left = - 0.5 * width, | |
view = this.view; | |
if ( this.view !== null && this.view.enabled ) { | |
var fullWidth = view.fullWidth, | |
fullHeight = view.fullHeight; | |
left += view.offsetX * width / fullWidth; | |
top -= view.offsetY * height / fullHeight; | |
width *= view.width / fullWidth; | |
height *= view.height / fullHeight; | |
} | |
var skew = this.filmOffset; | |
if ( skew !== 0 ) { left += near * skew / this.getFilmWidth(); } | |
this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far ); | |
this.projectionMatrixInverse.getInverse( this.projectionMatrix ); | |
}, | |
toJSON: function ( meta ) { | |
var data = Object3D.prototype.toJSON.call( this, meta ); | |
data.object.fov = this.fov; | |
data.object.zoom = this.zoom; | |
data.object.near = this.near; | |
data.object.far = this.far; | |
data.object.focus = this.focus; | |
data.object.aspect = this.aspect; | |
if ( this.view !== null ) { data.object.view = Object.assign( {}, this.view ); } | |
data.object.filmGauge = this.filmGauge; | |
data.object.filmOffset = this.filmOffset; | |
return data; | |
} | |
} ); | |
/** | |
* Camera for rendering cube maps | |
* - renders scene into axis-aligned cube | |
* | |
* @author alteredq / http://alteredqualia.com/ | |
*/ | |
var fov = 90, aspect = 1; | |
function CubeCamera( near, far, cubeResolution, options ) { | |
Object3D.call( this ); | |
this.type = 'CubeCamera'; | |
var cameraPX = new PerspectiveCamera( fov, aspect, near, far ); | |
cameraPX.up.set( 0, - 1, 0 ); | |
cameraPX.lookAt( new Vector3( 1, 0, 0 ) ); | |
this.add( cameraPX ); | |
var cameraNX = new PerspectiveCamera( fov, aspect, near, far ); | |
cameraNX.up.set( 0, - 1, 0 ); | |
cameraNX.lookAt( new Vector3( - 1, 0, 0 ) ); | |
this.add( cameraNX ); | |
var cameraPY = new PerspectiveCamera( fov, aspect, near, far ); | |
cameraPY.up.set( 0, 0, 1 ); | |
cameraPY.lookAt( new Vector3( 0, 1, 0 ) ); | |
this.add( cameraPY ); | |
var cameraNY = new PerspectiveCamera( fov, aspect, near, far ); | |
cameraNY.up.set( 0, 0, - 1 ); | |
cameraNY.lookAt( new Vector3( 0, - 1, 0 ) ); | |
this.add( cameraNY ); | |
var cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); | |
cameraPZ.up.set( 0, - 1, 0 ); | |
cameraPZ.lookAt( new Vector3( 0, 0, 1 ) ); | |
this.add( cameraPZ ); | |
var cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); | |
cameraNZ.up.set( 0, - 1, 0 ); | |
cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) ); | |
this.add( cameraNZ ); | |
options = options || { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter }; | |
this.renderTarget = new WebGLCubeRenderTarget( cubeResolution, options ); | |
this.renderTarget.texture.name = "CubeCamera"; | |
this.update = function ( renderer, scene ) { | |
if ( this.parent === null ) { this.updateMatrixWorld(); } | |
var currentRenderTarget = renderer.getRenderTarget(); | |
var renderTarget = this.renderTarget; | |
var generateMipmaps = renderTarget.texture.generateMipmaps; | |
renderTarget.texture.generateMipmaps = false; | |
renderer.setRenderTarget( renderTarget, 0 ); | |
renderer.render( scene, cameraPX ); | |
renderer.setRenderTarget( renderTarget, 1 ); | |
renderer.render( scene, cameraNX ); | |
renderer.setRenderTarget( renderTarget, 2 ); | |
renderer.render( scene, cameraPY ); | |
renderer.setRenderTarget( renderTarget, 3 ); | |
renderer.render( scene, cameraNY ); | |
renderer.setRenderTarget( renderTarget, 4 ); | |
renderer.render( scene, cameraPZ ); | |
renderTarget.texture.generateMipmaps = generateMipmaps; | |
renderer.setRenderTarget( renderTarget, 5 ); | |
renderer.render( scene, cameraNZ ); | |
renderer.setRenderTarget( currentRenderTarget ); | |
}; | |
this.clear = function ( renderer, color, depth, stencil ) { | |
var currentRenderTarget = renderer.getRenderTarget(); | |
var renderTarget = this.renderTarget; | |
for ( var i = 0; i < 6; i ++ ) { | |
renderer.setRenderTarget( renderTarget, i ); | |
renderer.clear( color, depth, stencil ); | |
} | |
renderer.setRenderTarget( currentRenderTarget ); | |
}; | |
} | |
CubeCamera.prototype = Object.create( Object3D.prototype ); | |
CubeCamera.prototype.constructor = CubeCamera; | |
/** | |
* @author alteredq / http://alteredqualia.com | |
* @author WestLangley / http://github.com/WestLangley | |
*/ | |
function WebGLCubeRenderTarget( size, options, dummy ) { | |
if ( Number.isInteger( options ) ) { | |
console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' ); | |
options = dummy; | |
} | |
WebGLRenderTarget.call( this, size, size, options ); | |
} | |
WebGLCubeRenderTarget.prototype = Object.create( WebGLRenderTarget.prototype ); | |
WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget; | |
WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true; | |
WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function ( renderer, texture ) { | |
this.texture.type = texture.type; | |
this.texture.format = texture.format; | |
this.texture.encoding = texture.encoding; | |
var scene = new Scene(); | |
var shader = { | |
uniforms: { | |
tEquirect: { value: null }, | |
}, | |
vertexShader: [ | |
"varying vec3 vWorldDirection;", | |
"vec3 transformDirection( in vec3 dir, in mat4 matrix ) {", | |
" return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );", | |
"}", | |
"void main() {", | |
" vWorldDirection = transformDirection( position, modelMatrix );", | |
" #include <begin_vertex>", | |
" #include <project_vertex>", | |
"}" | |
].join( '\n' ), | |
fragmentShader: [ | |
"uniform sampler2D tEquirect;", | |
"varying vec3 vWorldDirection;", | |
"#define RECIPROCAL_PI 0.31830988618", | |
"#define RECIPROCAL_PI2 0.15915494", | |
"void main() {", | |
" vec3 direction = normalize( vWorldDirection );", | |
" vec2 sampleUV;", | |
" sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;", | |
" sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;", | |
" gl_FragColor = texture2D( tEquirect, sampleUV );", | |
"}" | |
].join( '\n' ), | |
}; | |
var material = new ShaderMaterial( { | |
type: 'CubemapFromEquirect', | |
uniforms: cloneUniforms( shader.uniforms ), | |
vertexShader: shader.vertexShader, | |
fragmentShader: shader.fragmentShader, | |
side: BackSide, | |
blending: NoBlending | |
} ); | |
material.uniforms.tEquirect.value = texture; | |
var mesh = new Mesh( new BoxBufferGeometry( 5, 5, 5 ), material ); | |
scene.add( mesh ); | |
var camera = new CubeCamera( 1, 10, 1 ); | |
camera.renderTarget = this; | |
camera.renderTarget.texture.name = 'CubeCameraTexture'; | |
camera.update( renderer, scene ); | |
mesh.geometry.dispose(); | |
mesh.material.dispose(); | |
return this; | |
}; | |
/** | |
* @author alteredq / http://alteredqualia.com/ | |
*/ | |
function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { | |
Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); | |
this.image = { data: data || null, width: width || 1, height: height || 1 }; | |
this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; | |
this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; | |
this.generateMipmaps = false; | |
this.flipY = false; | |
this.unpackAlignment = 1; | |
this.needsUpdate = true; | |
} | |
DataTexture.prototype = Object.create( Texture.prototype ); | |
DataTexture.prototype.constructor = DataTexture; | |
DataTexture.prototype.isDataTexture = true; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author alteredq / http://alteredqualia.com/ | |
* @author bhouston / http://clara.io | |
*/ | |
var _sphere$1 = new Sphere(); | |
var _vector$5 = new Vector3(); | |
function Frustum( p0, p1, p2, p3, p4, p5 ) { | |
this.planes = [ | |
( p0 !== undefined ) ? p0 : new Plane(), | |
( p1 !== undefined ) ? p1 : new Plane(), | |
( p2 !== undefined ) ? p2 : new Plane(), | |
( p3 !== undefined ) ? p3 : new Plane(), | |
( p4 !== undefined ) ? p4 : new Plane(), | |
( p5 !== undefined ) ? p5 : new Plane() | |
]; | |
} | |
Object.assign( Frustum.prototype, { | |
set: function ( p0, p1, p2, p3, p4, p5 ) { | |
var planes = this.planes; | |
planes[ 0 ].copy( p0 ); | |
planes[ 1 ].copy( p1 ); | |
planes[ 2 ].copy( p2 ); | |
planes[ 3 ].copy( p3 ); | |
planes[ 4 ].copy( p4 ); | |
planes[ 5 ].copy( p5 ); | |
return this; | |
}, | |
clone: function () { | |
return new this.constructor().copy( this ); | |
}, | |
copy: function ( frustum ) { | |
var planes = this.planes; | |
for ( var i = 0; i < 6; i ++ ) { | |
planes[ i ].copy( frustum.planes[ i ] ); | |
} | |
return this; | |
}, | |
setFromProjectionMatrix: function ( m ) { | |
var planes = this.planes; | |
var me = m.elements; | |
var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ]; | |
var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ]; | |
var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ]; | |
var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ]; | |
planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); | |
planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); | |
planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); | |
planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); | |
planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); | |
planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); | |
return this; | |
}, | |
intersectsObject: function ( object ) { | |
var geometry = object.geometry; | |
if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); } | |
_sphere$1.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld ); | |
return this.intersectsSphere( _sphere$1 ); | |
}, | |
intersectsSprite: function ( sprite ) { | |
_sphere$1.center.set( 0, 0, 0 ); | |
_sphere$1.radius = 0.7071067811865476; | |
_sphere$1.applyMatrix4( sprite.matrixWorld ); | |
return this.intersectsSphere( _sphere$1 ); | |
}, | |
intersectsSphere: function ( sphere ) { | |
var planes = this.planes; | |
var center = sphere.center; | |
var negRadius = - sphere.radius; | |
for ( var i = 0; i < 6; i ++ ) { | |
var distance = planes[ i ].distanceToPoint( center ); | |
if ( distance < negRadius ) { | |
return false; | |
} | |
} | |
return true; | |
}, | |
intersectsBox: function ( box ) { | |
var planes = this.planes; | |
for ( var i = 0; i < 6; i ++ ) { | |
var plane = planes[ i ]; | |
// corner at max distance | |
_vector$5.x = plane.normal.x > 0 ? box.max.x : box.min.x; | |
_vector$5.y = plane.normal.y > 0 ? box.max.y : box.min.y; | |
_vector$5.z = plane.normal.z > 0 ? box.max.z : box.min.z; | |
if ( plane.distanceToPoint( _vector$5 ) < 0 ) { | |
return false; | |
} | |
} | |
return true; | |
}, | |
containsPoint: function ( point ) { | |
var planes = this.planes; | |
for ( var i = 0; i < 6; i ++ ) { | |
if ( planes[ i ].distanceToPoint( point ) < 0 ) { | |
return false; | |
} | |
} | |
return true; | |
} | |
} ); | |
/** | |
* Uniforms library for shared webgl shaders | |
*/ | |
var UniformsLib = { | |
common: { | |
diffuse: { value: new Color( 0xeeeeee ) }, | |
opacity: { value: 1.0 }, | |
map: { value: null }, | |
uvTransform: { value: new Matrix3() }, | |
uv2Transform: { value: new Matrix3() }, | |
alphaMap: { value: null }, | |
}, | |
specularmap: { | |
specularMap: { value: null }, | |
}, | |
envmap: { | |
envMap: { value: null }, | |
flipEnvMap: { value: - 1 }, | |
reflectivity: { value: 1.0 }, | |
refractionRatio: { value: 0.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 Vector2( 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: 0.00025 }, | |
fogNear: { value: 1 }, | |
fogFar: { value: 2000 }, | |
fogColor: { value: new Color( 0xffffff ) } | |
}, | |
lights: { | |
ambientLightColor: { value: [] }, | |
lightProbe: { value: [] }, | |
directionalLights: { value: [], properties: { | |
direction: {}, | |
color: {} | |
} }, | |
directionalLightShadows: { value: [], properties: { | |
shadowBias: {}, | |
shadowRadius: {}, | |
shadowMapSize: {} | |
} }, | |
directionalShadowMap: { value: [] }, | |
directionalShadowMatrix: { value: [] }, | |
spotLights: { value: [], properties: { | |
color: {}, | |
position: {}, | |
direction: {}, | |
distance: {}, | |
coneCos: {}, | |
penumbraCos: {}, | |
decay: {} | |
} }, | |
spotLightShadows: { value: [], properties: { | |
shadowBias: {}, | |
shadowRadius: {}, | |
shadowMapSize: {} | |
} }, | |
spotShadowMap: { value: [] }, | |
spotShadowMatrix: { value: [] }, | |
pointLights: { value: [], properties: { | |
color: {}, | |
position: {}, | |
decay: {}, | |
distance: {} | |
} }, | |
pointLightShadows: { value: [], properties: { | |
shadowBias: {}, | |
shadowRadius: {}, | |
shadowMapSize: {}, | |
shadowCameraNear: {}, | |
shadowCameraFar: {} | |
} }, | |
pointShadowMap: { value: [] }, | |
pointShadowMatrix: { value: [] }, | |
hemisphereLights: { value: [], properties: { | |
direction: {}, | |
skyColor: {}, | |
groundColor: {} | |
} }, | |
// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src | |
rectAreaLights: { value: [], properties: { | |
color: {}, | |
position: {}, | |
width: {}, | |
height: {} | |
} } | |
}, | |
points: { | |
diffuse: { value: new Color( 0xeeeeee ) }, | |
opacity: { value: 1.0 }, | |
size: { value: 1.0 }, | |
scale: { value: 1.0 }, | |
map: { value: null }, | |
alphaMap: { value: null }, | |
uvTransform: { value: new Matrix3() } | |
}, | |
sprite: { | |
diffuse: { value: new Color( 0xeeeeee ) }, | |
opacity: { value: 1.0 }, | |
center: { value: new Vector2( 0.5, 0.5 ) }, | |
rotation: { value: 0.0 }, | |
map: { value: null }, | |
alphaMap: { value: null }, | |
uvTransform: { value: new Matrix3() } | |
} | |
}; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLAnimation() { | |
var context = null; | |
var isAnimating = false; | |
var animationLoop = null; | |
function onAnimationFrame( time, frame ) { | |
if ( isAnimating === false ) { return; } | |
animationLoop( time, frame ); | |
context.requestAnimationFrame( onAnimationFrame ); | |
} | |
return { | |
start: function () { | |
if ( isAnimating === true ) { return; } | |
if ( animationLoop === null ) { return; } | |
context.requestAnimationFrame( onAnimationFrame ); | |
isAnimating = true; | |
}, | |
stop: function () { | |
isAnimating = false; | |
}, | |
setAnimationLoop: function ( callback ) { | |
animationLoop = callback; | |
}, | |
setContext: function ( value ) { | |
context = value; | |
} | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLAttributes( gl, capabilities ) { | |
var isWebGL2 = capabilities.isWebGL2; | |
var buffers = new WeakMap(); | |
function createBuffer( attribute, bufferType ) { | |
var array = attribute.array; | |
var usage = attribute.usage; | |
var buffer = gl.createBuffer(); | |
gl.bindBuffer( bufferType, buffer ); | |
gl.bufferData( bufferType, array, usage ); | |
attribute.onUploadCallback(); | |
var type = 5126; | |
if ( array instanceof Float32Array ) { | |
type = 5126; | |
} else if ( array instanceof Float64Array ) { | |
console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); | |
} else if ( array instanceof Uint16Array ) { | |
type = 5123; | |
} else if ( array instanceof Int16Array ) { | |
type = 5122; | |
} else if ( array instanceof Uint32Array ) { | |
type = 5125; | |
} else if ( array instanceof Int32Array ) { | |
type = 5124; | |
} else if ( array instanceof Int8Array ) { | |
type = 5120; | |
} else if ( array instanceof Uint8Array ) { | |
type = 5121; | |
} | |
return { | |
buffer: buffer, | |
type: type, | |
bytesPerElement: array.BYTES_PER_ELEMENT, | |
version: attribute.version | |
}; | |
} | |
function updateBuffer( buffer, attribute, bufferType ) { | |
var array = attribute.array; | |
var updateRange = attribute.updateRange; | |
gl.bindBuffer( bufferType, buffer ); | |
if ( updateRange.count === - 1 ) { | |
// Not using update ranges | |
gl.bufferSubData( bufferType, 0, array ); | |
} else { | |
if ( isWebGL2 ) { | |
gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, | |
array, updateRange.offset, updateRange.count ); | |
} else { | |
gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, | |
array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); | |
} | |
updateRange.count = - 1; // reset range | |
} | |
} | |
// | |
function get( attribute ) { | |
if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; } | |
return buffers.get( attribute ); | |
} | |
function remove( attribute ) { | |
if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; } | |
var data = buffers.get( attribute ); | |
if ( data ) { | |
gl.deleteBuffer( data.buffer ); | |
buffers.delete( attribute ); | |
} | |
} | |
function update( attribute, bufferType ) { | |
if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; } | |
var data = buffers.get( attribute ); | |
if ( data === undefined ) { | |
buffers.set( attribute, createBuffer( attribute, bufferType ) ); | |
} else if ( data.version < attribute.version ) { | |
updateBuffer( data.buffer, attribute, bufferType ); | |
data.version = attribute.version; | |
} | |
} | |
return { | |
get: get, | |
remove: remove, | |
update: update | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author Mugen87 / https://github.com/Mugen87 | |
*/ | |
// PlaneGeometry | |
function PlaneGeometry( width, height, widthSegments, heightSegments ) { | |
Geometry.call( this ); | |
this.type = 'PlaneGeometry'; | |
this.parameters = { | |
width: width, | |
height: height, | |
widthSegments: widthSegments, | |
heightSegments: heightSegments | |
}; | |
this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); | |
this.mergeVertices(); | |
} | |
PlaneGeometry.prototype = Object.create( Geometry.prototype ); | |
PlaneGeometry.prototype.constructor = PlaneGeometry; | |
// PlaneBufferGeometry | |
function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { | |
BufferGeometry.call( this ); | |
this.type = 'PlaneBufferGeometry'; | |
this.parameters = { | |
width: width, | |
height: height, | |
widthSegments: widthSegments, | |
heightSegments: heightSegments | |
}; | |
width = width || 1; | |
height = height || 1; | |
var width_half = width / 2; | |
var height_half = height / 2; | |
var gridX = Math.floor( widthSegments ) || 1; | |
var gridY = Math.floor( heightSegments ) || 1; | |
var gridX1 = gridX + 1; | |
var gridY1 = gridY + 1; | |
var segment_width = width / gridX; | |
var segment_height = height / gridY; | |
var ix, iy; | |
// buffers | |
var indices = []; | |
var vertices = []; | |
var normals = []; | |
var uvs = []; | |
// generate vertices, normals and uvs | |
for ( iy = 0; iy < gridY1; iy ++ ) { | |
var y = iy * segment_height - height_half; | |
for ( ix = 0; ix < gridX1; ix ++ ) { | |
var x = ix * segment_width - width_half; | |
vertices.push( x, - y, 0 ); | |
normals.push( 0, 0, 1 ); | |
uvs.push( ix / gridX ); | |
uvs.push( 1 - ( iy / gridY ) ); | |
} | |
} | |
// indices | |
for ( iy = 0; iy < gridY; iy ++ ) { | |
for ( ix = 0; ix < gridX; ix ++ ) { | |
var a = ix + gridX1 * iy; | |
var b = ix + gridX1 * ( iy + 1 ); | |
var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); | |
var d = ( ix + 1 ) + gridX1 * iy; | |
// faces | |
indices.push( a, b, d ); | |
indices.push( b, c, d ); | |
} | |
} | |
// build geometry | |
this.setIndex( indices ); | |
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); | |
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); | |
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); | |
} | |
PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); | |
PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; | |
var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; | |
var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; | |
var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif"; | |
var 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"; | |
var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; | |
var begin_vertex = "vec3 transformed = vec3( position );"; | |
var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; | |
var 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"; | |
var 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"; | |
var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; | |
var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; | |
var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif"; | |
var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif"; | |
var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; | |
var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; | |
var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; | |
var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; | |
var 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}"; | |
var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_maxMipLevel 8.0\n#define cubeUV_minMipLevel 4.0\n#define cubeUV_maxTileSize 256.0\n#define cubeUV_minTileSize 16.0\nfloat getFace(vec3 direction) {\n vec3 absDirection = abs(direction);\n float face = -1.0;\n if (absDirection.x > absDirection.z) {\n if (absDirection.x > absDirection.y)\n face = direction.x > 0.0 ? 0.0 : 3.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n } else {\n if (absDirection.z > absDirection.y)\n face = direction.z > 0.0 ? 2.0 : 5.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n }\n return face;\n}\nvec2 getUV(vec3 direction, float face) {\n vec2 uv;\n if (face == 0.0) {\n uv = vec2(-direction.z, direction.y) / abs(direction.x);\n } else if (face == 1.0) {\n uv = vec2(direction.x, -direction.z) / abs(direction.y);\n } else if (face == 2.0) {\n uv = direction.xy / abs(direction.z);\n } else if (face == 3.0) {\n uv = vec2(direction.z, direction.y) / abs(direction.x);\n } else if (face == 4.0) {\n uv = direction.xz / abs(direction.y);\n } else {\n uv = vec2(-direction.x, direction.y) / abs(direction.z);\n }\n return 0.5 * (uv + 1.0);\n}\nvec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {\n float face = getFace(direction);\n float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);\n mipInt = max(mipInt, cubeUV_minMipLevel);\n float faceSize = exp2(mipInt);\n float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);\n vec2 uv = getUV(direction, face) * (faceSize - 1.0);\n vec2 f = fract(uv);\n uv += 0.5 - f;\n if (face > 2.0) {\n uv.y += faceSize;\n face -= 3.0;\n }\n uv.x += face * faceSize;\n if(mipInt < cubeUV_maxMipLevel){\n uv.y += 2.0 * cubeUV_maxTileSize;\n }\n uv.y += filterInt * 2.0 * cubeUV_minTileSize;\n uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);\n uv *= texelSize;\n vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.x += texelSize;\n vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.y += texelSize;\n vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.x -= texelSize;\n vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n vec3 tm = mix(tl, tr, f.x);\n vec3 bm = mix(bl, br, f.x);\n return mix(tm, bm, f.y);\n}\n#define r0 1.0\n#define v0 0.339\n#define m0 -2.0\n#define r1 0.8\n#define v1 0.276\n#define m1 -1.0\n#define r4 0.4\n#define v4 0.046\n#define m4 2.0\n#define r5 0.305\n#define v5 0.016\n#define m5 3.0\n#define r6 0.21\n#define v6 0.0038\n#define m6 4.0\nfloat roughnessToMip(float roughness) {\n float mip = 0.0;\n if (roughness >= r1) {\n mip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0;\n } else if (roughness >= r4) {\n mip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1;\n } else if (roughness >= r5) {\n mip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4;\n } else if (roughness >= r6) {\n mip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5;\n } else {\n mip = -2.0 * log2(1.16 * roughness); }\n return mip;\n}\nvec4 textureCubeUV(sampler2D envMap, vec3 sampleDir, float roughness) {\n float mip = clamp(roughnessToMip(roughness), m0, cubeUV_maxMipLevel);\n float mipF = fract(mip);\n float mipInt = floor(mip);\n vec3 color0 = bilinearCubeUV(envMap, sampleDir, mipInt);\n if (mipF == 0.0) {\n return vec4(color0, 1.0);\n } else {\n vec3 color1 = bilinearCubeUV(envMap, sampleDir, mipInt + 1.0);\n return vec4(mix(color0, color1, mipF), 1.0);\n }\n}\n#endif"; | |
var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif"; | |
var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; | |
var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif"; | |
var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; | |
var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; | |
var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; | |
var 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 = clamp( floor( D ) / 255.0, 0.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}"; | |
var 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_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\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\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#endif\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"; | |
var 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"; | |
var 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"; | |
var 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"; | |
var 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"; | |
var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif"; | |
var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif"; | |
var 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"; | |
var 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"; | |
var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn texture2D( gradientMap, coord ).rgb;\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}"; | |
var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\treflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n#endif"; | |
var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; | |
var 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_start\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\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\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\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\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\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\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\t#pragma unroll_loop_end\n#endif"; | |
var 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};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\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};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\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};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\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"; | |
var 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\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 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\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, 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"; | |
var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; | |
var lights_toon_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct ToonMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\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_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)"; | |
var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; | |
var 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\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\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)"; | |
var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness;\nmaterial.specularRoughness = min( material.specularRoughness, 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 = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif"; | |
var 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}"; | |
var 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#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\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\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\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\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\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\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\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\t#pragma unroll_loop_end\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_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif"; | |
var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * 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"; | |
var 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"; | |
var 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"; | |
var 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"; | |
var 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"; | |
var 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"; | |
var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif"; | |
var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; | |
var 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"; | |
var 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"; | |
var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; | |
var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; | |
var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n#endif"; | |
var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; | |
var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t#endif\n#endif"; | |
var 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\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;"; | |
var 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\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, mapN );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif"; | |
var 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, vec3 mapN ) {\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\tmat3 tsn = mat3( S, T, N );\n\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif"; | |
var clearcoat_normal_fragment_begin = "#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; | |
var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN );\n\t#endif\n#endif"; | |
var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif"; | |
var 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 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);\n}\nvec2 unpackRGBATo2Half( 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}"; | |
var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; | |
var 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;"; | |
var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; | |
var 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"; | |
var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; | |
var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; | |
var 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 unpackRGBATo2Half( 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 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 dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\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"; | |
var 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"; | |
var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif"; | |
var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}"; | |
var 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"; | |
var 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"; | |
var 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"; | |
var 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"; | |
var 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"; | |
var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; | |
var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; | |
var 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}"; | |
var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; | |
var 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"; | |
var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; | |
var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; | |
var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif"; | |
var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; | |
var 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"; | |
var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}"; | |
var 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}"; | |
var cube_frag = "#include <envmap_common_pars_fragment>\nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include <envmap_fragment>\n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}"; | |
var cube_vert = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}"; | |
var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}"; | |
var depth_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}"; | |
var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}"; | |
var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}"; | |
var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\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 <tonemapping_fragment>\n\t#include <encodings_fragment>\n}"; | |
var equirect_vert = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}"; | |
var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}"; | |
var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}"; | |
var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}"; | |
var meshbasic_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}"; | |
var 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 <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\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 <lightmap_fragment>\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 <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; | |
var 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 <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}"; | |
var 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 <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\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 <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}"; | |
var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n\tvViewPosition = - mvPosition.xyz;\n}"; | |
var meshtoon_frag = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_toon_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_toon_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; | |
var meshtoon_vert = "#define TOON\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}"; | |
var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; | |
var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}"; | |
var 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 <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\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 <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"; | |
var 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 <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\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 <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}"; | |
var 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 <packing>\n#include <uv_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; | |
var 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 <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\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 <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; | |
var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}"; | |
var points_vert = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\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 <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n}"; | |
var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}"; | |
var shadow_vert = "#include <fog_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}"; | |
var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}"; | |
var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include <common>\n#include <uv_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\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 <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}"; | |
var ShaderChunk = { | |
alphamap_fragment: alphamap_fragment, | |
alphamap_pars_fragment: alphamap_pars_fragment, | |
alphatest_fragment: alphatest_fragment, | |
aomap_fragment: aomap_fragment, | |
aomap_pars_fragment: aomap_pars_fragment, | |
begin_vertex: begin_vertex, | |
beginnormal_vertex: beginnormal_vertex, | |
bsdfs: bsdfs, | |
bumpmap_pars_fragment: bumpmap_pars_fragment, | |
clipping_planes_fragment: clipping_planes_fragment, | |
clipping_planes_pars_fragment: clipping_planes_pars_fragment, | |
clipping_planes_pars_vertex: clipping_planes_pars_vertex, | |
clipping_planes_vertex: clipping_planes_vertex, | |
color_fragment: color_fragment, | |
color_pars_fragment: color_pars_fragment, | |
color_pars_vertex: color_pars_vertex, | |
color_vertex: color_vertex, | |
common: common, | |
cube_uv_reflection_fragment: cube_uv_reflection_fragment, | |
defaultnormal_vertex: defaultnormal_vertex, | |
displacementmap_pars_vertex: displacementmap_pars_vertex, | |
displacementmap_vertex: displacementmap_vertex, | |
emissivemap_fragment: emissivemap_fragment, | |
emissivemap_pars_fragment: emissivemap_pars_fragment, | |
encodings_fragment: encodings_fragment, | |
encodings_pars_fragment: encodings_pars_fragment, | |
envmap_fragment: envmap_fragment, | |
envmap_common_pars_fragment: envmap_common_pars_fragment, | |
envmap_pars_fragment: envmap_pars_fragment, | |
envmap_pars_vertex: envmap_pars_vertex, | |
envmap_physical_pars_fragment: envmap_physical_pars_fragment, | |
envmap_vertex: envmap_vertex, | |
fog_vertex: fog_vertex, | |
fog_pars_vertex: fog_pars_vertex, | |
fog_fragment: fog_fragment, | |
fog_pars_fragment: fog_pars_fragment, | |
gradientmap_pars_fragment: gradientmap_pars_fragment, | |
lightmap_fragment: lightmap_fragment, | |
lightmap_pars_fragment: lightmap_pars_fragment, | |
lights_lambert_vertex: lights_lambert_vertex, | |
lights_pars_begin: lights_pars_begin, | |
lights_toon_fragment: lights_toon_fragment, | |
lights_toon_pars_fragment: lights_toon_pars_fragment, | |
lights_phong_fragment: lights_phong_fragment, | |
lights_phong_pars_fragment: lights_phong_pars_fragment, | |
lights_physical_fragment: lights_physical_fragment, | |
lights_physical_pars_fragment: lights_physical_pars_fragment, | |
lights_fragment_begin: lights_fragment_begin, | |
lights_fragment_maps: lights_fragment_maps, | |
lights_fragment_end: lights_fragment_end, | |
logdepthbuf_fragment: logdepthbuf_fragment, | |
logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, | |
logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, | |
logdepthbuf_vertex: logdepthbuf_vertex, | |
map_fragment: map_fragment, | |
map_pars_fragment: map_pars_fragment, | |
map_particle_fragment: map_particle_fragment, | |
map_particle_pars_fragment: map_particle_pars_fragment, | |
metalnessmap_fragment: metalnessmap_fragment, | |
metalnessmap_pars_fragment: metalnessmap_pars_fragment, | |
morphnormal_vertex: morphnormal_vertex, | |
morphtarget_pars_vertex: morphtarget_pars_vertex, | |
morphtarget_vertex: morphtarget_vertex, | |
normal_fragment_begin: normal_fragment_begin, | |
normal_fragment_maps: normal_fragment_maps, | |
normalmap_pars_fragment: normalmap_pars_fragment, | |
clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, | |
clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, | |
clearcoat_pars_fragment: clearcoat_pars_fragment, | |
packing: packing, | |
premultiplied_alpha_fragment: premultiplied_alpha_fragment, | |
project_vertex: project_vertex, | |
dithering_fragment: dithering_fragment, | |
dithering_pars_fragment: dithering_pars_fragment, | |
roughnessmap_fragment: roughnessmap_fragment, | |
roughnessmap_pars_fragment: roughnessmap_pars_fragment, | |
shadowmap_pars_fragment: shadowmap_pars_fragment, | |
shadowmap_pars_vertex: shadowmap_pars_vertex, | |
shadowmap_vertex: shadowmap_vertex, | |
shadowmask_pars_fragment: shadowmask_pars_fragment, | |
skinbase_vertex: skinbase_vertex, | |
skinning_pars_vertex: skinning_pars_vertex, | |
skinning_vertex: skinning_vertex, | |
skinnormal_vertex: skinnormal_vertex, | |
specularmap_fragment: specularmap_fragment, | |
specularmap_pars_fragment: specularmap_pars_fragment, | |
tonemapping_fragment: tonemapping_fragment, | |
tonemapping_pars_fragment: tonemapping_pars_fragment, | |
uv_pars_fragment: uv_pars_fragment, | |
uv_pars_vertex: uv_pars_vertex, | |
uv_vertex: uv_vertex, | |
uv2_pars_fragment: uv2_pars_fragment, | |
uv2_pars_vertex: uv2_pars_vertex, | |
uv2_vertex: uv2_vertex, | |
worldpos_vertex: worldpos_vertex, | |
background_frag: background_frag, | |
background_vert: background_vert, | |
cube_frag: cube_frag, | |
cube_vert: cube_vert, | |
depth_frag: depth_frag, | |
depth_vert: depth_vert, | |
distanceRGBA_frag: distanceRGBA_frag, | |
distanceRGBA_vert: distanceRGBA_vert, | |
equirect_frag: equirect_frag, | |
equirect_vert: equirect_vert, | |
linedashed_frag: linedashed_frag, | |
linedashed_vert: linedashed_vert, | |
meshbasic_frag: meshbasic_frag, | |
meshbasic_vert: meshbasic_vert, | |
meshlambert_frag: meshlambert_frag, | |
meshlambert_vert: meshlambert_vert, | |
meshmatcap_frag: meshmatcap_frag, | |
meshmatcap_vert: meshmatcap_vert, | |
meshtoon_frag: meshtoon_frag, | |
meshtoon_vert: meshtoon_vert, | |
meshphong_frag: meshphong_frag, | |
meshphong_vert: meshphong_vert, | |
meshphysical_frag: meshphysical_frag, | |
meshphysical_vert: meshphysical_vert, | |
normal_frag: normal_frag, | |
normal_vert: normal_vert, | |
points_frag: points_frag, | |
points_vert: points_vert, | |
shadow_frag: shadow_frag, | |
shadow_vert: shadow_vert, | |
sprite_frag: sprite_frag, | |
sprite_vert: sprite_vert | |
}; | |
/** | |
* @author alteredq / http://alteredqualia.com/ | |
* @author mrdoob / http://mrdoob.com/ | |
* @author mikael emtinger / http://gomo.se/ | |
*/ | |
var ShaderLib = { | |
basic: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.common, | |
UniformsLib.specularmap, | |
UniformsLib.envmap, | |
UniformsLib.aomap, | |
UniformsLib.lightmap, | |
UniformsLib.fog | |
] ), | |
vertexShader: ShaderChunk.meshbasic_vert, | |
fragmentShader: ShaderChunk.meshbasic_frag | |
}, | |
lambert: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.common, | |
UniformsLib.specularmap, | |
UniformsLib.envmap, | |
UniformsLib.aomap, | |
UniformsLib.lightmap, | |
UniformsLib.emissivemap, | |
UniformsLib.fog, | |
UniformsLib.lights, | |
{ | |
emissive: { value: new Color( 0x000000 ) } | |
} | |
] ), | |
vertexShader: ShaderChunk.meshlambert_vert, | |
fragmentShader: ShaderChunk.meshlambert_frag | |
}, | |
phong: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.common, | |
UniformsLib.specularmap, | |
UniformsLib.envmap, | |
UniformsLib.aomap, | |
UniformsLib.lightmap, | |
UniformsLib.emissivemap, | |
UniformsLib.bumpmap, | |
UniformsLib.normalmap, | |
UniformsLib.displacementmap, | |
UniformsLib.fog, | |
UniformsLib.lights, | |
{ | |
emissive: { value: new Color( 0x000000 ) }, | |
specular: { value: new Color( 0x111111 ) }, | |
shininess: { value: 30 } | |
} | |
] ), | |
vertexShader: ShaderChunk.meshphong_vert, | |
fragmentShader: ShaderChunk.meshphong_frag | |
}, | |
standard: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.common, | |
UniformsLib.envmap, | |
UniformsLib.aomap, | |
UniformsLib.lightmap, | |
UniformsLib.emissivemap, | |
UniformsLib.bumpmap, | |
UniformsLib.normalmap, | |
UniformsLib.displacementmap, | |
UniformsLib.roughnessmap, | |
UniformsLib.metalnessmap, | |
UniformsLib.fog, | |
UniformsLib.lights, | |
{ | |
emissive: { value: new Color( 0x000000 ) }, | |
roughness: { value: 0.5 }, | |
metalness: { value: 0.5 }, | |
envMapIntensity: { value: 1 } // temporary | |
} | |
] ), | |
vertexShader: ShaderChunk.meshphysical_vert, | |
fragmentShader: ShaderChunk.meshphysical_frag | |
}, | |
toon: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.common, | |
UniformsLib.specularmap, | |
UniformsLib.aomap, | |
UniformsLib.lightmap, | |
UniformsLib.emissivemap, | |
UniformsLib.bumpmap, | |
UniformsLib.normalmap, | |
UniformsLib.displacementmap, | |
UniformsLib.gradientmap, | |
UniformsLib.fog, | |
UniformsLib.lights, | |
{ | |
emissive: { value: new Color( 0x000000 ) }, | |
specular: { value: new Color( 0x111111 ) }, | |
shininess: { value: 30 } | |
} | |
] ), | |
vertexShader: ShaderChunk.meshtoon_vert, | |
fragmentShader: ShaderChunk.meshtoon_frag | |
}, | |
matcap: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.common, | |
UniformsLib.bumpmap, | |
UniformsLib.normalmap, | |
UniformsLib.displacementmap, | |
UniformsLib.fog, | |
{ | |
matcap: { value: null } | |
} | |
] ), | |
vertexShader: ShaderChunk.meshmatcap_vert, | |
fragmentShader: ShaderChunk.meshmatcap_frag | |
}, | |
points: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.points, | |
UniformsLib.fog | |
] ), | |
vertexShader: ShaderChunk.points_vert, | |
fragmentShader: ShaderChunk.points_frag | |
}, | |
dashed: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.common, | |
UniformsLib.fog, | |
{ | |
scale: { value: 1 }, | |
dashSize: { value: 1 }, | |
totalSize: { value: 2 } | |
} | |
] ), | |
vertexShader: ShaderChunk.linedashed_vert, | |
fragmentShader: ShaderChunk.linedashed_frag | |
}, | |
depth: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.common, | |
UniformsLib.displacementmap | |
] ), | |
vertexShader: ShaderChunk.depth_vert, | |
fragmentShader: ShaderChunk.depth_frag | |
}, | |
normal: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.common, | |
UniformsLib.bumpmap, | |
UniformsLib.normalmap, | |
UniformsLib.displacementmap, | |
{ | |
opacity: { value: 1.0 } | |
} | |
] ), | |
vertexShader: ShaderChunk.normal_vert, | |
fragmentShader: ShaderChunk.normal_frag | |
}, | |
sprite: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.sprite, | |
UniformsLib.fog | |
] ), | |
vertexShader: ShaderChunk.sprite_vert, | |
fragmentShader: ShaderChunk.sprite_frag | |
}, | |
background: { | |
uniforms: { | |
uvTransform: { value: new Matrix3() }, | |
t2D: { value: null }, | |
}, | |
vertexShader: ShaderChunk.background_vert, | |
fragmentShader: ShaderChunk.background_frag | |
}, | |
/* ------------------------------------------------------------------------- | |
// Cube map shader | |
------------------------------------------------------------------------- */ | |
cube: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.envmap, | |
{ | |
opacity: { value: 1.0 } | |
} | |
] ), | |
vertexShader: ShaderChunk.cube_vert, | |
fragmentShader: ShaderChunk.cube_frag | |
}, | |
equirect: { | |
uniforms: { | |
tEquirect: { value: null }, | |
}, | |
vertexShader: ShaderChunk.equirect_vert, | |
fragmentShader: ShaderChunk.equirect_frag | |
}, | |
distanceRGBA: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.common, | |
UniformsLib.displacementmap, | |
{ | |
referencePosition: { value: new Vector3() }, | |
nearDistance: { value: 1 }, | |
farDistance: { value: 1000 } | |
} | |
] ), | |
vertexShader: ShaderChunk.distanceRGBA_vert, | |
fragmentShader: ShaderChunk.distanceRGBA_frag | |
}, | |
shadow: { | |
uniforms: mergeUniforms( [ | |
UniformsLib.lights, | |
UniformsLib.fog, | |
{ | |
color: { value: new Color( 0x00000 ) }, | |
opacity: { value: 1.0 } | |
} ] ), | |
vertexShader: ShaderChunk.shadow_vert, | |
fragmentShader: ShaderChunk.shadow_frag | |
} | |
}; | |
ShaderLib.physical = { | |
uniforms: mergeUniforms( [ | |
ShaderLib.standard.uniforms, | |
{ | |
clearcoat: { value: 0 }, | |
clearcoatMap: { value: null }, | |
clearcoatRoughness: { value: 0 }, | |
clearcoatRoughnessMap: { value: null }, | |
clearcoatNormalScale: { value: new Vector2( 1, 1 ) }, | |
clearcoatNormalMap: { value: null }, | |
sheen: { value: new Color( 0x000000 ) }, | |
transparency: { value: 0 }, | |
} | |
] ), | |
vertexShader: ShaderChunk.meshphysical_vert, | |
fragmentShader: ShaderChunk.meshphysical_frag | |
}; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { | |
var clearColor = new Color( 0x000000 ); | |
var clearAlpha = 0; | |
var planeMesh; | |
var boxMesh; | |
var currentBackground = null; | |
var currentBackgroundVersion = 0; | |
var currentTonemapping = null; | |
function render( renderList, scene, camera, forceClear ) { | |
var background = scene.background; | |
// Ignore background in AR | |
// TODO: Reconsider this. | |
var xr = renderer.xr; | |
var session = xr.getSession && xr.getSession(); | |
if ( session && session.environmentBlendMode === 'additive' ) { | |
background = null; | |
} | |
if ( background === null ) { | |
setClear( clearColor, clearAlpha ); | |
} else if ( background && background.isColor ) { | |
setClear( background, 1 ); | |
forceClear = true; | |
} | |
if ( renderer.autoClear || forceClear ) { | |
renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil ); | |
} | |
if ( background && ( background.isCubeTexture || background.isWebGLCubeRenderTarget || background.mapping === CubeUVReflectionMapping ) ) { | |
if ( boxMesh === undefined ) { | |
boxMesh = new Mesh( | |
new BoxBufferGeometry( 1, 1, 1 ), | |
new ShaderMaterial( { | |
type: 'BackgroundCubeMaterial', | |
uniforms: cloneUniforms( ShaderLib.cube.uniforms ), | |
vertexShader: ShaderLib.cube.vertexShader, | |
fragmentShader: ShaderLib.cube.fragmentShader, | |
side: BackSide, | |
depthTest: false, | |
depthWrite: false, | |
fog: false | |
} ) | |
); | |
boxMesh.geometry.deleteAttribute( 'normal' ); | |
boxMesh.geometry.deleteAttribute( 'uv' ); | |
boxMesh.onBeforeRender = function ( renderer, scene, camera ) { | |
this.matrixWorld.copyPosition( camera.matrixWorld ); | |
}; | |
// enable code injection for non-built-in material | |
Object.defineProperty( boxMesh.material, 'envMap', { | |
get: function () { | |
return this.uniforms.envMap.value; | |
} | |
} ); | |
objects.update( boxMesh ); | |
} | |
var texture = background.isWebGLCubeRenderTarget ? background.texture : background; | |
boxMesh.material.uniforms.envMap.value = texture; | |
boxMesh.material.uniforms.flipEnvMap.value = texture.isCubeTexture ? - 1 : 1; | |
if ( currentBackground !== background || | |
currentBackgroundVersion !== texture.version || | |
currentTonemapping !== renderer.toneMapping ) { | |
boxMesh.material.needsUpdate = true; | |
currentBackground = background; | |
currentBackgroundVersion = texture.version; | |
currentTonemapping = renderer.toneMapping; | |
} | |
// push to the pre-sorted opaque render list | |
renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null ); | |
} else if ( background && background.isTexture ) { | |
if ( planeMesh === undefined ) { | |
planeMesh = new Mesh( | |
new PlaneBufferGeometry( 2, 2 ), | |
new ShaderMaterial( { | |
type: 'BackgroundMaterial', | |
uniforms: cloneUniforms( ShaderLib.background.uniforms ), | |
vertexShader: ShaderLib.background.vertexShader, | |
fragmentShader: ShaderLib.background.fragmentShader, | |
side: FrontSide, | |
depthTest: false, | |
depthWrite: false, | |
fog: false | |
} ) | |
); | |
planeMesh.geometry.deleteAttribute( 'normal' ); | |
// enable code injection for non-built-in material | |
Object.defineProperty( planeMesh.material, 'map', { | |
get: function () { | |
return this.uniforms.t2D.value; | |
} | |
} ); | |
objects.update( planeMesh ); | |
} | |
planeMesh.material.uniforms.t2D.value = background; | |
if ( background.matrixAutoUpdate === true ) { | |
background.updateMatrix(); | |
} | |
planeMesh.material.uniforms.uvTransform.value.copy( background.matrix ); | |
if ( currentBackground !== background || | |
currentBackgroundVersion !== background.version || | |
currentTonemapping !== renderer.toneMapping ) { | |
planeMesh.material.needsUpdate = true; | |
currentBackground = background; | |
currentBackgroundVersion = background.version; | |
currentTonemapping = renderer.toneMapping; | |
} | |
// push to the pre-sorted opaque render list | |
renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null ); | |
} | |
} | |
function setClear( color, alpha ) { | |
state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha ); | |
} | |
return { | |
getClearColor: function () { | |
return clearColor; | |
}, | |
setClearColor: function ( color, alpha ) { | |
clearColor.set( color ); | |
clearAlpha = alpha !== undefined ? alpha : 1; | |
setClear( clearColor, clearAlpha ); | |
}, | |
getClearAlpha: function () { | |
return clearAlpha; | |
}, | |
setClearAlpha: function ( alpha ) { | |
clearAlpha = alpha; | |
setClear( clearColor, clearAlpha ); | |
}, | |
render: render | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLBufferRenderer( gl, extensions, info, capabilities ) { | |
var isWebGL2 = capabilities.isWebGL2; | |
var mode; | |
function setMode( value ) { | |
mode = value; | |
} | |
function render( start, count ) { | |
gl.drawArrays( mode, start, count ); | |
info.update( count, mode ); | |
} | |
function renderInstances( geometry, start, count, primcount ) { | |
if ( primcount === 0 ) { return; } | |
var extension, methodName; | |
if ( isWebGL2 ) { | |
extension = gl; | |
methodName = 'drawArraysInstanced'; | |
} else { | |
extension = extensions.get( 'ANGLE_instanced_arrays' ); | |
methodName = 'drawArraysInstancedANGLE'; | |
if ( extension === null ) { | |
console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); | |
return; | |
} | |
} | |
extension[ methodName ]( mode, start, count, primcount ); | |
info.update( count, mode, primcount ); | |
} | |
// | |
this.setMode = setMode; | |
this.render = render; | |
this.renderInstances = renderInstances; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLCapabilities( gl, extensions, parameters ) { | |
var maxAnisotropy; | |
function getMaxAnisotropy() { | |
if ( maxAnisotropy !== undefined ) { return maxAnisotropy; } | |
var extension = extensions.get( 'EXT_texture_filter_anisotropic' ); | |
if ( extension !== null ) { | |
maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT ); | |
} else { | |
maxAnisotropy = 0; | |
} | |
return maxAnisotropy; | |
} | |
function getMaxPrecision( precision ) { | |
if ( precision === 'highp' ) { | |
if ( gl.getShaderPrecisionFormat( 35633, 36338 ).precision > 0 && | |
gl.getShaderPrecisionFormat( 35632, 36338 ).precision > 0 ) { | |
return 'highp'; | |
} | |
precision = 'mediump'; | |
} | |
if ( precision === 'mediump' ) { | |
if ( gl.getShaderPrecisionFormat( 35633, 36337 ).precision > 0 && | |
gl.getShaderPrecisionFormat( 35632, 36337 ).precision > 0 ) { | |
return 'mediump'; | |
} | |
} | |
return 'lowp'; | |
} | |
/* eslint-disable no-undef */ | |
var isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext ) || | |
( typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext ); | |
/* eslint-enable no-undef */ | |
var precision = parameters.precision !== undefined ? parameters.precision : 'highp'; | |
var maxPrecision = getMaxPrecision( precision ); | |
if ( maxPrecision !== precision ) { | |
console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' ); | |
precision = maxPrecision; | |
} | |
var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; | |
var maxTextures = gl.getParameter( 34930 ); | |
var maxVertexTextures = gl.getParameter( 35660 ); | |
var maxTextureSize = gl.getParameter( 3379 ); | |
var maxCubemapSize = gl.getParameter( 34076 ); | |
var maxAttributes = gl.getParameter( 34921 ); | |
var maxVertexUniforms = gl.getParameter( 36347 ); | |
var maxVaryings = gl.getParameter( 36348 ); | |
var maxFragmentUniforms = gl.getParameter( 36349 ); | |
var vertexTextures = maxVertexTextures > 0; | |
var floatFragmentTextures = isWebGL2 || !! extensions.get( 'OES_texture_float' ); | |
var floatVertexTextures = vertexTextures && floatFragmentTextures; | |
var maxSamples = isWebGL2 ? gl.getParameter( 36183 ) : 0; | |
return { | |
isWebGL2: isWebGL2, | |
getMaxAnisotropy: getMaxAnisotropy, | |
getMaxPrecision: getMaxPrecision, | |
precision: precision, | |
logarithmicDepthBuffer: logarithmicDepthBuffer, | |
maxTextures: maxTextures, | |
maxVertexTextures: maxVertexTextures, | |
maxTextureSize: maxTextureSize, | |
maxCubemapSize: maxCubemapSize, | |
maxAttributes: maxAttributes, | |
maxVertexUniforms: maxVertexUniforms, | |
maxVaryings: maxVaryings, | |
maxFragmentUniforms: maxFragmentUniforms, | |
vertexTextures: vertexTextures, | |
floatFragmentTextures: floatFragmentTextures, | |
floatVertexTextures: floatVertexTextures, | |
maxSamples: maxSamples | |
}; | |
} | |
/** | |
* @author tschw | |
*/ | |
function WebGLClipping() { | |
var scope = this, | |
globalState = null, | |
numGlobalPlanes = 0, | |
localClippingEnabled = false, | |
renderingShadows = false, | |
plane = new Plane(), | |
viewNormalMatrix = new Matrix3(), | |
uniform = { value: null, needsUpdate: false }; | |
this.uniform = uniform; | |
this.numPlanes = 0; | |
this.numIntersection = 0; | |
this.init = function ( planes, enableLocalClipping, camera ) { | |
var enabled = | |
planes.length !== 0 || | |
enableLocalClipping || | |
// enable state of previous frame - the clipping code has to | |
// run another frame in order to reset the state: | |
numGlobalPlanes !== 0 || | |
localClippingEnabled; | |
localClippingEnabled = enableLocalClipping; | |
globalState = projectPlanes( planes, camera, 0 ); | |
numGlobalPlanes = planes.length; | |
return enabled; | |
}; | |
this.beginShadows = function () { | |
renderingShadows = true; | |
projectPlanes( null ); | |
}; | |
this.endShadows = function () { | |
renderingShadows = false; | |
resetGlobalState(); | |
}; | |
this.setState = function ( planes, clipIntersection, clipShadows, camera, cache, fromCache ) { | |
if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) { | |
// there's no local clipping | |
if ( renderingShadows ) { | |
// there's no global clipping | |
projectPlanes( null ); | |
} else { | |
resetGlobalState(); | |
} | |
} else { | |
var nGlobal = renderingShadows ? 0 : numGlobalPlanes, | |
lGlobal = nGlobal * 4, | |
dstArray = cache.clippingState || null; | |
uniform.value = dstArray; // ensure unique state | |
dstArray = projectPlanes( planes, camera, lGlobal, fromCache ); | |
for ( var i = 0; i !== lGlobal; ++ i ) { | |
dstArray[ i ] = globalState[ i ]; | |
} | |
cache.clippingState = dstArray; | |
this.numIntersection = clipIntersection ? this.numPlanes : 0; | |
this.numPlanes += nGlobal; | |
} | |
}; | |
function resetGlobalState() { | |
if ( uniform.value !== globalState ) { | |
uniform.value = globalState; | |
uniform.needsUpdate = numGlobalPlanes > 0; | |
} | |
scope.numPlanes = numGlobalPlanes; | |
scope.numIntersection = 0; | |
} | |
function projectPlanes( planes, camera, dstOffset, skipTransform ) { | |
var nPlanes = planes !== null ? planes.length : 0, | |
dstArray = null; | |
if ( nPlanes !== 0 ) { | |
dstArray = uniform.value; | |
if ( skipTransform !== true || dstArray === null ) { | |
var flatSize = dstOffset + nPlanes * 4, | |
viewMatrix = camera.matrixWorldInverse; | |
viewNormalMatrix.getNormalMatrix( viewMatrix ); | |
if ( dstArray === null || dstArray.length < flatSize ) { | |
dstArray = new Float32Array( flatSize ); | |
} | |
for ( var i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) { | |
plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix ); | |
plane.normal.toArray( dstArray, i4 ); | |
dstArray[ i4 + 3 ] = plane.constant; | |
} | |
} | |
uniform.value = dstArray; | |
uniform.needsUpdate = true; | |
} | |
scope.numPlanes = nPlanes; | |
scope.numIntersection = 0; | |
return dstArray; | |
} | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLExtensions( gl ) { | |
var extensions = {}; | |
return { | |
get: function ( name ) { | |
if ( extensions[ name ] !== undefined ) { | |
return extensions[ name ]; | |
} | |
var extension; | |
switch ( name ) { | |
case 'WEBGL_depth_texture': | |
extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' ); | |
break; | |
case 'EXT_texture_filter_anisotropic': | |
extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' ); | |
break; | |
case 'WEBGL_compressed_texture_s3tc': | |
extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' ); | |
break; | |
case 'WEBGL_compressed_texture_pvrtc': | |
extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ); | |
break; | |
default: | |
extension = gl.getExtension( name ); | |
} | |
if ( extension === null ) { | |
console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' ); | |
} | |
extensions[ name ] = extension; | |
return extension; | |
} | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLGeometries( gl, attributes, info ) { | |
var geometries = new WeakMap(); | |
var wireframeAttributes = new WeakMap(); | |
function onGeometryDispose( event ) { | |
var geometry = event.target; | |
var buffergeometry = geometries.get( geometry ); | |
if ( buffergeometry.index !== null ) { | |
attributes.remove( buffergeometry.index ); | |
} | |
for ( var name in buffergeometry.attributes ) { | |
attributes.remove( buffergeometry.attributes[ name ] ); | |
} | |
geometry.removeEventListener( 'dispose', onGeometryDispose ); | |
geometries.delete( geometry ); | |
var attribute = wireframeAttributes.get( buffergeometry ); | |
if ( attribute ) { | |
attributes.remove( attribute ); | |
wireframeAttributes.delete( buffergeometry ); | |
} | |
// | |
info.memory.geometries --; | |
} | |
function get( object, geometry ) { | |
var buffergeometry = geometries.get( geometry ); | |
if ( buffergeometry ) { return buffergeometry; } | |
geometry.addEventListener( 'dispose', onGeometryDispose ); | |
if ( geometry.isBufferGeometry ) { | |
buffergeometry = geometry; | |
} else if ( geometry.isGeometry ) { | |
if ( geometry._bufferGeometry === undefined ) { | |
geometry._bufferGeometry = new BufferGeometry().setFromObject( object ); | |
} | |
buffergeometry = geometry._bufferGeometry; | |
} | |
geometries.set( geometry, buffergeometry ); | |
info.memory.geometries ++; | |
return buffergeometry; | |
} | |
function update( geometry ) { | |
var index = geometry.index; | |
var geometryAttributes = geometry.attributes; | |
if ( index !== null ) { | |
attributes.update( index, 34963 ); | |
} | |
for ( var name in geometryAttributes ) { | |
attributes.update( geometryAttributes[ name ], 34962 ); | |
} | |
// morph targets | |
var morphAttributes = geometry.morphAttributes; | |
for ( var name in morphAttributes ) { | |
var array = morphAttributes[ name ]; | |
for ( var i = 0, l = array.length; i < l; i ++ ) { | |
attributes.update( array[ i ], 34962 ); | |
} | |
} | |
} | |
function updateWireframeAttribute( geometry ) { | |
var indices = []; | |
var geometryIndex = geometry.index; | |
var geometryPosition = geometry.attributes.position; | |
var version = 0; | |
if ( geometryIndex !== null ) { | |
var array = geometryIndex.array; | |
version = geometryIndex.version; | |
for ( var i = 0, l = array.length; i < l; i += 3 ) { | |
var a = array[ i + 0 ]; | |
var b = array[ i + 1 ]; | |
var c = array[ i + 2 ]; | |
indices.push( a, b, b, c, c, a ); | |
} | |
} else { | |
var array = geometryPosition.array; | |
version = geometryPosition.version; | |
for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) { | |
var a = i + 0; | |
var b = i + 1; | |
var c = i + 2; | |
indices.push( a, b, b, c, c, a ); | |
} | |
} | |
var attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 ); | |
attribute.version = version; | |
attributes.update( attribute, 34963 ); | |
// | |
var previousAttribute = wireframeAttributes.get( geometry ); | |
if ( previousAttribute ) { attributes.remove( previousAttribute ); } | |
// | |
wireframeAttributes.set( geometry, attribute ); | |
} | |
function getWireframeAttribute( geometry ) { | |
var currentAttribute = wireframeAttributes.get( geometry ); | |
if ( currentAttribute ) { | |
var geometryIndex = geometry.index; | |
if ( geometryIndex !== null ) { | |
// if the attribute is obsolete, create a new one | |
if ( currentAttribute.version < geometryIndex.version ) { | |
updateWireframeAttribute( geometry ); | |
} | |
} | |
} else { | |
updateWireframeAttribute( geometry ); | |
} | |
return wireframeAttributes.get( geometry ); | |
} | |
return { | |
get: get, | |
update: update, | |
getWireframeAttribute: getWireframeAttribute | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) { | |
var isWebGL2 = capabilities.isWebGL2; | |
var mode; | |
function setMode( value ) { | |
mode = value; | |
} | |
var type, bytesPerElement; | |
function setIndex( value ) { | |
type = value.type; | |
bytesPerElement = value.bytesPerElement; | |
} | |
function render( start, count ) { | |
gl.drawElements( mode, count, type, start * bytesPerElement ); | |
info.update( count, mode ); | |
} | |
function renderInstances( geometry, start, count, primcount ) { | |
if ( primcount === 0 ) { return; } | |
var extension, methodName; | |
if ( isWebGL2 ) { | |
extension = gl; | |
methodName = 'drawElementsInstanced'; | |
} else { | |
extension = extensions.get( 'ANGLE_instanced_arrays' ); | |
methodName = 'drawElementsInstancedANGLE'; | |
if ( extension === null ) { | |
console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); | |
return; | |
} | |
} | |
extension[ methodName ]( mode, count, type, start * bytesPerElement, primcount ); | |
info.update( count, mode, primcount ); | |
} | |
// | |
this.setMode = setMode; | |
this.setIndex = setIndex; | |
this.render = render; | |
this.renderInstances = renderInstances; | |
} | |
/** | |
* @author Mugen87 / https://github.com/Mugen87 | |
*/ | |
function WebGLInfo( gl ) { | |
var memory = { | |
geometries: 0, | |
textures: 0 | |
}; | |
var render = { | |
frame: 0, | |
calls: 0, | |
triangles: 0, | |
points: 0, | |
lines: 0 | |
}; | |
function update( count, mode, instanceCount ) { | |
instanceCount = instanceCount || 1; | |
render.calls ++; | |
switch ( mode ) { | |
case 4: | |
render.triangles += instanceCount * ( count / 3 ); | |
break; | |
case 1: | |
render.lines += instanceCount * ( count / 2 ); | |
break; | |
case 3: | |
render.lines += instanceCount * ( count - 1 ); | |
break; | |
case 2: | |
render.lines += instanceCount * count; | |
break; | |
case 0: | |
render.points += instanceCount * count; | |
break; | |
default: | |
console.error( 'THREE.WebGLInfo: Unknown draw mode:', mode ); | |
break; | |
} | |
} | |
function reset() { | |
render.frame ++; | |
render.calls = 0; | |
render.triangles = 0; | |
render.points = 0; | |
render.lines = 0; | |
} | |
return { | |
memory: memory, | |
render: render, | |
programs: null, | |
autoReset: true, | |
reset: reset, | |
update: update | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function absNumericalSort( a, b ) { | |
return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] ); | |
} | |
function WebGLMorphtargets( gl ) { | |
var influencesList = {}; | |
var morphInfluences = new Float32Array( 8 ); | |
function update( object, geometry, material, program ) { | |
var objectInfluences = object.morphTargetInfluences; | |
// When object doesn't have morph target influences defined, we treat it as a 0-length array | |
// This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences | |
var length = objectInfluences === undefined ? 0 : objectInfluences.length; | |
var influences = influencesList[ geometry.id ]; | |
if ( influences === undefined ) { | |
// initialise list | |
influences = []; | |
for ( var i = 0; i < length; i ++ ) { | |
influences[ i ] = [ i, 0 ]; | |
} | |
influencesList[ geometry.id ] = influences; | |
} | |
var morphTargets = material.morphTargets && geometry.morphAttributes.position; | |
var morphNormals = material.morphNormals && geometry.morphAttributes.normal; | |
// Remove current morphAttributes | |
for ( var i = 0; i < length; i ++ ) { | |
var influence = influences[ i ]; | |
if ( influence[ 1 ] !== 0 ) { | |
if ( morphTargets ) { geometry.deleteAttribute( 'morphTarget' + i ); } | |
if ( morphNormals ) { geometry.deleteAttribute( 'morphNormal' + i ); } | |
} | |
} | |
// Collect influences | |
for ( var i = 0; i < length; i ++ ) { | |
var influence = influences[ i ]; | |
influence[ 0 ] = i; | |
influence[ 1 ] = objectInfluences[ i ]; | |
} | |
influences.sort( absNumericalSort ); | |
// Add morphAttributes | |
var morphInfluencesSum = 0; | |
for ( var i = 0; i < 8; i ++ ) { | |
var influence = influences[ i ]; | |
if ( influence ) { | |
var index = influence[ 0 ]; | |
var value = influence[ 1 ]; | |
if ( value ) { | |
if ( morphTargets ) { geometry.setAttribute( 'morphTarget' + i, morphTargets[ index ] ); } | |
if ( morphNormals ) { geometry.setAttribute( 'morphNormal' + i, morphNormals[ index ] ); } | |
morphInfluences[ i ] = value; | |
morphInfluencesSum += value; | |
continue; | |
} | |
} | |
morphInfluences[ i ] = 0; | |
} | |
// GLSL shader uses formula baseinfluence * base + sum(target * influence) | |
// This allows us to switch between absolute morphs and relative morphs without changing shader code | |
// When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence) | |
var morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; | |
program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence ); | |
program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences ); | |
} | |
return { | |
update: update | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLObjects( gl, geometries, attributes, info ) { | |
var updateMap = new WeakMap(); | |
function update( object ) { | |
var frame = info.render.frame; | |
var geometry = object.geometry; | |
var buffergeometry = geometries.get( object, geometry ); | |
// Update once per frame | |
if ( updateMap.get( buffergeometry ) !== frame ) { | |
if ( geometry.isGeometry ) { | |
buffergeometry.updateFromObject( object ); | |
} | |
geometries.update( buffergeometry ); | |
updateMap.set( buffergeometry, frame ); | |
} | |
if ( object.isInstancedMesh ) { | |
attributes.update( object.instanceMatrix, 34962 ); | |
} | |
return buffergeometry; | |
} | |
function dispose() { | |
updateMap = new WeakMap(); | |
} | |
return { | |
update: update, | |
dispose: dispose | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { | |
images = images !== undefined ? images : []; | |
mapping = mapping !== undefined ? mapping : CubeReflectionMapping; | |
format = format !== undefined ? format : RGBFormat; | |
Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); | |
this.flipY = false; | |
} | |
CubeTexture.prototype = Object.create( Texture.prototype ); | |
CubeTexture.prototype.constructor = CubeTexture; | |
CubeTexture.prototype.isCubeTexture = true; | |
Object.defineProperty( CubeTexture.prototype, 'images', { | |
get: function () { | |
return this.image; | |
}, | |
set: function ( value ) { | |
this.image = value; | |
} | |
} ); | |
/** | |
* @author Takahiro https://github.com/takahirox | |
*/ | |
function DataTexture2DArray( data, width, height, depth ) { | |
Texture.call( this, null ); | |
this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 }; | |
this.magFilter = NearestFilter; | |
this.minFilter = NearestFilter; | |
this.wrapR = ClampToEdgeWrapping; | |
this.generateMipmaps = false; | |
this.flipY = false; | |
this.needsUpdate = true; | |
} | |
DataTexture2DArray.prototype = Object.create( Texture.prototype ); | |
DataTexture2DArray.prototype.constructor = DataTexture2DArray; | |
DataTexture2DArray.prototype.isDataTexture2DArray = true; | |
/** | |
* @author Artur Trzesiok | |
*/ | |
function DataTexture3D( data, width, height, depth ) { | |
// We're going to add .setXXX() methods for setting properties later. | |
// Users can still set in DataTexture3D directly. | |
// | |
// var texture = new THREE.DataTexture3D( data, width, height, depth ); | |
// texture.anisotropy = 16; | |
// | |
// See #14839 | |
Texture.call( this, null ); | |
this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 }; | |
this.magFilter = NearestFilter; | |
this.minFilter = NearestFilter; | |
this.wrapR = ClampToEdgeWrapping; | |
this.generateMipmaps = false; | |
this.flipY = false; | |
this.needsUpdate = true; | |
} | |
DataTexture3D.prototype = Object.create( Texture.prototype ); | |
DataTexture3D.prototype.constructor = DataTexture3D; | |
DataTexture3D.prototype.isDataTexture3D = true; | |
/** | |
* @author tschw | |
* @author Mugen87 / https://github.com/Mugen87 | |
* @author mrdoob / http://mrdoob.com/ | |
* | |
* Uniforms of a program. | |
* Those form a tree structure with a special top-level container for the root, | |
* which you get by calling 'new WebGLUniforms( gl, program )'. | |
* | |
* | |
* Properties of inner nodes including the top-level container: | |
* | |
* .seq - array of nested uniforms | |
* .map - nested uniforms by name | |
* | |
* | |
* Methods of all nodes except the top-level container: | |
* | |
* .setValue( gl, value, [textures] ) | |
* | |
* uploads a uniform value(s) | |
* the 'textures' parameter is needed for sampler uniforms | |
* | |
* | |
* Static methods of the top-level container (textures factorizations): | |
* | |
* .upload( gl, seq, values, textures ) | |
* | |
* sets uniforms in 'seq' to 'values[id].value' | |
* | |
* .seqWithValue( seq, values ) : filteredSeq | |
* | |
* filters 'seq' entries with corresponding entry in values | |
* | |
* | |
* Methods of the top-level container (textures factorizations): | |
* | |
* .setValue( gl, name, value, textures ) | |
* | |
* sets uniform with name 'name' to 'value' | |
* | |
* .setOptional( gl, obj, prop ) | |
* | |
* like .set for an optional property of the object | |
* | |
*/ | |
var emptyTexture = new Texture(); | |
var emptyTexture2dArray = new DataTexture2DArray(); | |
var emptyTexture3d = new DataTexture3D(); | |
var emptyCubeTexture = new CubeTexture(); | |
// --- Utilities --- | |
// Array Caches (provide typed arrays for temporary by size) | |
var arrayCacheF32 = []; | |
var arrayCacheI32 = []; | |
// Float32Array caches used for uploading Matrix uniforms | |
var mat4array = new Float32Array( 16 ); | |
var mat3array = new Float32Array( 9 ); | |
var mat2array = new Float32Array( 4 ); | |
// Flattening for arrays of vectors and matrices | |
function flatten( array, nBlocks, blockSize ) { | |
var firstElem = array[ 0 ]; | |
if ( firstElem <= 0 || firstElem > 0 ) { return array; } | |
// unoptimized: ! isNaN( firstElem ) | |
// see http://jacksondunstan.com/articles/983 | |
var n = nBlocks * blockSize, | |
r = arrayCacheF32[ n ]; | |
if ( r === undefined ) { | |
r = new Float32Array( n ); | |
arrayCacheF32[ n ] = r; | |
} | |
if ( nBlocks !== 0 ) { | |
firstElem.toArray( r, 0 ); | |
for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) { | |
offset += blockSize; | |
array[ i ].toArray( r, offset ); | |
} | |
} | |
return r; | |
} | |
function arraysEqual( a, b ) { | |
if ( a.length !== b.length ) { return false; } | |
for ( var i = 0, l = a.length; i < l; i ++ ) { | |
if ( a[ i ] !== b[ i ] ) { return false; } | |
} | |
return true; | |
} | |
function copyArray( a, b ) { | |
for ( var i = 0, l = b.length; i < l; i ++ ) { | |
a[ i ] = b[ i ]; | |
} | |
} | |
// Texture unit allocation | |
function allocTexUnits( textures, n ) { | |
var r = arrayCacheI32[ n ]; | |
if ( r === undefined ) { | |
r = new Int32Array( n ); | |
arrayCacheI32[ n ] = r; | |
} | |
for ( var i = 0; i !== n; ++ i ) | |
{ r[ i ] = textures.allocateTextureUnit(); } | |
return r; | |
} | |
// --- Setters --- | |
// Note: Defining these methods externally, because they come in a bunch | |
// and this way their names minify. | |
// Single scalar | |
function setValueV1f( gl, v ) { | |
var cache = this.cache; | |
if ( cache[ 0 ] === v ) { return; } | |
gl.uniform1f( this.addr, v ); | |
cache[ 0 ] = v; | |
} | |
// Single float vector (from flat array or THREE.VectorN) | |
function setValueV2f( gl, v ) { | |
var cache = this.cache; | |
if ( v.x !== undefined ) { | |
if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) { | |
gl.uniform2f( this.addr, v.x, v.y ); | |
cache[ 0 ] = v.x; | |
cache[ 1 ] = v.y; | |
} | |
} else { | |
if ( arraysEqual( cache, v ) ) { return; } | |
gl.uniform2fv( this.addr, v ); | |
copyArray( cache, v ); | |
} | |
} | |
function setValueV3f( gl, v ) { | |
var cache = this.cache; | |
if ( v.x !== undefined ) { | |
if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) { | |
gl.uniform3f( this.addr, v.x, v.y, v.z ); | |
cache[ 0 ] = v.x; | |
cache[ 1 ] = v.y; | |
cache[ 2 ] = v.z; | |
} | |
} else if ( v.r !== undefined ) { | |
if ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) { | |
gl.uniform3f( this.addr, v.r, v.g, v.b ); | |
cache[ 0 ] = v.r; | |
cache[ 1 ] = v.g; | |
cache[ 2 ] = v.b; | |
} | |
} else { | |
if ( arraysEqual( cache, v ) ) { return; } | |
gl.uniform3fv( this.addr, v ); | |
copyArray( cache, v ); | |
} | |
} | |
function setValueV4f( gl, v ) { | |
var cache = this.cache; | |
if ( v.x !== undefined ) { | |
if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) { | |
gl.uniform4f( this.addr, v.x, v.y, v.z, v.w ); | |
cache[ 0 ] = v.x; | |
cache[ 1 ] = v.y; | |
cache[ 2 ] = v.z; | |
cache[ 3 ] = v.w; | |
} | |
} else { | |
if ( arraysEqual( cache, v ) ) { return; } | |
gl.uniform4fv( this.addr, v ); | |
copyArray( cache, v ); | |
} | |
} | |
// Single matrix (from flat array or MatrixN) | |
function setValueM2( gl, v ) { | |
var cache = this.cache; | |
var elements = v.elements; | |
if ( elements === undefined ) { | |
if ( arraysEqual( cache, v ) ) { return; } | |
gl.uniformMatrix2fv( this.addr, false, v ); | |
copyArray( cache, v ); | |
} else { | |
if ( arraysEqual( cache, elements ) ) { return; } | |
mat2array.set( elements ); | |
gl.uniformMatrix2fv( this.addr, false, mat2array ); | |
copyArray( cache, elements ); | |
} | |
} | |
function setValueM3( gl, v ) { | |
var cache = this.cache; | |
var elements = v.elements; | |
if ( elements === undefined ) { | |
if ( arraysEqual( cache, v ) ) { return; } | |
gl.uniformMatrix3fv( this.addr, false, v ); | |
copyArray( cache, v ); | |
} else { | |
if ( arraysEqual( cache, elements ) ) { return; } | |
mat3array.set( elements ); | |
gl.uniformMatrix3fv( this.addr, false, mat3array ); | |
copyArray( cache, elements ); | |
} | |
} | |
function setValueM4( gl, v ) { | |
var cache = this.cache; | |
var elements = v.elements; | |
if ( elements === undefined ) { | |
if ( arraysEqual( cache, v ) ) { return; } | |
gl.uniformMatrix4fv( this.addr, false, v ); | |
copyArray( cache, v ); | |
} else { | |
if ( arraysEqual( cache, elements ) ) { return; } | |
mat4array.set( elements ); | |
gl.uniformMatrix4fv( this.addr, false, mat4array ); | |
copyArray( cache, elements ); | |
} | |
} | |
// Single texture (2D / Cube) | |
function setValueT1( gl, v, textures ) { | |
var cache = this.cache; | |
var unit = textures.allocateTextureUnit(); | |
if ( cache[ 0 ] !== unit ) { | |
gl.uniform1i( this.addr, unit ); | |
cache[ 0 ] = unit; | |
} | |
textures.safeSetTexture2D( v || emptyTexture, unit ); | |
} | |
function setValueT2DArray1( gl, v, textures ) { | |
var cache = this.cache; | |
var unit = textures.allocateTextureUnit(); | |
if ( cache[ 0 ] !== unit ) { | |
gl.uniform1i( this.addr, unit ); | |
cache[ 0 ] = unit; | |
} | |
textures.setTexture2DArray( v || emptyTexture2dArray, unit ); | |
} | |
function setValueT3D1( gl, v, textures ) { | |
var cache = this.cache; | |
var unit = textures.allocateTextureUnit(); | |
if ( cache[ 0 ] !== unit ) { | |
gl.uniform1i( this.addr, unit ); | |
cache[ 0 ] = unit; | |
} | |
textures.setTexture3D( v || emptyTexture3d, unit ); | |
} | |
function setValueT6( gl, v, textures ) { | |
var cache = this.cache; | |
var unit = textures.allocateTextureUnit(); | |
if ( cache[ 0 ] !== unit ) { | |
gl.uniform1i( this.addr, unit ); | |
cache[ 0 ] = unit; | |
} | |
textures.safeSetTextureCube( v || emptyCubeTexture, unit ); | |
} | |
// Integer / Boolean vectors or arrays thereof (always flat arrays) | |
function setValueV1i( gl, v ) { | |
var cache = this.cache; | |
if ( cache[ 0 ] === v ) { return; } | |
gl.uniform1i( this.addr, v ); | |
cache[ 0 ] = v; | |
} | |
function setValueV2i( gl, v ) { | |
var cache = this.cache; | |
if ( arraysEqual( cache, v ) ) { return; } | |
gl.uniform2iv( this.addr, v ); | |
copyArray( cache, v ); | |
} | |
function setValueV3i( gl, v ) { | |
var cache = this.cache; | |
if ( arraysEqual( cache, v ) ) { return; } | |
gl.uniform3iv( this.addr, v ); | |
copyArray( cache, v ); | |
} | |
function setValueV4i( gl, v ) { | |
var cache = this.cache; | |
if ( arraysEqual( cache, v ) ) { return; } | |
gl.uniform4iv( this.addr, v ); | |
copyArray( cache, v ); | |
} | |
// uint | |
function setValueV1ui( gl, v ) { | |
var cache = this.cache; | |
if ( cache[ 0 ] === v ) { return; } | |
gl.uniform1ui( this.addr, v ); | |
cache[ 0 ] = v; | |
} | |
// Helper to pick the right setter for the singular case | |
function getSingularSetter( type ) { | |
switch ( type ) { | |
case 0x1406: return setValueV1f; // FLOAT | |
case 0x8b50: return setValueV2f; // _VEC2 | |
case 0x8b51: return setValueV3f; // _VEC3 | |
case 0x8b52: return setValueV4f; // _VEC4 | |
case 0x8b5a: return setValueM2; // _MAT2 | |
case 0x8b5b: return setValueM3; // _MAT3 | |
case 0x8b5c: return setValueM4; // _MAT4 | |
case 0x1404: case 0x8b56: return setValueV1i; // INT, BOOL | |
case 0x8b53: case 0x8b57: return setValueV2i; // _VEC2 | |
case 0x8b54: case 0x8b58: return setValueV3i; // _VEC3 | |
case 0x8b55: case 0x8b59: return setValueV4i; // _VEC4 | |
case 0x1405: return setValueV1ui; // UINT | |
case 0x8b5e: // SAMPLER_2D | |
case 0x8d66: // SAMPLER_EXTERNAL_OES | |
case 0x8dca: // INT_SAMPLER_2D | |
case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D | |
case 0x8b62: // SAMPLER_2D_SHADOW | |
return setValueT1; | |
case 0x8b5f: // SAMPLER_3D | |
case 0x8dcb: // INT_SAMPLER_3D | |
case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D | |
return setValueT3D1; | |
case 0x8b60: // SAMPLER_CUBE | |
case 0x8dcc: // INT_SAMPLER_CUBE | |
case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE | |
case 0x8dc5: // SAMPLER_CUBE_SHADOW | |
return setValueT6; | |
case 0x8dc1: // SAMPLER_2D_ARRAY | |
case 0x8dcf: // INT_SAMPLER_2D_ARRAY | |
case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY | |
case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW | |
return setValueT2DArray1; | |
} | |
} | |
// Array of scalars | |
function setValueV1fArray( gl, v ) { | |
gl.uniform1fv( this.addr, v ); | |
} | |
// Integer / Boolean vectors or arrays thereof (always flat arrays) | |
function setValueV1iArray( gl, v ) { | |
gl.uniform1iv( this.addr, v ); | |
} | |
function setValueV2iArray( gl, v ) { | |
gl.uniform2iv( this.addr, v ); | |
} | |
function setValueV3iArray( gl, v ) { | |
gl.uniform3iv( this.addr, v ); | |
} | |
function setValueV4iArray( gl, v ) { | |
gl.uniform4iv( this.addr, v ); | |
} | |
// Array of vectors (flat or from THREE classes) | |
function setValueV2fArray( gl, v ) { | |
var data = flatten( v, this.size, 2 ); | |
gl.uniform2fv( this.addr, data ); | |
} | |
function setValueV3fArray( gl, v ) { | |
var data = flatten( v, this.size, 3 ); | |
gl.uniform3fv( this.addr, data ); | |
} | |
function setValueV4fArray( gl, v ) { | |
var data = flatten( v, this.size, 4 ); | |
gl.uniform4fv( this.addr, data ); | |
} | |
// Array of matrices (flat or from THREE clases) | |
function setValueM2Array( gl, v ) { | |
var data = flatten( v, this.size, 4 ); | |
gl.uniformMatrix2fv( this.addr, false, data ); | |
} | |
function setValueM3Array( gl, v ) { | |
var data = flatten( v, this.size, 9 ); | |
gl.uniformMatrix3fv( this.addr, false, data ); | |
} | |
function setValueM4Array( gl, v ) { | |
var data = flatten( v, this.size, 16 ); | |
gl.uniformMatrix4fv( this.addr, false, data ); | |
} | |
// Array of textures (2D / Cube) | |
function setValueT1Array( gl, v, textures ) { | |
var n = v.length; | |
var units = allocTexUnits( textures, n ); | |
gl.uniform1iv( this.addr, units ); | |
for ( var i = 0; i !== n; ++ i ) { | |
textures.safeSetTexture2D( v[ i ] || emptyTexture, units[ i ] ); | |
} | |
} | |
function setValueT6Array( gl, v, textures ) { | |
var n = v.length; | |
var units = allocTexUnits( textures, n ); | |
gl.uniform1iv( this.addr, units ); | |
for ( var i = 0; i !== n; ++ i ) { | |
textures.safeSetTextureCube( v[ i ] || emptyCubeTexture, units[ i ] ); | |
} | |
} | |
// Helper to pick the right setter for a pure (bottom-level) array | |
function getPureArraySetter( type ) { | |
switch ( type ) { | |
case 0x1406: return setValueV1fArray; // FLOAT | |
case 0x8b50: return setValueV2fArray; // _VEC2 | |
case 0x8b51: return setValueV3fArray; // _VEC3 | |
case 0x8b52: return setValueV4fArray; // _VEC4 | |
case 0x8b5a: return setValueM2Array; // _MAT2 | |
case 0x8b5b: return setValueM3Array; // _MAT3 | |
case 0x8b5c: return setValueM4Array; // _MAT4 | |
case 0x1404: case 0x8b56: return setValueV1iArray; // INT, BOOL | |
case 0x8b53: case 0x8b57: return setValueV2iArray; // _VEC2 | |
case 0x8b54: case 0x8b58: return setValueV3iArray; // _VEC3 | |
case 0x8b55: case 0x8b59: return setValueV4iArray; // _VEC4 | |
case 0x8b5e: // SAMPLER_2D | |
case 0x8d66: // SAMPLER_EXTERNAL_OES | |
case 0x8dca: // INT_SAMPLER_2D | |
case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D | |
case 0x8b62: // SAMPLER_2D_SHADOW | |
return setValueT1Array; | |
case 0x8b60: // SAMPLER_CUBE | |
case 0x8dcc: // INT_SAMPLER_CUBE | |
case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE | |
case 0x8dc5: // SAMPLER_CUBE_SHADOW | |
return setValueT6Array; | |
} | |
} | |
// --- Uniform Classes --- | |
function SingleUniform( id, activeInfo, addr ) { | |
this.id = id; | |
this.addr = addr; | |
this.cache = []; | |
this.setValue = getSingularSetter( activeInfo.type ); | |
// this.path = activeInfo.name; // DEBUG | |
} | |
function PureArrayUniform( id, activeInfo, addr ) { | |
this.id = id; | |
this.addr = addr; | |
this.cache = []; | |
this.size = activeInfo.size; | |
this.setValue = getPureArraySetter( activeInfo.type ); | |
// this.path = activeInfo.name; // DEBUG | |
} | |
PureArrayUniform.prototype.updateCache = function ( data ) { | |
var cache = this.cache; | |
if ( data instanceof Float32Array && cache.length !== data.length ) { | |
this.cache = new Float32Array( data.length ); | |
} | |
copyArray( cache, data ); | |
}; | |
function StructuredUniform( id ) { | |
this.id = id; | |
this.seq = []; | |
this.map = {}; | |
} | |
StructuredUniform.prototype.setValue = function ( gl, value, textures ) { | |
var seq = this.seq; | |
for ( var i = 0, n = seq.length; i !== n; ++ i ) { | |
var u = seq[ i ]; | |
u.setValue( gl, value[ u.id ], textures ); | |
} | |
}; | |
// --- Top-level --- | |
// Parser - builds up the property tree from the path strings | |
var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g; | |
// extracts | |
// - the identifier (member name or array index) | |
// - followed by an optional right bracket (found when array index) | |
// - followed by an optional left bracket or dot (type of subscript) | |
// | |
// Note: These portions can be read in a non-overlapping fashion and | |
// allow straightforward parsing of the hierarchy that WebGL encodes | |
// in the uniform names. | |
function addUniform( container, uniformObject ) { | |
container.seq.push( uniformObject ); | |
container.map[ uniformObject.id ] = uniformObject; | |
} | |
function parseUniform( activeInfo, addr, container ) { | |
var path = activeInfo.name, | |
pathLength = path.length; | |
// reset RegExp object, because of the early exit of a previous run | |
RePathPart.lastIndex = 0; | |
while ( true ) { | |
var match = RePathPart.exec( path ), | |
matchEnd = RePathPart.lastIndex, | |
id = match[ 1 ], | |
idIsIndex = match[ 2 ] === ']', | |
subscript = match[ 3 ]; | |
if ( idIsIndex ) { id = id | 0; } // convert to integer | |
if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) { | |
// bare name or "pure" bottom-level array "[0]" suffix | |
addUniform( container, subscript === undefined ? | |
new SingleUniform( id, activeInfo, addr ) : | |
new PureArrayUniform( id, activeInfo, addr ) ); | |
break; | |
} else { | |
// step into inner node / create it in case it doesn't exist | |
var map = container.map, next = map[ id ]; | |
if ( next === undefined ) { | |
next = new StructuredUniform( id ); | |
addUniform( container, next ); | |
} | |
container = next; | |
} | |
} | |
} | |
// Root Container | |
function WebGLUniforms( gl, program ) { | |
this.seq = []; | |
this.map = {}; | |
var n = gl.getProgramParameter( program, 35718 ); | |
for ( var i = 0; i < n; ++ i ) { | |
var info = gl.getActiveUniform( program, i ), | |
addr = gl.getUniformLocation( program, info.name ); | |
parseUniform( info, addr, this ); | |
} | |
} | |
WebGLUniforms.prototype.setValue = function ( gl, name, value, textures ) { | |
var u = this.map[ name ]; | |
if ( u !== undefined ) { u.setValue( gl, value, textures ); } | |
}; | |
WebGLUniforms.prototype.setOptional = function ( gl, object, name ) { | |
var v = object[ name ]; | |
if ( v !== undefined ) { this.setValue( gl, name, v ); } | |
}; | |
// Static interface | |
WebGLUniforms.upload = function ( gl, seq, values, textures ) { | |
for ( var i = 0, n = seq.length; i !== n; ++ i ) { | |
var u = seq[ i ], | |
v = values[ u.id ]; | |
if ( v.needsUpdate !== false ) { | |
// note: always updating when .needsUpdate is undefined | |
u.setValue( gl, v.value, textures ); | |
} | |
} | |
}; | |
WebGLUniforms.seqWithValue = function ( seq, values ) { | |
var r = []; | |
for ( var i = 0, n = seq.length; i !== n; ++ i ) { | |
var u = seq[ i ]; | |
if ( u.id in values ) { r.push( u ); } | |
} | |
return r; | |
}; | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLShader( gl, type, string ) { | |
var shader = gl.createShader( type ); | |
gl.shaderSource( shader, string ); | |
gl.compileShader( shader ); | |
return shader; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
var programIdCount = 0; | |
function addLineNumbers( string ) { | |
var lines = string.split( '\n' ); | |
for ( var i = 0; i < lines.length; i ++ ) { | |
lines[ i ] = ( i + 1 ) + ': ' + lines[ i ]; | |
} | |
return lines.join( '\n' ); | |
} | |
function getEncodingComponents( encoding ) { | |
switch ( encoding ) { | |
case LinearEncoding: | |
return [ 'Linear', '( value )' ]; | |
case sRGBEncoding: | |
return [ 'sRGB', '( value )' ]; | |
case RGBEEncoding: | |
return [ 'RGBE', '( value )' ]; | |
case RGBM7Encoding: | |
return [ 'RGBM', '( value, 7.0 )' ]; | |
case RGBM16Encoding: | |
return [ 'RGBM', '( value, 16.0 )' ]; | |
case RGBDEncoding: | |
return [ 'RGBD', '( value, 256.0 )' ]; | |
case GammaEncoding: | |
return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ]; | |
case LogLuvEncoding: | |
return [ 'LogLuv', '( value )' ]; | |
default: | |
throw new Error( 'unsupported encoding: ' + encoding ); | |
} | |
} | |
function getShaderErrors( gl, shader, type ) { | |
var status = gl.getShaderParameter( shader, 35713 ); | |
var log = gl.getShaderInfoLog( shader ).trim(); | |
if ( status && log === '' ) { return ''; } | |
// --enable-privileged-webgl-extension | |
// console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); | |
var source = gl.getShaderSource( shader ); | |
return 'THREE.WebGLShader: gl.getShaderInfoLog() ' + type + '\n' + log + addLineNumbers( source ); | |
} | |
function getTexelDecodingFunction( functionName, encoding ) { | |
var components = getEncodingComponents( encoding ); | |
return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[ 0 ] + 'ToLinear' + components[ 1 ] + '; }'; | |
} | |
function getTexelEncodingFunction( functionName, encoding ) { | |
var components = getEncodingComponents( encoding ); | |
return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }'; | |
} | |
function getToneMappingFunction( functionName, toneMapping ) { | |
var toneMappingName; | |
switch ( toneMapping ) { | |
case LinearToneMapping: | |
toneMappingName = 'Linear'; | |
break; | |
case ReinhardToneMapping: | |
toneMappingName = 'Reinhard'; | |
break; | |
case Uncharted2ToneMapping: | |
toneMappingName = 'Uncharted2'; | |
break; | |
case CineonToneMapping: | |
toneMappingName = 'OptimizedCineon'; | |
break; | |
case ACESFilmicToneMapping: | |
toneMappingName = 'ACESFilmic'; | |
break; | |
default: | |
throw new Error( 'unsupported toneMapping: ' + toneMapping ); | |
} | |
return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }'; | |
} | |
function generateExtensions( parameters ) { | |
var chunks = [ | |
( parameters.extensionDerivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ) ? '#extension GL_OES_standard_derivatives : enable' : '', | |
( parameters.extensionFragDepth || parameters.logarithmicDepthBuffer ) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '', | |
( parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ) ? '#extension GL_EXT_draw_buffers : require' : '', | |
( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : '' | |
]; | |
return chunks.filter( filterEmptyLine ).join( '\n' ); | |
} | |
function generateDefines( defines ) { | |
var chunks = []; | |
for ( var name in defines ) { | |
var value = defines[ name ]; | |
if ( value === false ) { continue; } | |
chunks.push( '#define ' + name + ' ' + value ); | |
} | |
return chunks.join( '\n' ); | |
} | |
function fetchAttributeLocations( gl, program ) { | |
var attributes = {}; | |
var n = gl.getProgramParameter( program, 35721 ); | |
for ( var i = 0; i < n; i ++ ) { | |
var info = gl.getActiveAttrib( program, i ); | |
var name = info.name; | |
// console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); | |
attributes[ name ] = gl.getAttribLocation( program, name ); | |
} | |
return attributes; | |
} | |
function filterEmptyLine( string ) { | |
return string !== ''; | |
} | |
function replaceLightNums( string, parameters ) { | |
return string | |
.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights ) | |
.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights ) | |
.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights ) | |
.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights ) | |
.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights ) | |
.replace( /NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows ) | |
.replace( /NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows ) | |
.replace( /NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows ); | |
} | |
function replaceClippingPlaneNums( string, parameters ) { | |
return string | |
.replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes ) | |
.replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) ); | |
} | |
// Resolve Includes | |
var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; | |
function resolveIncludes( string ) { | |
return string.replace( includePattern, includeReplacer ); | |
} | |
function includeReplacer( match, include ) { | |
var string = ShaderChunk[ include ]; | |
if ( string === undefined ) { | |
throw new Error( 'Can not resolve #include <' + include + '>' ); | |
} | |
return resolveIncludes( string ); | |
} | |
// Unroll Loops | |
var deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; | |
var unrollLoopPattern = /#pragma unroll_loop_start[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}[\s]+?#pragma unroll_loop_end/g; | |
function unrollLoops( string ) { | |
return string | |
.replace( unrollLoopPattern, loopReplacer ) | |
.replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer ); | |
} | |
function deprecatedLoopReplacer( match, start, end, snippet ) { | |
console.warn( 'WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.' ); | |
return loopReplacer( match, start, end, snippet ); | |
} | |
function loopReplacer( match, start, end, snippet ) { | |
var string = ''; | |
for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) { | |
string += snippet | |
.replace( /\[ i \]/g, '[ ' + i + ' ]' ) | |
.replace( /UNROLLED_LOOP_INDEX/g, i ); | |
} | |
return string; | |
} | |
// | |
function generatePrecision( parameters ) { | |
var precisionstring = "precision " + parameters.precision + " float;\nprecision " + parameters.precision + " int;"; | |
if ( parameters.precision === "highp" ) { | |
precisionstring += "\n#define HIGH_PRECISION"; | |
} else if ( parameters.precision === "mediump" ) { | |
precisionstring += "\n#define MEDIUM_PRECISION"; | |
} else if ( parameters.precision === "lowp" ) { | |
precisionstring += "\n#define LOW_PRECISION"; | |
} | |
return precisionstring; | |
} | |
function generateShadowMapTypeDefine( parameters ) { | |
var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; | |
if ( parameters.shadowMapType === PCFShadowMap ) { | |
shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; | |
} else if ( parameters.shadowMapType === PCFSoftShadowMap ) { | |
shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; | |
} else if ( parameters.shadowMapType === VSMShadowMap ) { | |
shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; | |
} | |
return shadowMapTypeDefine; | |
} | |
function generateEnvMapTypeDefine( parameters ) { | |
var envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; | |
if ( parameters.envMap ) { | |
switch ( parameters.envMapMode ) { | |
case CubeReflectionMapping: | |
case CubeRefractionMapping: | |
envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; | |
break; | |
case CubeUVReflectionMapping: | |
case CubeUVRefractionMapping: | |
envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; | |
break; | |
case EquirectangularReflectionMapping: | |
case EquirectangularRefractionMapping: | |
envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC'; | |
break; | |
case SphericalReflectionMapping: | |
envMapTypeDefine = 'ENVMAP_TYPE_SPHERE'; | |
break; | |
} | |
} | |
return envMapTypeDefine; | |
} | |
function generateEnvMapModeDefine( parameters ) { | |
var envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; | |
if ( parameters.envMap ) { | |
switch ( parameters.envMapMode ) { | |
case CubeRefractionMapping: | |
case EquirectangularRefractionMapping: | |
envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; | |
break; | |
} | |
} | |
return envMapModeDefine; | |
} | |
function generateEnvMapBlendingDefine( parameters ) { | |
var envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; | |
if ( parameters.envMap ) { | |
switch ( parameters.combine ) { | |
case MultiplyOperation: | |
envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; | |
break; | |
case MixOperation: | |
envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; | |
break; | |
case AddOperation: | |
envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; | |
break; | |
} | |
} | |
return envMapBlendingDefine; | |
} | |
function WebGLProgram( renderer, cacheKey, parameters ) { | |
var gl = renderer.getContext(); | |
var defines = parameters.defines; | |
var vertexShader = parameters.vertexShader; | |
var fragmentShader = parameters.fragmentShader; | |
var shadowMapTypeDefine = generateShadowMapTypeDefine( parameters ); | |
var envMapTypeDefine = generateEnvMapTypeDefine( parameters ); | |
var envMapModeDefine = generateEnvMapModeDefine( parameters ); | |
var envMapBlendingDefine = generateEnvMapBlendingDefine( parameters ); | |
var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; | |
var customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters ); | |
var customDefines = generateDefines( defines ); | |
var program = gl.createProgram(); | |
var prefixVertex, prefixFragment; | |
if ( parameters.isRawShaderMaterial ) { | |
prefixVertex = [ | |
customDefines | |
].filter( filterEmptyLine ).join( '\n' ); | |
if ( prefixVertex.length > 0 ) { | |
prefixVertex += '\n'; | |
} | |
prefixFragment = [ | |
customExtensions, | |
customDefines | |
].filter( filterEmptyLine ).join( '\n' ); | |
if ( prefixFragment.length > 0 ) { | |
prefixFragment += '\n'; | |
} | |
} else { | |
prefixVertex = [ | |
generatePrecision( parameters ), | |
'#define SHADER_NAME ' + parameters.shaderName, | |
customDefines, | |
parameters.instancing ? '#define USE_INSTANCING' : '', | |
parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', | |
'#define GAMMA_FACTOR ' + gammaFactorDefine, | |
'#define MAX_BONES ' + parameters.maxBones, | |
( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', | |
( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', | |
parameters.map ? '#define USE_MAP' : '', | |
parameters.envMap ? '#define USE_ENVMAP' : '', | |
parameters.envMap ? '#define ' + envMapModeDefine : '', | |
parameters.lightMap ? '#define USE_LIGHTMAP' : '', | |
parameters.aoMap ? '#define USE_AOMAP' : '', | |
parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', | |
parameters.bumpMap ? '#define USE_BUMPMAP' : '', | |
parameters.normalMap ? '#define USE_NORMALMAP' : '', | |
( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', | |
( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '', | |
parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', | |
parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', | |
parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', | |
parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', | |
parameters.specularMap ? '#define USE_SPECULARMAP' : '', | |
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', | |
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', | |
parameters.alphaMap ? '#define USE_ALPHAMAP' : '', | |
parameters.vertexTangents ? '#define USE_TANGENT' : '', | |
parameters.vertexColors ? '#define USE_COLOR' : '', | |
parameters.vertexUvs ? '#define USE_UV' : '', | |
parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', | |
parameters.flatShading ? '#define FLAT_SHADED' : '', | |
parameters.skinning ? '#define USE_SKINNING' : '', | |
parameters.useVertexTexture ? '#define BONE_TEXTURE' : '', | |
parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', | |
parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', | |
parameters.doubleSided ? '#define DOUBLE_SIDED' : '', | |
parameters.flipSided ? '#define FLIP_SIDED' : '', | |
parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', | |
parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', | |
parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', | |
parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', | |
( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', | |
'uniform mat4 modelMatrix;', | |
'uniform mat4 modelViewMatrix;', | |
'uniform mat4 projectionMatrix;', | |
'uniform mat4 viewMatrix;', | |
'uniform mat3 normalMatrix;', | |
'uniform vec3 cameraPosition;', | |
'uniform bool isOrthographic;', | |
'#ifdef USE_INSTANCING', | |
' attribute mat4 instanceMatrix;', | |
'#endif', | |
'attribute vec3 position;', | |
'attribute vec3 normal;', | |
'attribute vec2 uv;', | |
'#ifdef USE_TANGENT', | |
' attribute vec4 tangent;', | |
'#endif', | |
'#ifdef USE_COLOR', | |
' attribute vec3 color;', | |
'#endif', | |
'#ifdef USE_MORPHTARGETS', | |
' attribute vec3 morphTarget0;', | |
' attribute vec3 morphTarget1;', | |
' attribute vec3 morphTarget2;', | |
' attribute vec3 morphTarget3;', | |
' #ifdef USE_MORPHNORMALS', | |
' attribute vec3 morphNormal0;', | |
' attribute vec3 morphNormal1;', | |
' attribute vec3 morphNormal2;', | |
' attribute vec3 morphNormal3;', | |
' #else', | |
' attribute vec3 morphTarget4;', | |
' attribute vec3 morphTarget5;', | |
' attribute vec3 morphTarget6;', | |
' attribute vec3 morphTarget7;', | |
' #endif', | |
'#endif', | |
'#ifdef USE_SKINNING', | |
' attribute vec4 skinIndex;', | |
' attribute vec4 skinWeight;', | |
'#endif', | |
'\n' | |
].filter( filterEmptyLine ).join( '\n' ); | |
prefixFragment = [ | |
customExtensions, | |
generatePrecision( parameters ), | |
'#define SHADER_NAME ' + parameters.shaderName, | |
customDefines, | |
parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest + ( parameters.alphaTest % 1 ? '' : '.0' ) : '', // add '.0' if integer | |
'#define GAMMA_FACTOR ' + gammaFactorDefine, | |
( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', | |
( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', | |
parameters.map ? '#define USE_MAP' : '', | |
parameters.matcap ? '#define USE_MATCAP' : '', | |
parameters.envMap ? '#define USE_ENVMAP' : '', | |
parameters.envMap ? '#define ' + envMapTypeDefine : '', | |
parameters.envMap ? '#define ' + envMapModeDefine : '', | |
parameters.envMap ? '#define ' + envMapBlendingDefine : '', | |
parameters.lightMap ? '#define USE_LIGHTMAP' : '', | |
parameters.aoMap ? '#define USE_AOMAP' : '', | |
parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', | |
parameters.bumpMap ? '#define USE_BUMPMAP' : '', | |
parameters.normalMap ? '#define USE_NORMALMAP' : '', | |
( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', | |
( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '', | |
parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', | |
parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', | |
parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', | |
parameters.specularMap ? '#define USE_SPECULARMAP' : '', | |
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', | |
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', | |
parameters.alphaMap ? '#define USE_ALPHAMAP' : '', | |
parameters.sheen ? '#define USE_SHEEN' : '', | |
parameters.vertexTangents ? '#define USE_TANGENT' : '', | |
parameters.vertexColors ? '#define USE_COLOR' : '', | |
parameters.vertexUvs ? '#define USE_UV' : '', | |
parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', | |
parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', | |
parameters.flatShading ? '#define FLAT_SHADED' : '', | |
parameters.doubleSided ? '#define DOUBLE_SIDED' : '', | |
parameters.flipSided ? '#define FLIP_SIDED' : '', | |
parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', | |
parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', | |
parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '', | |
parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', | |
parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', | |
( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', | |
( ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ) ? '#define TEXTURE_LOD_EXT' : '', | |
'uniform mat4 viewMatrix;', | |
'uniform vec3 cameraPosition;', | |
'uniform bool isOrthographic;', | |
( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '', | |
( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below | |
( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '', | |
parameters.dithering ? '#define DITHERING' : '', | |
( parameters.outputEncoding || parameters.mapEncoding || parameters.matcapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding || parameters.lightMapEncoding ) ? | |
ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below | |
parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '', | |
parameters.matcapEncoding ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '', | |
parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '', | |
parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '', | |
parameters.lightMapEncoding ? getTexelDecodingFunction( 'lightMapTexelToLinear', parameters.lightMapEncoding ) : '', | |
parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '', | |
parameters.depthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '', | |
'\n' | |
].filter( filterEmptyLine ).join( '\n' ); | |
} | |
vertexShader = resolveIncludes( vertexShader ); | |
vertexShader = replaceLightNums( vertexShader, parameters ); | |
vertexShader = replaceClippingPlaneNums( vertexShader, parameters ); | |
fragmentShader = resolveIncludes( fragmentShader ); | |
fragmentShader = replaceLightNums( fragmentShader, parameters ); | |
fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters ); | |
vertexShader = unrollLoops( vertexShader ); | |
fragmentShader = unrollLoops( fragmentShader ); | |
if ( parameters.isWebGL2 && ! parameters.isRawShaderMaterial ) { | |
var isGLSL3ShaderMaterial = false; | |
var versionRegex = /^\s*#version\s+300\s+es\s*\n/; | |
if ( parameters.isShaderMaterial && | |
vertexShader.match( versionRegex ) !== null && | |
fragmentShader.match( versionRegex ) !== null ) { | |
isGLSL3ShaderMaterial = true; | |
vertexShader = vertexShader.replace( versionRegex, '' ); | |
fragmentShader = fragmentShader.replace( versionRegex, '' ); | |
} | |
// GLSL 3.0 conversion | |
prefixVertex = [ | |
'#version 300 es\n', | |
'#define attribute in', | |
'#define varying out', | |
'#define texture2D texture' | |
].join( '\n' ) + '\n' + prefixVertex; | |
prefixFragment = [ | |
'#version 300 es\n', | |
'#define varying in', | |
isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;', | |
isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor', | |
'#define gl_FragDepthEXT gl_FragDepth', | |
'#define texture2D texture', | |
'#define textureCube texture', | |
'#define texture2DProj textureProj', | |
'#define texture2DLodEXT textureLod', | |
'#define texture2DProjLodEXT textureProjLod', | |
'#define textureCubeLodEXT textureLod', | |
'#define texture2DGradEXT textureGrad', | |
'#define texture2DProjGradEXT textureProjGrad', | |
'#define textureCubeGradEXT textureGrad' | |
].join( '\n' ) + '\n' + prefixFragment; | |
} | |
var vertexGlsl = prefixVertex + vertexShader; | |
var fragmentGlsl = prefixFragment + fragmentShader; | |
// console.log( '*VERTEX*', vertexGlsl ); | |
// console.log( '*FRAGMENT*', fragmentGlsl ); | |
var glVertexShader = WebGLShader( gl, 35633, vertexGlsl ); | |
var glFragmentShader = WebGLShader( gl, 35632, fragmentGlsl ); | |
gl.attachShader( program, glVertexShader ); | |
gl.attachShader( program, glFragmentShader ); | |
// Force a particular attribute to index 0. | |
if ( parameters.index0AttributeName !== undefined ) { | |
gl.bindAttribLocation( program, 0, parameters.index0AttributeName ); | |
} else if ( parameters.morphTargets === true ) { | |
// programs with morphTargets displace position out of attribute 0 | |
gl.bindAttribLocation( program, 0, 'position' ); | |
} | |
gl.linkProgram( program ); | |
// check for link errors | |
if ( renderer.debug.checkShaderErrors ) { | |
var programLog = gl.getProgramInfoLog( program ).trim(); | |
var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim(); | |
var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim(); | |
var runnable = true; | |
var haveDiagnostics = true; | |
if ( gl.getProgramParameter( program, 35714 ) === false ) { | |
runnable = false; | |
var vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' ); | |
var fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' ); | |
console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), '35715', gl.getProgramParameter( program, 35715 ), 'gl.getProgramInfoLog', programLog, vertexErrors, fragmentErrors ); | |
} else if ( programLog !== '' ) { | |
console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog ); | |
} else if ( vertexLog === '' || fragmentLog === '' ) { | |
haveDiagnostics = false; | |
} | |
if ( haveDiagnostics ) { | |
this.diagnostics = { | |
runnable: runnable, | |
programLog: programLog, | |
vertexShader: { | |
log: vertexLog, | |
prefix: prefixVertex | |
}, | |
fragmentShader: { | |
log: fragmentLog, | |
prefix: prefixFragment | |
} | |
}; | |
} | |
} | |
// clean up | |
gl.detachShader( program, glVertexShader ); | |
gl.detachShader( program, glFragmentShader ); | |
gl.deleteShader( glVertexShader ); | |
gl.deleteShader( glFragmentShader ); | |
// set up caching for uniform locations | |
var cachedUniforms; | |
this.getUniforms = function () { | |
if ( cachedUniforms === undefined ) { | |
cachedUniforms = new WebGLUniforms( gl, program ); | |
} | |
return cachedUniforms; | |
}; | |
// set up caching for attribute locations | |
var cachedAttributes; | |
this.getAttributes = function () { | |
if ( cachedAttributes === undefined ) { | |
cachedAttributes = fetchAttributeLocations( gl, program ); | |
} | |
return cachedAttributes; | |
}; | |
// free resource | |
this.destroy = function () { | |
gl.deleteProgram( program ); | |
this.program = undefined; | |
}; | |
// | |
this.name = parameters.shaderName; | |
this.id = programIdCount ++; | |
this.cacheKey = cacheKey; | |
this.usedTimes = 1; | |
this.program = program; | |
this.vertexShader = glVertexShader; | |
this.fragmentShader = glFragmentShader; | |
return this; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLPrograms( renderer, extensions, capabilities ) { | |
var programs = []; | |
var isWebGL2 = capabilities.isWebGL2; | |
var logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; | |
var floatVertexTextures = capabilities.floatVertexTextures; | |
var precision = capabilities.precision; | |
var maxVertexUniforms = capabilities.maxVertexUniforms; | |
var vertexTextures = capabilities.vertexTextures; | |
var shaderIDs = { | |
MeshDepthMaterial: 'depth', | |
MeshDistanceMaterial: 'distanceRGBA', | |
MeshNormalMaterial: 'normal', | |
MeshBasicMaterial: 'basic', | |
MeshLambertMaterial: 'lambert', | |
MeshPhongMaterial: 'phong', | |
MeshToonMaterial: 'toon', | |
MeshStandardMaterial: 'physical', | |
MeshPhysicalMaterial: 'physical', | |
MeshMatcapMaterial: 'matcap', | |
LineBasicMaterial: 'basic', | |
LineDashedMaterial: 'dashed', | |
PointsMaterial: 'points', | |
ShadowMaterial: 'shadow', | |
SpriteMaterial: 'sprite' | |
}; | |
var parameterNames = [ | |
"precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing", | |
"map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV", | |
"lightMap", "lightMapEncoding", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatMap", "clearcoatRoughnessMap", "clearcoatNormalMap", "displacementMap", "specularMap", | |
"roughnessMap", "metalnessMap", "gradientMap", | |
"alphaMap", "combine", "vertexColors", "vertexTangents", "vertexUvs", "uvsVertexOnly", "fog", "useFog", "fogExp2", | |
"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", | |
"maxBones", "useVertexTexture", "morphTargets", "morphNormals", | |
"maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", | |
"numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights", | |
"numDirLightShadows", "numPointLightShadows", "numSpotLightShadows", | |
"shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', | |
"alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering", | |
"sheen" | |
]; | |
function getShaderObject( material, shaderID ) { | |
var shaderobject; | |
if ( shaderID ) { | |
var shader = ShaderLib[ shaderID ]; | |
shaderobject = { | |
name: material.type, | |
uniforms: UniformsUtils.clone( shader.uniforms ), | |
vertexShader: shader.vertexShader, | |
fragmentShader: shader.fragmentShader | |
}; | |
} else { | |
shaderobject = { | |
name: material.type, | |
uniforms: material.uniforms, | |
vertexShader: material.vertexShader, | |
fragmentShader: material.fragmentShader | |
}; | |
} | |
return shaderobject; | |
} | |
function allocateBones( object ) { | |
var skeleton = object.skeleton; | |
var bones = skeleton.bones; | |
if ( floatVertexTextures ) { | |
return 1024; | |
} else { | |
// default for when object is not specified | |
// ( for example when prebuilding shader to be used with multiple objects ) | |
// | |
// - leave some extra space for other uniforms | |
// - limit here is ANGLE's 254 max uniform vectors | |
// (up to 54 should be safe) | |
var nVertexUniforms = maxVertexUniforms; | |
var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 ); | |
var maxBones = Math.min( nVertexMatrices, bones.length ); | |
if ( maxBones < bones.length ) { | |
console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' ); | |
return 0; | |
} | |
return maxBones; | |
} | |
} | |
function getTextureEncodingFromMap( map ) { | |
var encoding; | |
if ( ! map ) { | |
encoding = LinearEncoding; | |
} else if ( map.isTexture ) { | |
encoding = map.encoding; | |
} else if ( map.isWebGLRenderTarget ) { | |
console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." ); | |
encoding = map.texture.encoding; | |
} | |
return encoding; | |
} | |
this.getParameters = function ( material, lights, shadows, scene, nClipPlanes, nClipIntersection, object ) { | |
var fog = scene.fog; | |
var environment = material.isMeshStandardMaterial ? scene.environment : null; | |
var envMap = material.envMap || environment; | |
var shaderID = shaderIDs[ material.type ]; | |
// heuristics to create shader parameters according to lights in the scene | |
// (not to blow over maxLights budget) | |
var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0; | |
if ( material.precision !== null ) { | |
precision = capabilities.getMaxPrecision( material.precision ); | |
if ( precision !== material.precision ) { | |
console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' ); | |
} | |
} | |
var shaderobject = getShaderObject( material, shaderID ); | |
material.onBeforeCompile( shaderobject, renderer ); | |
var currentRenderTarget = renderer.getRenderTarget(); | |
var parameters = { | |
isWebGL2: isWebGL2, | |
shaderID: shaderID, | |
shaderName: shaderobject.name, | |
uniforms: shaderobject.uniforms, | |
vertexShader: shaderobject.vertexShader, | |
fragmentShader: shaderobject.fragmentShader, | |
defines: material.defines, | |
isRawShaderMaterial: material.isRawShaderMaterial, | |
isShaderMaterial: material.isShaderMaterial, | |
precision: precision, | |
instancing: object.isInstancedMesh === true, | |
supportsVertexTextures: vertexTextures, | |
outputEncoding: ( currentRenderTarget !== null ) ? getTextureEncodingFromMap( currentRenderTarget.texture ) : renderer.outputEncoding, | |
map: !! material.map, | |
mapEncoding: getTextureEncodingFromMap( material.map ), | |
matcap: !! material.matcap, | |
matcapEncoding: getTextureEncodingFromMap( material.matcap ), | |
envMap: !! envMap, | |
envMapMode: envMap && envMap.mapping, | |
envMapEncoding: getTextureEncodingFromMap( envMap ), | |
envMapCubeUV: ( !! envMap ) && ( ( envMap.mapping === CubeUVReflectionMapping ) || ( envMap.mapping === CubeUVRefractionMapping ) ), | |
lightMap: !! material.lightMap, | |
lightMapEncoding: getTextureEncodingFromMap( material.lightMap ), | |
aoMap: !! material.aoMap, | |
emissiveMap: !! material.emissiveMap, | |
emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap ), | |
bumpMap: !! material.bumpMap, | |
normalMap: !! material.normalMap, | |
objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, | |
tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap, | |
clearcoatMap: !! material.clearcoatMap, | |
clearcoatRoughnessMap: !! material.clearcoatRoughnessMap, | |
clearcoatNormalMap: !! material.clearcoatNormalMap, | |
displacementMap: !! material.displacementMap, | |
roughnessMap: !! material.roughnessMap, | |
metalnessMap: !! material.metalnessMap, | |
specularMap: !! material.specularMap, | |
alphaMap: !! material.alphaMap, | |
gradientMap: !! material.gradientMap, | |
sheen: !! material.sheen, | |
combine: material.combine, | |
vertexTangents: ( material.normalMap && material.vertexTangents ), | |
vertexColors: material.vertexColors, | |
vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.displacementMap, | |
uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap ) && !! material.displacementMap, | |
fog: !! fog, | |
useFog: material.fog, | |
fogExp2: ( fog && fog.isFogExp2 ), | |
flatShading: material.flatShading, | |
sizeAttenuation: material.sizeAttenuation, | |
logarithmicDepthBuffer: logarithmicDepthBuffer, | |
skinning: material.skinning && maxBones > 0, | |
maxBones: maxBones, | |
useVertexTexture: floatVertexTextures, | |
morphTargets: material.morphTargets, | |
morphNormals: material.morphNormals, | |
maxMorphTargets: renderer.maxMorphTargets, | |
maxMorphNormals: renderer.maxMorphNormals, | |
numDirLights: lights.directional.length, | |
numPointLights: lights.point.length, | |
numSpotLights: lights.spot.length, | |
numRectAreaLights: lights.rectArea.length, | |
numHemiLights: lights.hemi.length, | |
numDirLightShadows: lights.directionalShadowMap.length, | |
numPointLightShadows: lights.pointShadowMap.length, | |
numSpotLightShadows: lights.spotShadowMap.length, | |
numClippingPlanes: nClipPlanes, | |
numClipIntersection: nClipIntersection, | |
dithering: material.dithering, | |
shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0, | |
shadowMapType: renderer.shadowMap.type, | |
toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping, | |
physicallyCorrectLights: renderer.physicallyCorrectLights, | |
premultipliedAlpha: material.premultipliedAlpha, | |
alphaTest: material.alphaTest, | |
doubleSided: material.side === DoubleSide, | |
flipSided: material.side === BackSide, | |
depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false, | |
index0AttributeName: material.index0AttributeName, | |
extensionDerivatives: material.extensions && material.extensions.derivatives, | |
extensionFragDepth: material.extensions && material.extensions.fragDepth, | |
extensionDrawBuffers: material.extensions && material.extensions.drawBuffers, | |
extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD, | |
rendererExtensionFragDepth: isWebGL2 || extensions.get( 'EXT_frag_depth' ) !== null, | |
rendererExtensionDrawBuffers: isWebGL2 || extensions.get( 'WEBGL_draw_buffers' ) !== null, | |
rendererExtensionShaderTextureLod: isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) !== null, | |
onBeforeCompile: material.onBeforeCompile | |
}; | |
return parameters; | |
}; | |
this.getProgramCacheKey = function ( parameters ) { | |
var array = []; | |
if ( parameters.shaderID ) { | |
array.push( parameters.shaderID ); | |
} else { | |
array.push( parameters.fragmentShader ); | |
array.push( parameters.vertexShader ); | |
} | |
if ( parameters.defines !== undefined ) { | |
for ( var name in parameters.defines ) { | |
array.push( name ); | |
array.push( parameters.defines[ name ] ); | |
} | |
} | |
if ( parameters.isRawShaderMaterial === undefined ) { | |
for ( var i = 0; i < parameterNames.length; i ++ ) { | |
array.push( parameters[ parameterNames[ i ] ] ); | |
} | |
array.push( renderer.outputEncoding ); | |
array.push( renderer.gammaFactor ); | |
} | |
array.push( parameters.onBeforeCompile.toString() ); | |
return array.join(); | |
}; | |
this.acquireProgram = function ( parameters, cacheKey ) { | |
var program; | |
// Check if code has been already compiled | |
for ( var p = 0, pl = programs.length; p < pl; p ++ ) { | |
var preexistingProgram = programs[ p ]; | |
if ( preexistingProgram.cacheKey === cacheKey ) { | |
program = preexistingProgram; | |
++ program.usedTimes; | |
break; | |
} | |
} | |
if ( program === undefined ) { | |
program = new WebGLProgram( renderer, cacheKey, parameters ); | |
programs.push( program ); | |
} | |
return program; | |
}; | |
this.releaseProgram = function ( program ) { | |
if ( -- program.usedTimes === 0 ) { | |
// Remove from unordered set | |
var i = programs.indexOf( program ); | |
programs[ i ] = programs[ programs.length - 1 ]; | |
programs.pop(); | |
// Free WebGL resources | |
program.destroy(); | |
} | |
}; | |
// Exposed for resource monitoring & error feedback via renderer.info: | |
this.programs = programs; | |
} | |
/** | |
* @author fordacious / fordacious.github.io | |
*/ | |
function WebGLProperties() { | |
var properties = new WeakMap(); | |
function get( object ) { | |
var map = properties.get( object ); | |
if ( map === undefined ) { | |
map = {}; | |
properties.set( object, map ); | |
} | |
return map; | |
} | |
function remove( object ) { | |
properties.delete( object ); | |
} | |
function update( object, key, value ) { | |
properties.get( object )[ key ] = value; | |
} | |
function dispose() { | |
properties = new WeakMap(); | |
} | |
return { | |
get: get, | |
remove: remove, | |
update: update, | |
dispose: dispose | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function painterSortStable( a, b ) { | |
if ( a.groupOrder !== b.groupOrder ) { | |
return a.groupOrder - b.groupOrder; | |
} else if ( a.renderOrder !== b.renderOrder ) { | |
return a.renderOrder - b.renderOrder; | |
} else if ( a.program !== b.program ) { | |
return a.program.id - b.program.id; | |
} else if ( a.material.id !== b.material.id ) { | |
return a.material.id - b.material.id; | |
} else if ( a.z !== b.z ) { | |
return a.z - b.z; | |
} else { | |
return a.id - b.id; | |
} | |
} | |
function reversePainterSortStable( a, b ) { | |
if ( a.groupOrder !== b.groupOrder ) { | |
return a.groupOrder - b.groupOrder; | |
} else if ( a.renderOrder !== b.renderOrder ) { | |
return a.renderOrder - b.renderOrder; | |
} else if ( a.z !== b.z ) { | |
return b.z - a.z; | |
} else { | |
return a.id - b.id; | |
} | |
} | |
function WebGLRenderList() { | |
var renderItems = []; | |
var renderItemsIndex = 0; | |
var opaque = []; | |
var transparent = []; | |
var defaultProgram = { id: - 1 }; | |
function init() { | |
renderItemsIndex = 0; | |
opaque.length = 0; | |
transparent.length = 0; | |
} | |
function getNextRenderItem( object, geometry, material, groupOrder, z, group ) { | |
var renderItem = renderItems[ renderItemsIndex ]; | |
if ( renderItem === undefined ) { | |
renderItem = { | |
id: object.id, | |
object: object, | |
geometry: geometry, | |
material: material, | |
program: material.program || defaultProgram, | |
groupOrder: groupOrder, | |
renderOrder: object.renderOrder, | |
z: z, | |
group: group | |
}; | |
renderItems[ renderItemsIndex ] = renderItem; | |
} else { | |
renderItem.id = object.id; | |
renderItem.object = object; | |
renderItem.geometry = geometry; | |
renderItem.material = material; | |
renderItem.program = material.program || defaultProgram; | |
renderItem.groupOrder = groupOrder; | |
renderItem.renderOrder = object.renderOrder; | |
renderItem.z = z; | |
renderItem.group = group; | |
} | |
renderItemsIndex ++; | |
return renderItem; | |
} | |
function push( object, geometry, material, groupOrder, z, group ) { | |
var renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group ); | |
( material.transparent === true ? transparent : opaque ).push( renderItem ); | |
} | |
function unshift( object, geometry, material, groupOrder, z, group ) { | |
var renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group ); | |
( material.transparent === true ? transparent : opaque ).unshift( renderItem ); | |
} | |
function sort( customOpaqueSort, customTransparentSort ) { | |
if ( opaque.length > 1 ) { opaque.sort( customOpaqueSort || painterSortStable ); } | |
if ( transparent.length > 1 ) { transparent.sort( customTransparentSort || reversePainterSortStable ); } | |
} | |
function finish() { | |
// Clear references from inactive renderItems in the list | |
for ( var i = renderItemsIndex, il = renderItems.length; i < il; i ++ ) { | |
var renderItem = renderItems[ i ]; | |
if ( renderItem.id === null ) { break; } | |
renderItem.id = null; | |
renderItem.object = null; | |
renderItem.geometry = null; | |
renderItem.material = null; | |
renderItem.program = null; | |
renderItem.group = null; | |
} | |
} | |
return { | |
opaque: opaque, | |
transparent: transparent, | |
init: init, | |
push: push, | |
unshift: unshift, | |
finish: finish, | |
sort: sort | |
}; | |
} | |
function WebGLRenderLists() { | |
var lists = new WeakMap(); | |
function onSceneDispose( event ) { | |
var scene = event.target; | |
scene.removeEventListener( 'dispose', onSceneDispose ); | |
lists.delete( scene ); | |
} | |
function get( scene, camera ) { | |
var cameras = lists.get( scene ); | |
var list; | |
if ( cameras === undefined ) { | |
list = new WebGLRenderList(); | |
lists.set( scene, new WeakMap() ); | |
lists.get( scene ).set( camera, list ); | |
scene.addEventListener( 'dispose', onSceneDispose ); | |
} else { | |
list = cameras.get( camera ); | |
if ( list === undefined ) { | |
list = new WebGLRenderList(); | |
cameras.set( camera, list ); | |
} | |
} | |
return list; | |
} | |
function dispose() { | |
lists = new WeakMap(); | |
} | |
return { | |
get: get, | |
dispose: dispose | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function UniformsCache() { | |
var lights = {}; | |
return { | |
get: function ( light ) { | |
if ( lights[ light.id ] !== undefined ) { | |
return lights[ light.id ]; | |
} | |
var uniforms; | |
switch ( light.type ) { | |
case 'DirectionalLight': | |
uniforms = { | |
direction: new Vector3(), | |
color: new Color() | |
}; | |
break; | |
case 'SpotLight': | |
uniforms = { | |
position: new Vector3(), | |
direction: new Vector3(), | |
color: new Color(), | |
distance: 0, | |
coneCos: 0, | |
penumbraCos: 0, | |
decay: 0 | |
}; | |
break; | |
case 'PointLight': | |
uniforms = { | |
position: new Vector3(), | |
color: new Color(), | |
distance: 0, | |
decay: 0 | |
}; | |
break; | |
case 'HemisphereLight': | |
uniforms = { | |
direction: new Vector3(), | |
skyColor: new Color(), | |
groundColor: new Color() | |
}; | |
break; | |
case 'RectAreaLight': | |
uniforms = { | |
color: new Color(), | |
position: new Vector3(), | |
halfWidth: new Vector3(), | |
halfHeight: new Vector3() | |
}; | |
break; | |
} | |
lights[ light.id ] = uniforms; | |
return uniforms; | |
} | |
}; | |
} | |
function ShadowUniformsCache() { | |
var lights = {}; | |
return { | |
get: function ( light ) { | |
if ( lights[ light.id ] !== undefined ) { | |
return lights[ light.id ]; | |
} | |
var uniforms; | |
switch ( light.type ) { | |
case 'DirectionalLight': | |
uniforms = { | |
shadowBias: 0, | |
shadowRadius: 1, | |
shadowMapSize: new Vector2() | |
}; | |
break; | |
case 'SpotLight': | |
uniforms = { | |
shadowBias: 0, | |
shadowRadius: 1, | |
shadowMapSize: new Vector2() | |
}; | |
break; | |
case 'PointLight': | |
uniforms = { | |
shadowBias: 0, | |
shadowRadius: 1, | |
shadowMapSize: new Vector2(), | |
shadowCameraNear: 1, | |
shadowCameraFar: 1000 | |
}; | |
break; | |
// TODO (abelnation): set RectAreaLight shadow uniforms | |
} | |
lights[ light.id ] = uniforms; | |
return uniforms; | |
} | |
}; | |
} | |
var nextVersion = 0; | |
function shadowCastingLightsFirst( lightA, lightB ) { | |
return ( lightB.castShadow ? 1 : 0 ) - ( lightA.castShadow ? 1 : 0 ); | |
} | |
function WebGLLights() { | |
var cache = new UniformsCache(); | |
var shadowCache = ShadowUniformsCache(); | |
var state = { | |
version: 0, | |
hash: { | |
directionalLength: - 1, | |
pointLength: - 1, | |
spotLength: - 1, | |
rectAreaLength: - 1, | |
hemiLength: - 1, | |
numDirectionalShadows: - 1, | |
numPointShadows: - 1, | |
numSpotShadows: - 1 | |
}, | |
ambient: [ 0, 0, 0 ], | |
probe: [], | |
directional: [], | |
directionalShadow: [], | |
directionalShadowMap: [], | |
directionalShadowMatrix: [], | |
spot: [], | |
spotShadow: [], | |
spotShadowMap: [], | |
spotShadowMatrix: [], | |
rectArea: [], | |
point: [], | |
pointShadow: [], | |
pointShadowMap: [], | |
pointShadowMatrix: [], | |
hemi: [] | |
}; | |
for ( var i = 0; i < 9; i ++ ) { state.probe.push( new Vector3() ); } | |
var vector3 = new Vector3(); | |
var matrix4 = new Matrix4(); | |
var matrix42 = new Matrix4(); | |
function setup( lights, shadows, camera ) { | |
var r = 0, g = 0, b = 0; | |
for ( var i = 0; i < 9; i ++ ) { state.probe[ i ].set( 0, 0, 0 ); } | |
var directionalLength = 0; | |
var pointLength = 0; | |
var spotLength = 0; | |
var rectAreaLength = 0; | |
var hemiLength = 0; | |
var numDirectionalShadows = 0; | |
var numPointShadows = 0; | |
var numSpotShadows = 0; | |
var viewMatrix = camera.matrixWorldInverse; | |
lights.sort( shadowCastingLightsFirst ); | |
for ( var i = 0, l = lights.length; i < l; i ++ ) { | |
var light = lights[ i ]; | |
var color = light.color; | |
var intensity = light.intensity; | |
var distance = light.distance; | |
var shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null; | |
if ( light.isAmbientLight ) { | |
r += color.r * intensity; | |
g += color.g * intensity; | |
b += color.b * intensity; | |
} else if ( light.isLightProbe ) { | |
for ( var j = 0; j < 9; j ++ ) { | |
state.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity ); | |
} | |
} else if ( light.isDirectionalLight ) { | |
var uniforms = cache.get( light ); | |
uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); | |
uniforms.direction.setFromMatrixPosition( light.matrixWorld ); | |
vector3.setFromMatrixPosition( light.target.matrixWorld ); | |
uniforms.direction.sub( vector3 ); | |
uniforms.direction.transformDirection( viewMatrix ); | |
if ( light.castShadow ) { | |
var shadow = light.shadow; | |
var shadowUniforms = shadowCache.get( light ); | |
shadowUniforms.shadowBias = shadow.bias; | |
shadowUniforms.shadowRadius = shadow.radius; | |
shadowUniforms.shadowMapSize = shadow.mapSize; | |
state.directionalShadow[ directionalLength ] = shadowUniforms; | |
state.directionalShadowMap[ directionalLength ] = shadowMap; | |
state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; | |
numDirectionalShadows ++; | |
} | |
state.directional[ directionalLength ] = uniforms; | |
directionalLength ++; | |
} else if ( light.isSpotLight ) { | |
var uniforms = cache.get( light ); | |
uniforms.position.setFromMatrixPosition( light.matrixWorld ); | |
uniforms.position.applyMatrix4( viewMatrix ); | |
uniforms.color.copy( color ).multiplyScalar( intensity ); | |
uniforms.distance = distance; | |
uniforms.direction.setFromMatrixPosition( light.matrixWorld ); | |
vector3.setFromMatrixPosition( light.target.matrixWorld ); | |
uniforms.direction.sub( vector3 ); | |
uniforms.direction.transformDirection( viewMatrix ); | |
uniforms.coneCos = Math.cos( light.angle ); | |
uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); | |
uniforms.decay = light.decay; | |
if ( light.castShadow ) { | |
var shadow = light.shadow; | |
var shadowUniforms = shadowCache.get( light ); | |
shadowUniforms.shadowBias = shadow.bias; | |
shadowUniforms.shadowRadius = shadow.radius; | |
shadowUniforms.shadowMapSize = shadow.mapSize; | |
state.spotShadow[ spotLength ] = shadowUniforms; | |
state.spotShadowMap[ spotLength ] = shadowMap; | |
state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; | |
numSpotShadows ++; | |
} | |
state.spot[ spotLength ] = uniforms; | |
spotLength ++; | |
} else if ( light.isRectAreaLight ) { | |
var uniforms = cache.get( light ); | |
// (a) intensity is the total visible light emitted | |
//uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) ); | |
// (b) intensity is the brightness of the light | |
uniforms.color.copy( color ).multiplyScalar( intensity ); | |
uniforms.position.setFromMatrixPosition( light.matrixWorld ); | |
uniforms.position.applyMatrix4( viewMatrix ); | |
// extract local rotation of light to derive width/height half vectors | |
matrix42.identity(); | |
matrix4.copy( light.matrixWorld ); | |
matrix4.premultiply( viewMatrix ); | |
matrix42.extractRotation( matrix4 ); | |
uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 ); | |
uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 ); | |
uniforms.halfWidth.applyMatrix4( matrix42 ); | |
uniforms.halfHeight.applyMatrix4( matrix42 ); | |
// TODO (abelnation): RectAreaLight distance? | |
// uniforms.distance = distance; | |
state.rectArea[ rectAreaLength ] = uniforms; | |
rectAreaLength ++; | |
} else if ( light.isPointLight ) { | |
var uniforms = cache.get( light ); | |
uniforms.position.setFromMatrixPosition( light.matrixWorld ); | |
uniforms.position.applyMatrix4( viewMatrix ); | |
uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); | |
uniforms.distance = light.distance; | |
uniforms.decay = light.decay; | |
if ( light.castShadow ) { | |
var shadow = light.shadow; | |
var shadowUniforms = shadowCache.get( light ); | |
shadowUniforms.shadowBias = shadow.bias; | |
shadowUniforms.shadowRadius = shadow.radius; | |
shadowUniforms.shadowMapSize = shadow.mapSize; | |
shadowUniforms.shadowCameraNear = shadow.camera.near; | |
shadowUniforms.shadowCameraFar = shadow.camera.far; | |
state.pointShadow[ pointLength ] = shadowUniforms; | |
state.pointShadowMap[ pointLength ] = shadowMap; | |
state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; | |
numPointShadows ++; | |
} | |
state.point[ pointLength ] = uniforms; | |
pointLength ++; | |
} else if ( light.isHemisphereLight ) { | |
var uniforms = cache.get( light ); | |
uniforms.direction.setFromMatrixPosition( light.matrixWorld ); | |
uniforms.direction.transformDirection( viewMatrix ); | |
uniforms.direction.normalize(); | |
uniforms.skyColor.copy( light.color ).multiplyScalar( intensity ); | |
uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity ); | |
state.hemi[ hemiLength ] = uniforms; | |
hemiLength ++; | |
} | |
} | |
state.ambient[ 0 ] = r; | |
state.ambient[ 1 ] = g; | |
state.ambient[ 2 ] = b; | |
var hash = state.hash; | |
if ( hash.directionalLength !== directionalLength || | |
hash.pointLength !== pointLength || | |
hash.spotLength !== spotLength || | |
hash.rectAreaLength !== rectAreaLength || | |
hash.hemiLength !== hemiLength || | |
hash.numDirectionalShadows !== numDirectionalShadows || | |
hash.numPointShadows !== numPointShadows || | |
hash.numSpotShadows !== numSpotShadows ) { | |
state.directional.length = directionalLength; | |
state.spot.length = spotLength; | |
state.rectArea.length = rectAreaLength; | |
state.point.length = pointLength; | |
state.hemi.length = hemiLength; | |
state.directionalShadow.length = numDirectionalShadows; | |
state.directionalShadowMap.length = numDirectionalShadows; | |
state.pointShadow.length = numPointShadows; | |
state.pointShadowMap.length = numPointShadows; | |
state.spotShadow.length = numSpotShadows; | |
state.spotShadowMap.length = numSpotShadows; | |
state.directionalShadowMatrix.length = numDirectionalShadows; | |
state.pointShadowMatrix.length = numPointShadows; | |
state.spotShadowMatrix.length = numSpotShadows; | |
hash.directionalLength = directionalLength; | |
hash.pointLength = pointLength; | |
hash.spotLength = spotLength; | |
hash.rectAreaLength = rectAreaLength; | |
hash.hemiLength = hemiLength; | |
hash.numDirectionalShadows = numDirectionalShadows; | |
hash.numPointShadows = numPointShadows; | |
hash.numSpotShadows = numSpotShadows; | |
state.version = nextVersion ++; | |
} | |
} | |
return { | |
setup: setup, | |
state: state | |
}; | |
} | |
/** | |
* @author Mugen87 / https://github.com/Mugen87 | |
*/ | |
function WebGLRenderState() { | |
var lights = new WebGLLights(); | |
var lightsArray = []; | |
var shadowsArray = []; | |
function init() { | |
lightsArray.length = 0; | |
shadowsArray.length = 0; | |
} | |
function pushLight( light ) { | |
lightsArray.push( light ); | |
} | |
function pushShadow( shadowLight ) { | |
shadowsArray.push( shadowLight ); | |
} | |
function setupLights( camera ) { | |
lights.setup( lightsArray, shadowsArray, camera ); | |
} | |
var state = { | |
lightsArray: lightsArray, | |
shadowsArray: shadowsArray, | |
lights: lights | |
}; | |
return { | |
init: init, | |
state: state, | |
setupLights: setupLights, | |
pushLight: pushLight, | |
pushShadow: pushShadow | |
}; | |
} | |
function WebGLRenderStates() { | |
var renderStates = new WeakMap(); | |
function onSceneDispose( event ) { | |
var scene = event.target; | |
scene.removeEventListener( 'dispose', onSceneDispose ); | |
renderStates.delete( scene ); | |
} | |
function get( scene, camera ) { | |
var renderState; | |
if ( renderStates.has( scene ) === false ) { | |
renderState = new WebGLRenderState(); | |
renderStates.set( scene, new WeakMap() ); | |
renderStates.get( scene ).set( camera, renderState ); | |
scene.addEventListener( 'dispose', onSceneDispose ); | |
} else { | |
if ( renderStates.get( scene ).has( camera ) === false ) { | |
renderState = new WebGLRenderState(); | |
renderStates.get( scene ).set( camera, renderState ); | |
} else { | |
renderState = renderStates.get( scene ).get( camera ); | |
} | |
} | |
return renderState; | |
} | |
function dispose() { | |
renderStates = new WeakMap(); | |
} | |
return { | |
get: get, | |
dispose: dispose | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
* @author alteredq / http://alteredqualia.com/ | |
* @author bhouston / https://clara.io | |
* @author WestLangley / http://github.com/WestLangley | |
* | |
* parameters = { | |
* | |
* opacity: <float>, | |
* | |
* map: new THREE.Texture( <Image> ), | |
* | |
* alphaMap: new THREE.Texture( <Image> ), | |
* | |
* displacementMap: new THREE.Texture( <Image> ), | |
* displacementScale: <float>, | |
* displacementBias: <float>, | |
* | |
* wireframe: <boolean>, | |
* wireframeLinewidth: <float> | |
* } | |
*/ | |
function MeshDepthMaterial( parameters ) { | |
Material.call( this ); | |
this.type = 'MeshDepthMaterial'; | |
this.depthPacking = BasicDepthPacking; | |
this.skinning = false; | |
this.morphTargets = false; | |
this.map = null; | |
this.alphaMap = null; | |
this.displacementMap = null; | |
this.displacementScale = 1; | |
this.displacementBias = 0; | |
this.wireframe = false; | |
this.wireframeLinewidth = 1; | |
this.fog = false; | |
this.setValues( parameters ); | |
} | |
MeshDepthMaterial.prototype = Object.create( Material.prototype ); | |
MeshDepthMaterial.prototype.constructor = MeshDepthMaterial; | |
MeshDepthMaterial.prototype.isMeshDepthMaterial = true; | |
MeshDepthMaterial.prototype.copy = function ( source ) { | |
Material.prototype.copy.call( this, source ); | |
this.depthPacking = source.depthPacking; | |
this.skinning = source.skinning; | |
this.morphTargets = source.morphTargets; | |
this.map = source.map; | |
this.alphaMap = source.alphaMap; | |
this.displacementMap = source.displacementMap; | |
this.displacementScale = source.displacementScale; | |
this.displacementBias = source.displacementBias; | |
this.wireframe = source.wireframe; | |
this.wireframeLinewidth = source.wireframeLinewidth; | |
return this; | |
}; | |
/** | |
* @author WestLangley / http://github.com/WestLangley | |
* | |
* parameters = { | |
* | |
* referencePosition: <float>, | |
* nearDistance: <float>, | |
* farDistance: <float>, | |
* | |
* skinning: <bool>, | |
* morphTargets: <bool>, | |
* | |
* map: new THREE.Texture( <Image> ), | |
* | |
* alphaMap: new THREE.Texture( <Image> ), | |
* | |
* displacementMap: new THREE.Texture( <Image> ), | |
* displacementScale: <float>, | |
* displacementBias: <float> | |
* | |
* } | |
*/ | |
function MeshDistanceMaterial( parameters ) { | |
Material.call( this ); | |
this.type = 'MeshDistanceMaterial'; | |
this.referencePosition = new Vector3(); | |
this.nearDistance = 1; | |
this.farDistance = 1000; | |
this.skinning = false; | |
this.morphTargets = false; | |
this.map = null; | |
this.alphaMap = null; | |
this.displacementMap = null; | |
this.displacementScale = 1; | |
this.displacementBias = 0; | |
this.fog = false; | |
this.setValues( parameters ); | |
} | |
MeshDistanceMaterial.prototype = Object.create( Material.prototype ); | |
MeshDistanceMaterial.prototype.constructor = MeshDistanceMaterial; | |
MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true; | |
MeshDistanceMaterial.prototype.copy = function ( source ) { | |
Material.prototype.copy.call( this, source ); | |
this.referencePosition.copy( source.referencePosition ); | |
this.nearDistance = source.nearDistance; | |
this.farDistance = source.farDistance; | |
this.skinning = source.skinning; | |
this.morphTargets = source.morphTargets; | |
this.map = source.map; | |
this.alphaMap = source.alphaMap; | |
this.displacementMap = source.displacementMap; | |
this.displacementScale = source.displacementScale; | |
this.displacementBias = source.displacementBias; | |
return this; | |
}; | |
var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\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 = unpackRGBATo2Half( 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 = sqrt( squared_mean - mean * mean );\n gl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}"; | |
var vsm_vert = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; | |
/** | |
* @author alteredq / http://alteredqualia.com/ | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { | |
var _frustum = new Frustum(), | |
_shadowMapSize = new Vector2(), | |
_viewportSize = new Vector2(), | |
_viewport = new Vector4(), | |
_depthMaterials = [], | |
_distanceMaterials = [], | |
_materialCache = {}; | |
var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide }; | |
var shadowMaterialVertical = new ShaderMaterial( { | |
defines: { | |
SAMPLE_RATE: 2.0 / 8.0, | |
HALF_SAMPLE_RATE: 1.0 / 8.0 | |
}, | |
uniforms: { | |
shadow_pass: { value: null }, | |
resolution: { value: new Vector2() }, | |
radius: { value: 4.0 } | |
}, | |
vertexShader: vsm_vert, | |
fragmentShader: vsm_frag | |
} ); | |
var shadowMaterialHorizonal = shadowMaterialVertical.clone(); | |
shadowMaterialHorizonal.defines.HORIZONAL_PASS = 1; | |
var fullScreenTri = new BufferGeometry(); | |
fullScreenTri.setAttribute( | |
"position", | |
new BufferAttribute( | |
new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ), | |
3 | |
) | |
); | |
var fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical ); | |
var scope = this; | |
this.enabled = false; | |
this.autoUpdate = true; | |
this.needsUpdate = false; | |
this.type = PCFShadowMap; | |
this.render = function ( lights, scene, camera ) { | |
if ( scope.enabled === false ) { return; } | |
if ( scope.autoUpdate === false && scope.needsUpdate === false ) { return; } | |
if ( lights.length === 0 ) { return; } | |
var currentRenderTarget = _renderer.getRenderTarget(); | |
var activeCubeFace = _renderer.getActiveCubeFace(); | |
var activeMipmapLevel = _renderer.getActiveMipmapLevel(); | |
var _state = _renderer.state; | |
// Set GL state for depth map. | |
_state.setBlending( NoBlending ); | |
_state.buffers.color.setClear( 1, 1, 1, 1 ); | |
_state.buffers.depth.setTest( true ); | |
_state.setScissorTest( false ); | |
// render depth map | |
for ( var i = 0, il = lights.length; i < il; i ++ ) { | |
var light = lights[ i ]; | |
var shadow = light.shadow; | |
if ( shadow === undefined ) { | |
console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' ); | |
continue; | |
} | |
_shadowMapSize.copy( shadow.mapSize ); | |
var shadowFrameExtents = shadow.getFrameExtents(); | |
_shadowMapSize.multiply( shadowFrameExtents ); | |
_viewportSize.copy( shadow.mapSize ); | |
if ( _shadowMapSize.x > maxTextureSize || _shadowMapSize.y > maxTextureSize ) { | |
console.warn( 'THREE.WebGLShadowMap:', light, 'has shadow exceeding max texture size, reducing' ); | |
if ( _shadowMapSize.x > maxTextureSize ) { | |
_viewportSize.x = Math.floor( maxTextureSize / shadowFrameExtents.x ); | |
_shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x; | |
shadow.mapSize.x = _viewportSize.x; | |
} | |
if ( _shadowMapSize.y > maxTextureSize ) { | |
_viewportSize.y = Math.floor( maxTextureSize / shadowFrameExtents.y ); | |
_shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; | |
shadow.mapSize.y = _viewportSize.y; | |
} | |
} | |
if ( shadow.map === null && ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { | |
var pars = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat }; | |
shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); | |
shadow.map.texture.name = light.name + ".shadowMap"; | |
shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); | |
shadow.camera.updateProjectionMatrix(); | |
} | |
if ( shadow.map === null ) { | |
var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; | |
shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); | |
shadow.map.texture.name = light.name + ".shadowMap"; | |
shadow.camera.updateProjectionMatrix(); | |
} | |
_renderer.setRenderTarget( shadow.map ); | |
_renderer.clear(); | |
var viewportCount = shadow.getViewportCount(); | |
for ( var vp = 0; vp < viewportCount; vp ++ ) { | |
var viewport = shadow.getViewport( vp ); | |
_viewport.set( | |
_viewportSize.x * viewport.x, | |
_viewportSize.y * viewport.y, | |
_viewportSize.x * viewport.z, | |
_viewportSize.y * viewport.w | |
); | |
_state.viewport( _viewport ); | |
shadow.updateMatrices( light, vp ); | |
_frustum = shadow.getFrustum(); | |
renderObject( scene, camera, shadow.camera, light, this.type ); | |
} | |
// do blur pass for VSM | |
if ( ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { | |
VSMPass( shadow, camera ); | |
} | |
} | |
scope.needsUpdate = false; | |
_renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel ); | |
}; | |
function VSMPass( shadow, camera ) { | |
var geometry = _objects.update( fullScreenMesh ); | |
// vertical pass | |
shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; | |
shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; | |
shadowMaterialVertical.uniforms.radius.value = shadow.radius; | |
_renderer.setRenderTarget( shadow.mapPass ); | |
_renderer.clear(); | |
_renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null ); | |
// horizonal pass | |
shadowMaterialHorizonal.uniforms.shadow_pass.value = shadow.mapPass.texture; | |
shadowMaterialHorizonal.uniforms.resolution.value = shadow.mapSize; | |
shadowMaterialHorizonal.uniforms.radius.value = shadow.radius; | |
_renderer.setRenderTarget( shadow.map ); | |
_renderer.clear(); | |
_renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizonal, fullScreenMesh, null ); | |
} | |
function getDepthMaterialVariant( useMorphing, useSkinning, useInstancing ) { | |
var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2; | |
var material = _depthMaterials[ index ]; | |
if ( material === undefined ) { | |
material = new MeshDepthMaterial( { | |
depthPacking: RGBADepthPacking, | |
morphTargets: useMorphing, | |
skinning: useSkinning | |
} ); | |
_depthMaterials[ index ] = material; | |
} | |
return material; | |
} | |
function getDistanceMaterialVariant( useMorphing, useSkinning, useInstancing ) { | |
var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2; | |
var material = _distanceMaterials[ index ]; | |
if ( material === undefined ) { | |
material = new MeshDistanceMaterial( { | |
morphTargets: useMorphing, | |
skinning: useSkinning | |
} ); | |
_distanceMaterials[ index ] = material; | |
} | |
return material; | |
} | |
function getDepthMaterial( object, material, light, shadowCameraNear, shadowCameraFar, type ) { | |
var geometry = object.geometry; | |
var result = null; | |
var getMaterialVariant = getDepthMaterialVariant; | |
var customMaterial = object.customDepthMaterial; | |
if ( light.isPointLight === true ) { | |
getMaterialVariant = getDistanceMaterialVariant; | |
customMaterial = object.customDistanceMaterial; | |
} | |
if ( customMaterial === undefined ) { | |
var useMorphing = false; | |
if ( material.morphTargets === true ) { | |
if ( geometry.isBufferGeometry === true ) { | |
useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0; | |
} else if ( geometry.isGeometry === true ) { | |
useMorphing = geometry.morphTargets && geometry.morphTargets.length > 0; | |
} | |
} | |
var useSkinning = false; | |
if ( object.isSkinnedMesh === true ) { | |
if ( material.skinning === true ) { | |
useSkinning = true; | |
} else { | |
console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object ); | |
} | |
} | |
var useInstancing = object.isInstancedMesh === true; | |
result = getMaterialVariant( useMorphing, useSkinning, useInstancing ); | |
} else { | |
result = customMaterial; | |
} | |
if ( _renderer.localClippingEnabled && | |
material.clipShadows === true && | |
material.clippingPlanes.length !== 0 ) { | |
// in this case we need a unique material instance reflecting the | |
// appropriate state | |
var keyA = result.uuid, keyB = material.uuid; | |
var materialsForVariant = _materialCache[ keyA ]; | |
if ( materialsForVariant === undefined ) { | |
materialsForVariant = {}; | |
_materialCache[ keyA ] = materialsForVariant; | |
} | |
var cachedMaterial = materialsForVariant[ keyB ]; | |
if ( cachedMaterial === undefined ) { | |
cachedMaterial = result.clone(); | |
materialsForVariant[ keyB ] = cachedMaterial; | |
} | |
result = cachedMaterial; | |
} | |
result.visible = material.visible; | |
result.wireframe = material.wireframe; | |
if ( type === VSMShadowMap ) { | |
result.side = ( material.shadowSide !== null ) ? material.shadowSide : material.side; | |
} else { | |
result.side = ( material.shadowSide !== null ) ? material.shadowSide : shadowSide[ material.side ]; | |
} | |
result.clipShadows = material.clipShadows; | |
result.clippingPlanes = material.clippingPlanes; | |
result.clipIntersection = material.clipIntersection; | |
result.wireframeLinewidth = material.wireframeLinewidth; | |
result.linewidth = material.linewidth; | |
if ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) { | |
result.referencePosition.setFromMatrixPosition( light.matrixWorld ); | |
result.nearDistance = shadowCameraNear; | |
result.farDistance = shadowCameraFar; | |
} | |
return result; | |
} | |
function renderObject( object, camera, shadowCamera, light, type ) { | |
if ( object.visible === false ) { return; } | |
var visible = object.layers.test( camera.layers ); | |
if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) { | |
if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { | |
object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); | |
var geometry = _objects.update( object ); | |
var material = object.material; | |
if ( Array.isArray( material ) ) { | |
var groups = geometry.groups; | |
for ( var k = 0, kl = groups.length; k < kl; k ++ ) { | |
var group = groups[ k ]; | |
var groupMaterial = material[ group.materialIndex ]; | |
if ( groupMaterial && groupMaterial.visible ) { | |
var depthMaterial = getDepthMaterial( object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type ); | |
_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); | |
} | |
} | |
} else if ( material.visible ) { | |
var depthMaterial = getDepthMaterial( object, material, light, shadowCamera.near, shadowCamera.far, type ); | |
_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); | |
} | |
} | |
} | |
var children = object.children; | |
for ( var i = 0, l = children.length; i < l; i ++ ) { | |
renderObject( children[ i ], camera, shadowCamera, light, type ); | |
} | |
} | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLState( gl, extensions, capabilities ) { | |
var isWebGL2 = capabilities.isWebGL2; | |
function ColorBuffer() { | |
var locked = false; | |
var color = new Vector4(); | |
var currentColorMask = null; | |
var currentColorClear = new Vector4( 0, 0, 0, 0 ); | |
return { | |
setMask: function ( colorMask ) { | |
if ( currentColorMask !== colorMask && ! locked ) { | |
gl.colorMask( colorMask, colorMask, colorMask, colorMask ); | |
currentColorMask = colorMask; | |
} | |
}, | |
setLocked: function ( lock ) { | |
locked = lock; | |
}, | |
setClear: function ( r, g, b, a, premultipliedAlpha ) { | |
if ( premultipliedAlpha === true ) { | |
r *= a; g *= a; b *= a; | |
} | |
color.set( r, g, b, a ); | |
if ( currentColorClear.equals( color ) === false ) { | |
gl.clearColor( r, g, b, a ); | |
currentColorClear.copy( color ); | |
} | |
}, | |
reset: function () { | |
locked = false; | |
currentColorMask = null; | |
currentColorClear.set( - 1, 0, 0, 0 ); // set to invalid state | |
} | |
}; | |
} | |
function DepthBuffer() { | |
var locked = false; | |
var currentDepthMask = null; | |
var currentDepthFunc = null; | |
var currentDepthClear = null; | |
return { | |
setTest: function ( depthTest ) { | |
if ( depthTest ) { | |
enable( 2929 ); | |
} else { | |
disable( 2929 ); | |
} | |
}, | |
setMask: function ( depthMask ) { | |
if ( currentDepthMask !== depthMask && ! locked ) { | |
gl.depthMask( depthMask ); | |
currentDepthMask = depthMask; | |
} | |
}, | |
setFunc: function ( depthFunc ) { | |
if ( currentDepthFunc !== depthFunc ) { | |
if ( depthFunc ) { | |
switch ( depthFunc ) { | |
case NeverDepth: | |
gl.depthFunc( 512 ); | |
break; | |
case AlwaysDepth: | |
gl.depthFunc( 519 ); | |
break; | |
case LessDepth: | |
gl.depthFunc( 513 ); | |
break; | |
case LessEqualDepth: | |
gl.depthFunc( 515 ); | |
break; | |
case EqualDepth: | |
gl.depthFunc( 514 ); | |
break; | |
case GreaterEqualDepth: | |
gl.depthFunc( 518 ); | |
break; | |
case GreaterDepth: | |
gl.depthFunc( 516 ); | |
break; | |
case NotEqualDepth: | |
gl.depthFunc( 517 ); | |
break; | |
default: | |
gl.depthFunc( 515 ); | |
} | |
} else { | |
gl.depthFunc( 515 ); | |
} | |
currentDepthFunc = depthFunc; | |
} | |
}, | |
setLocked: function ( lock ) { | |
locked = lock; | |
}, | |
setClear: function ( depth ) { | |
if ( currentDepthClear !== depth ) { | |
gl.clearDepth( depth ); | |
currentDepthClear = depth; | |
} | |
}, | |
reset: function () { | |
locked = false; | |
currentDepthMask = null; | |
currentDepthFunc = null; | |
currentDepthClear = null; | |
} | |
}; | |
} | |
function StencilBuffer() { | |
var locked = false; | |
var currentStencilMask = null; | |
var currentStencilFunc = null; | |
var currentStencilRef = null; | |
var currentStencilFuncMask = null; | |
var currentStencilFail = null; | |
var currentStencilZFail = null; | |
var currentStencilZPass = null; | |
var currentStencilClear = null; | |
return { | |
setTest: function ( stencilTest ) { | |
if ( ! locked ) { | |
if ( stencilTest ) { | |
enable( 2960 ); | |
} else { | |
disable( 2960 ); | |
} | |
} | |
}, | |
setMask: function ( stencilMask ) { | |
if ( currentStencilMask !== stencilMask && ! locked ) { | |
gl.stencilMask( stencilMask ); | |
currentStencilMask = stencilMask; | |
} | |
}, | |
setFunc: function ( stencilFunc, stencilRef, stencilMask ) { | |
if ( currentStencilFunc !== stencilFunc || | |
currentStencilRef !== stencilRef || | |
currentStencilFuncMask !== stencilMask ) { | |
gl.stencilFunc( stencilFunc, stencilRef, stencilMask ); | |
currentStencilFunc = stencilFunc; | |
currentStencilRef = stencilRef; | |
currentStencilFuncMask = stencilMask; | |
} | |
}, | |
setOp: function ( stencilFail, stencilZFail, stencilZPass ) { | |
if ( currentStencilFail !== stencilFail || | |
currentStencilZFail !== stencilZFail || | |
currentStencilZPass !== stencilZPass ) { | |
gl.stencilOp( stencilFail, stencilZFail, stencilZPass ); | |
currentStencilFail = stencilFail; | |
currentStencilZFail = stencilZFail; | |
currentStencilZPass = stencilZPass; | |
} | |
}, | |
setLocked: function ( lock ) { | |
locked = lock; | |
}, | |
setClear: function ( stencil ) { | |
if ( currentStencilClear !== stencil ) { | |
gl.clearStencil( stencil ); | |
currentStencilClear = stencil; | |
} | |
}, | |
reset: function () { | |
locked = false; | |
currentStencilMask = null; | |
currentStencilFunc = null; | |
currentStencilRef = null; | |
currentStencilFuncMask = null; | |
currentStencilFail = null; | |
currentStencilZFail = null; | |
currentStencilZPass = null; | |
currentStencilClear = null; | |
} | |
}; | |
} | |
// | |
var colorBuffer = new ColorBuffer(); | |
var depthBuffer = new DepthBuffer(); | |
var stencilBuffer = new StencilBuffer(); | |
var maxVertexAttributes = gl.getParameter( 34921 ); | |
var newAttributes = new Uint8Array( maxVertexAttributes ); | |
var enabledAttributes = new Uint8Array( maxVertexAttributes ); | |
var attributeDivisors = new Uint8Array( maxVertexAttributes ); | |
var enabledCapabilities = {}; | |
var currentProgram = null; | |
var currentBlendingEnabled = null; | |
var currentBlending = null; | |
var currentBlendEquation = null; | |
var currentBlendSrc = null; | |
var currentBlendDst = null; | |
var currentBlendEquationAlpha = null; | |
var currentBlendSrcAlpha = null; | |
var currentBlendDstAlpha = null; | |
var currentPremultipledAlpha = false; | |
var currentFlipSided = null; | |
var currentCullFace = null; | |
var currentLineWidth = null; | |
var currentPolygonOffsetFactor = null; | |
var currentPolygonOffsetUnits = null; | |
var maxTextures = gl.getParameter( 35661 ); | |
var lineWidthAvailable = false; | |
var version = 0; | |
var glVersion = gl.getParameter( 7938 ); | |
if ( glVersion.indexOf( 'WebGL' ) !== - 1 ) { | |
version = parseFloat( /^WebGL\ ([0-9])/.exec( glVersion )[ 1 ] ); | |
lineWidthAvailable = ( version >= 1.0 ); | |
} else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) { | |
version = parseFloat( /^OpenGL\ ES\ ([0-9])/.exec( glVersion )[ 1 ] ); | |
lineWidthAvailable = ( version >= 2.0 ); | |
} | |
var currentTextureSlot = null; | |
var currentBoundTextures = {}; | |
var currentScissor = new Vector4(); | |
var currentViewport = new Vector4(); | |
function createTexture( type, target, count ) { | |
var data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4. | |
var texture = gl.createTexture(); | |
gl.bindTexture( type, texture ); | |
gl.texParameteri( type, 10241, 9728 ); | |
gl.texParameteri( type, 10240, 9728 ); | |
for ( var i = 0; i < count; i ++ ) { | |
gl.texImage2D( target + i, 0, 6408, 1, 1, 0, 6408, 5121, data ); | |
} | |
return texture; | |
} | |
var emptyTextures = {}; | |
emptyTextures[ 3553 ] = createTexture( 3553, 3553, 1 ); | |
emptyTextures[ 34067 ] = createTexture( 34067, 34069, 6 ); | |
// init | |
colorBuffer.setClear( 0, 0, 0, 1 ); | |
depthBuffer.setClear( 1 ); | |
stencilBuffer.setClear( 0 ); | |
enable( 2929 ); | |
depthBuffer.setFunc( LessEqualDepth ); | |
setFlipSided( false ); | |
setCullFace( CullFaceBack ); | |
enable( 2884 ); | |
setBlending( NoBlending ); | |
// | |
function initAttributes() { | |
for ( var i = 0, l = newAttributes.length; i < l; i ++ ) { | |
newAttributes[ i ] = 0; | |
} | |
} | |
function enableAttribute( attribute ) { | |
enableAttributeAndDivisor( attribute, 0 ); | |
} | |
function enableAttributeAndDivisor( attribute, meshPerAttribute ) { | |
newAttributes[ attribute ] = 1; | |
if ( enabledAttributes[ attribute ] === 0 ) { | |
gl.enableVertexAttribArray( attribute ); | |
enabledAttributes[ attribute ] = 1; | |
} | |
if ( attributeDivisors[ attribute ] !== meshPerAttribute ) { | |
var extension = isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' ); | |
extension[ isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute ); | |
attributeDivisors[ attribute ] = meshPerAttribute; | |
} | |
} | |
function disableUnusedAttributes() { | |
for ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) { | |
if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { | |
gl.disableVertexAttribArray( i ); | |
enabledAttributes[ i ] = 0; | |
} | |
} | |
} | |
function enable( id ) { | |
if ( enabledCapabilities[ id ] !== true ) { | |
gl.enable( id ); | |
enabledCapabilities[ id ] = true; | |
} | |
} | |
function disable( id ) { | |
if ( enabledCapabilities[ id ] !== false ) { | |
gl.disable( id ); | |
enabledCapabilities[ id ] = false; | |
} | |
} | |
function useProgram( program ) { | |
if ( currentProgram !== program ) { | |
gl.useProgram( program ); | |
currentProgram = program; | |
return true; | |
} | |
return false; | |
} | |
var equationToGL = {}; | |
equationToGL[ AddEquation ] = 32774; | |
equationToGL[ SubtractEquation ] = 32778; | |
equationToGL[ ReverseSubtractEquation ] = 32779; | |
if ( isWebGL2 ) { | |
equationToGL[ MinEquation ] = 32775; | |
equationToGL[ MaxEquation ] = 32776; | |
} else { | |
var extension = extensions.get( 'EXT_blend_minmax' ); | |
if ( extension !== null ) { | |
equationToGL[ MinEquation ] = extension.MIN_EXT; | |
equationToGL[ MaxEquation ] = extension.MAX_EXT; | |
} | |
} | |
var factorToGL = {}; | |
factorToGL[ ZeroFactor ] = 0; | |
factorToGL[ OneFactor ] = 1; | |
factorToGL[ SrcColorFactor ] = 768; | |
factorToGL[ SrcAlphaFactor ] = 770; | |
factorToGL[ SrcAlphaSaturateFactor ] = 776; | |
factorToGL[ DstColorFactor ] = 774; | |
factorToGL[ DstAlphaFactor ] = 772; | |
factorToGL[ OneMinusSrcColorFactor ] = 769; | |
factorToGL[ OneMinusSrcAlphaFactor ] = 771; | |
factorToGL[ OneMinusDstColorFactor ] = 775; | |
factorToGL[ OneMinusDstAlphaFactor ] = 773; | |
function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) { | |
if ( blending === NoBlending ) { | |
if ( currentBlendingEnabled ) { | |
disable( 3042 ); | |
currentBlendingEnabled = false; | |
} | |
return; | |
} | |
if ( ! currentBlendingEnabled ) { | |
enable( 3042 ); | |
currentBlendingEnabled = true; | |
} | |
if ( blending !== CustomBlending ) { | |
if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) { | |
if ( currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation ) { | |
gl.blendEquation( 32774 ); | |
currentBlendEquation = AddEquation; | |
currentBlendEquationAlpha = AddEquation; | |
} | |
if ( premultipliedAlpha ) { | |
switch ( blending ) { | |
case NormalBlending: | |
gl.blendFuncSeparate( 1, 771, 1, 771 ); | |
break; | |
case AdditiveBlending: | |
gl.blendFunc( 1, 1 ); | |
break; | |
case SubtractiveBlending: | |
gl.blendFuncSeparate( 0, 0, 769, 771 ); | |
break; | |
case MultiplyBlending: | |
gl.blendFuncSeparate( 0, 768, 0, 770 ); | |
break; | |
default: | |
console.error( 'THREE.WebGLState: Invalid blending: ', blending ); | |
break; | |
} | |
} else { | |
switch ( blending ) { | |
case NormalBlending: | |
gl.blendFuncSeparate( 770, 771, 1, 771 ); | |
break; | |
case AdditiveBlending: | |
gl.blendFunc( 770, 1 ); | |
break; | |
case SubtractiveBlending: | |
gl.blendFunc( 0, 769 ); | |
break; | |
case MultiplyBlending: | |
gl.blendFunc( 0, 768 ); | |
break; | |
default: | |
console.error( 'THREE.WebGLState: Invalid blending: ', blending ); | |
break; | |
} | |
} | |
currentBlendSrc = null; | |
currentBlendDst = null; | |
currentBlendSrcAlpha = null; | |
currentBlendDstAlpha = null; | |
currentBlending = blending; | |
currentPremultipledAlpha = premultipliedAlpha; | |
} | |
return; | |
} | |
// custom blending | |
blendEquationAlpha = blendEquationAlpha || blendEquation; | |
blendSrcAlpha = blendSrcAlpha || blendSrc; | |
blendDstAlpha = blendDstAlpha || blendDst; | |
if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { | |
gl.blendEquationSeparate( equationToGL[ blendEquation ], equationToGL[ blendEquationAlpha ] ); | |
currentBlendEquation = blendEquation; | |
currentBlendEquationAlpha = blendEquationAlpha; | |
} | |
if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { | |
gl.blendFuncSeparate( factorToGL[ blendSrc ], factorToGL[ blendDst ], factorToGL[ blendSrcAlpha ], factorToGL[ blendDstAlpha ] ); | |
currentBlendSrc = blendSrc; | |
currentBlendDst = blendDst; | |
currentBlendSrcAlpha = blendSrcAlpha; | |
currentBlendDstAlpha = blendDstAlpha; | |
} | |
currentBlending = blending; | |
currentPremultipledAlpha = null; | |
} | |
function setMaterial( material, frontFaceCW ) { | |
material.side === DoubleSide | |
? disable( 2884 ) | |
: enable( 2884 ); | |
var flipSided = ( material.side === BackSide ); | |
if ( frontFaceCW ) { flipSided = ! flipSided; } | |
setFlipSided( flipSided ); | |
( material.blending === NormalBlending && material.transparent === false ) | |
? setBlending( NoBlending ) | |
: setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ); | |
depthBuffer.setFunc( material.depthFunc ); | |
depthBuffer.setTest( material.depthTest ); | |
depthBuffer.setMask( material.depthWrite ); | |
colorBuffer.setMask( material.colorWrite ); | |
var stencilWrite = material.stencilWrite; | |
stencilBuffer.setTest( stencilWrite ); | |
if ( stencilWrite ) { | |
stencilBuffer.setMask( material.stencilWriteMask ); | |
stencilBuffer.setFunc( material.stencilFunc, material.stencilRef, material.stencilFuncMask ); | |
stencilBuffer.setOp( material.stencilFail, material.stencilZFail, material.stencilZPass ); | |
} | |
setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits ); | |
} | |
// | |
function setFlipSided( flipSided ) { | |
if ( currentFlipSided !== flipSided ) { | |
if ( flipSided ) { | |
gl.frontFace( 2304 ); | |
} else { | |
gl.frontFace( 2305 ); | |
} | |
currentFlipSided = flipSided; | |
} | |
} | |
function setCullFace( cullFace ) { | |
if ( cullFace !== CullFaceNone ) { | |
enable( 2884 ); | |
if ( cullFace !== currentCullFace ) { | |
if ( cullFace === CullFaceBack ) { | |
gl.cullFace( 1029 ); | |
} else if ( cullFace === CullFaceFront ) { | |
gl.cullFace( 1028 ); | |
} else { | |
gl.cullFace( 1032 ); | |
} | |
} | |
} else { | |
disable( 2884 ); | |
} | |
currentCullFace = cullFace; | |
} | |
function setLineWidth( width ) { | |
if ( width !== currentLineWidth ) { | |
if ( lineWidthAvailable ) { gl.lineWidth( width ); } | |
currentLineWidth = width; | |
} | |
} | |
function setPolygonOffset( polygonOffset, factor, units ) { | |
if ( polygonOffset ) { | |
enable( 32823 ); | |
if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) { | |
gl.polygonOffset( factor, units ); | |
currentPolygonOffsetFactor = factor; | |
currentPolygonOffsetUnits = units; | |
} | |
} else { | |
disable( 32823 ); | |
} | |
} | |
function setScissorTest( scissorTest ) { | |
if ( scissorTest ) { | |
enable( 3089 ); | |
} else { | |
disable( 3089 ); | |
} | |
} | |
// texture | |
function activeTexture( webglSlot ) { | |
if ( webglSlot === undefined ) { webglSlot = 33984 + maxTextures - 1; } | |
if ( currentTextureSlot !== webglSlot ) { | |
gl.activeTexture( webglSlot ); | |
currentTextureSlot = webglSlot; | |
} | |
} | |
function bindTexture( webglType, webglTexture ) { | |
if ( currentTextureSlot === null ) { | |
activeTexture(); | |
} | |
var boundTexture = currentBoundTextures[ currentTextureSlot ]; | |
if ( boundTexture === undefined ) { | |
boundTexture = { type: undefined, texture: undefined }; | |
currentBoundTextures[ currentTextureSlot ] = boundTexture; | |
} | |
if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { | |
gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] ); | |
boundTexture.type = webglType; | |
boundTexture.texture = webglTexture; | |
} | |
} | |
function unbindTexture() { | |
var boundTexture = currentBoundTextures[ currentTextureSlot ]; | |
if ( boundTexture !== undefined && boundTexture.type !== undefined ) { | |
gl.bindTexture( boundTexture.type, null ); | |
boundTexture.type = undefined; | |
boundTexture.texture = undefined; | |
} | |
} | |
function compressedTexImage2D() { | |
try { | |
gl.compressedTexImage2D.apply( gl, arguments ); | |
} catch ( error ) { | |
console.error( 'THREE.WebGLState:', error ); | |
} | |
} | |
function texImage2D() { | |
try { | |
gl.texImage2D.apply( gl, arguments ); | |
} catch ( error ) { | |
console.error( 'THREE.WebGLState:', error ); | |
} | |
} | |
function texImage3D() { | |
try { | |
gl.texImage3D.apply( gl, arguments ); | |
} catch ( error ) { | |
console.error( 'THREE.WebGLState:', error ); | |
} | |
} | |
// | |
function scissor( scissor ) { | |
if ( currentScissor.equals( scissor ) === false ) { | |
gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w ); | |
currentScissor.copy( scissor ); | |
} | |
} | |
function viewport( viewport ) { | |
if ( currentViewport.equals( viewport ) === false ) { | |
gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w ); | |
currentViewport.copy( viewport ); | |
} | |
} | |
// | |
function reset() { | |
for ( var i = 0; i < enabledAttributes.length; i ++ ) { | |
if ( enabledAttributes[ i ] === 1 ) { | |
gl.disableVertexAttribArray( i ); | |
enabledAttributes[ i ] = 0; | |
} | |
} | |
enabledCapabilities = {}; | |
currentTextureSlot = null; | |
currentBoundTextures = {}; | |
currentProgram = null; | |
currentBlending = null; | |
currentFlipSided = null; | |
currentCullFace = null; | |
colorBuffer.reset(); | |
depthBuffer.reset(); | |
stencilBuffer.reset(); | |
} | |
return { | |
buffers: { | |
color: colorBuffer, | |
depth: depthBuffer, | |
stencil: stencilBuffer | |
}, | |
initAttributes: initAttributes, | |
enableAttribute: enableAttribute, | |
enableAttributeAndDivisor: enableAttributeAndDivisor, | |
disableUnusedAttributes: disableUnusedAttributes, | |
enable: enable, | |
disable: disable, | |
useProgram: useProgram, | |
setBlending: setBlending, | |
setMaterial: setMaterial, | |
setFlipSided: setFlipSided, | |
setCullFace: setCullFace, | |
setLineWidth: setLineWidth, | |
setPolygonOffset: setPolygonOffset, | |
setScissorTest: setScissorTest, | |
activeTexture: activeTexture, | |
bindTexture: bindTexture, | |
unbindTexture: unbindTexture, | |
compressedTexImage2D: compressedTexImage2D, | |
texImage2D: texImage2D, | |
texImage3D: texImage3D, | |
scissor: scissor, | |
viewport: viewport, | |
reset: reset | |
}; | |
} | |
/** | |
* @author mrdoob / http://mrdoob.com/ | |
*/ | |
function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { | |
var isWebGL2 = capabilities.isWebGL2; | |
var maxTextures = capabilities.maxTextures; | |
var maxCubemapSize = capabilities.maxCubemapSize; | |
var maxTextureSize = capabilities.maxTextureSize; | |
var maxSamples = capabilities.maxSamples; | |
var _videoTextures = new WeakMap(); | |
var _canvas; | |
// cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas, | |
// also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")! | |
// Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d). | |
var useOffscreenCanvas = false; | |
try { | |
useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' | |
&& ( new OffscreenCanvas( 1, 1 ).getContext( "2d" ) ) !== null; | |
} catch ( err ) { | |
// Ignore any errors | |
} | |
function createCanvas( width, height ) { | |
// Use OffscreenCanvas when available. Specially needed in web workers | |
return useOffscreenCanvas ? | |
new OffscreenCanvas( width, height ) : | |
document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); | |
} | |
function resizeImage( image, needsPowerOfTwo, needsNewCanvas, maxSize ) { | |
var scale = 1; | |
// handle case if texture exceeds max size | |
if ( image.width > maxSize || image.height > maxSize ) { | |
scale = maxSize / Math.max( image.width, image.height ); | |
} | |
// only perform resize if necessary | |
if ( scale < 1 || needsPowerOfTwo === true ) { | |
// only perform resize for certain image types | |
if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) || | |
( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) || | |
( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) { | |
var floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor; | |
var width = floor( scale * image.width ); | |
var height = floor( scale * image.height ); | |
if ( _canvas === undefined ) { _canvas = createCanvas( width, height ); } | |
// cube textures can't reuse the same canvas | |
var canvas = needsNewCanvas ? createCanvas( width, height ) : _canvas; | |
canvas.width = width; | |
canvas.height = height; | |
var context = canvas.getContext( '2d' ); | |
context.drawImage( image, 0, 0, width, height ); | |
console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' ); | |
return canvas; | |
} else { | |
if ( 'data' in image ) { | |
console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' ); | |
} | |
return image; | |
} | |
} | |
return image; | |
} | |
function isPowerOfTwo( image ) { | |
return MathUtils.isPowerOfTwo( image.width ) && MathUtils.isPowerOfTwo( image.height ); | |
} | |
function textureNeedsPowerOfTwo( texture ) { | |
if ( isWebGL2 ) { return false; } | |
return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) || | |
( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ); | |
} | |
function textureNeedsGenerateMipmaps( texture, supportsMips ) { | |
return texture.generateMipmaps && supportsMips && | |
texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; | |
} | |
function generateMipmap( target, texture, width, height ) { | |
_gl.generateMipmap( target ); | |
var textureProperties = properties.get( texture ); | |
// Note: Math.log( x ) * Math.LOG2E used instead of Math.log2( x ) which is not supported by IE11 | |
textureProperties.__maxMipLevel = Math.log( Math.max( width, height ) ) * Math.LOG2E; | |
} | |
function getInternalFormat( internalFormatName, glFormat, glType ) { | |
if ( isWebGL2 === false ) { return glFormat; } | |
if ( internalFormatName !== null ) { | |
if ( _gl[ internalFormatName ] !== undefined ) { return _gl[ internalFormatName ]; } | |
console.warn( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'' ); | |
} | |
var internalFormat = glFormat; | |
if ( glFormat === 6403 ) { | |
if ( glType === 5126 ) { internalFormat = 33326; } | |
if ( glType === 5131 ) { internalFormat = 33325; } | |
if ( glType === 5121 ) { internalFormat = 33321; } | |
} | |
if ( glFormat === 6407 ) { | |
if ( glType === 5126 ) { internalFormat = 34837; } | |
if ( glType === 5131 ) { internalFormat = 34843; } | |
if ( glType === 5121 ) { internalFormat = 32849; } | |
} | |
if ( glFormat === 6408 ) { | |
if ( glType === 5126 ) { internalFormat = 34836; } | |
if ( glType === 5131 ) { internalFormat = 34842; } | |
if ( glType === 5121 ) { internalFormat = 32856; } | |
} | |
if ( internalFormat === 33325 || internalFormat === 33326 || | |
internalFormat === 34842 || internalFormat === 34836 ) { | |
extensions.get( 'EXT_color_buffer_float' ); | |
} | |
return internalFormat; | |
} | |
// Fallback filters for non-power-of-2 textures | |
function filterFallback( f ) { | |
if ( f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter ) { | |
return 9728; | |
} | |
return 9729; | |
} | |
// | |
function onTextureDispose( event ) { | |
var texture = event.target; | |
texture.removeEventListener( 'dispose', onTextureDispose ); | |
deallocateTexture( texture ); | |
if ( texture.isVideoTexture ) { | |
_videoTextures.delete( texture ); | |
} | |
info.memory.textures --; | |
} | |
function onRenderTargetDispose( event ) { | |
var renderTarget = event.target; | |
renderTarget.removeEventListener( 'dispose', onRenderTargetDispose ); | |
deallocateRenderTarget( renderTarget ); | |
info.memory.textures --; | |
} | |
// | |
function deallocateTexture( texture ) { | |
var textureProperties = properties.get( texture ); | |
if ( textureProperties.__webglInit === undefined ) { return; } | |
_gl.d |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment