/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a2, b2) => { for (var prop in b2 || (b2 = {})) if (__hasOwnProp.call(b2, prop)) __defNormalProp(a2, prop, b2[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b2)) { if (__propIsEnum.call(b2, prop)) __defNormalProp(a2, prop, b2[prop]); } return a2; }; var __spreadProps = (a2, b2) => __defProps(a2, __getOwnPropDescs(b2)); var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __commonJS = (cb2, mod) => function __require() { return mod || (0, cb2[Object.keys(cb2)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { __markAsModule(target); for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __reExport = (target, module2, desc) => { if (module2 && typeof module2 === "object" || typeof module2 === "function") { for (let key of __getOwnPropNames(module2)) if (!__hasOwnProp.call(target, key) && key !== "default") __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); } return target; }; var __toModule = (module2) => { return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); }; var __async = (__this, __arguments, generator) => { return new Promise((resolve2, reject2) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject2(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject2(e); } }; var step = (x) => x.done ? resolve2(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // node_modules/lex/lexer.js var require_lexer = __commonJS({ "node_modules/lex/lexer.js"(exports, module2) { if (typeof module2 === "object" && typeof module2.exports === "object") module2.exports = Lexer; Lexer.defunct = function(chr) { throw new Error("Unexpected character at index " + (this.index - 1) + ": " + chr); }; function Lexer(defunct) { if (typeof defunct !== "function") defunct = Lexer.defunct; var tokens = []; var rules = []; var remove = 0; this.state = 0; this.index = 0; this.input = ""; this.addRule = function(pattern, action, start) { var global2 = pattern.global; if (!global2) { var flags = "g"; if (pattern.multiline) flags += "m"; if (pattern.ignoreCase) flags += "i"; pattern = new RegExp(pattern.source, flags); } if (Object.prototype.toString.call(start) !== "[object Array]") start = [0]; rules.push({ pattern, global: global2, action, start }); return this; }; this.setInput = function(input) { remove = 0; this.state = 0; this.index = 0; tokens.length = 0; this.input = input; return this; }; this.lex = function() { if (tokens.length) return tokens.shift(); this.reject = true; while (this.index <= this.input.length) { var matches = scan.call(this).splice(remove); var index = this.index; while (matches.length) { if (this.reject) { var match = matches.shift(); var result = match.result; var length = match.length; this.index += length; this.reject = false; remove++; var token = match.action.apply(this, result); if (this.reject) this.index = result.index; else if (typeof token !== "undefined") { switch (Object.prototype.toString.call(token)) { case "[object Array]": tokens = token.slice(1); token = token[0]; default: if (length) remove = 0; return token; } } } else break; } var input = this.input; if (index < input.length) { if (this.reject) { remove = 0; var token = defunct.call(this, input.charAt(this.index++)); if (typeof token !== "undefined") { if (Object.prototype.toString.call(token) === "[object Array]") { tokens = token.slice(1); return token[0]; } else return token; } } else { if (this.index !== index) remove = 0; this.reject = true; } } else if (matches.length) this.reject = true; else break; } }; function scan() { var matches = []; var index = 0; var state = this.state; var lastIndex = this.index; var input = this.input; for (var i = 0, length = rules.length; i < length; i++) { var rule = rules[i]; var start = rule.start; var states = start.length; if (!states || start.indexOf(state) >= 0 || state % 2 && states === 1 && !start[0]) { var pattern = rule.pattern; pattern.lastIndex = lastIndex; var result = pattern.exec(input); if (result && result.index === lastIndex) { var j = matches.push({ result, action: rule.action, length: result[0].length }); if (rule.global) index = j; while (--j > index) { var k = j - 1; if (matches[j].length > matches[k].length) { var temple = matches[j]; matches[j] = matches[k]; matches[k] = temple; } } } } } return matches; } } } }); // node_modules/he/he.js var require_he = __commonJS({ "node_modules/he/he.js"(exports, module2) { (function(root) { var freeExports = typeof exports == "object" && exports; var freeModule = typeof module2 == "object" && module2 && module2.exports == freeExports && module2; var freeGlobal = typeof global == "object" && global; if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { root = freeGlobal; } var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; var regexAsciiWhitelist = /[\x01-\x7F]/g; var regexBmpWhitelist = /[\x01-\t\x0B\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g; var regexEncodeNonAscii = /<\u20D2|=\u20E5|>\u20D2|\u205F\u200A|\u219D\u0338|\u2202\u0338|\u2220\u20D2|\u2229\uFE00|\u222A\uFE00|\u223C\u20D2|\u223D\u0331|\u223E\u0333|\u2242\u0338|\u224B\u0338|\u224D\u20D2|\u224E\u0338|\u224F\u0338|\u2250\u0338|\u2261\u20E5|\u2264\u20D2|\u2265\u20D2|\u2266\u0338|\u2267\u0338|\u2268\uFE00|\u2269\uFE00|\u226A\u0338|\u226A\u20D2|\u226B\u0338|\u226B\u20D2|\u227F\u0338|\u2282\u20D2|\u2283\u20D2|\u228A\uFE00|\u228B\uFE00|\u228F\u0338|\u2290\u0338|\u2293\uFE00|\u2294\uFE00|\u22B4\u20D2|\u22B5\u20D2|\u22D8\u0338|\u22D9\u0338|\u22DA\uFE00|\u22DB\uFE00|\u22F5\u0338|\u22F9\u0338|\u2933\u0338|\u29CF\u0338|\u29D0\u0338|\u2A6D\u0338|\u2A70\u0338|\u2A7D\u0338|\u2A7E\u0338|\u2AA1\u0338|\u2AA2\u0338|\u2AAC\uFE00|\u2AAD\uFE00|\u2AAF\u0338|\u2AB0\u0338|\u2AC5\u0338|\u2AC6\u0338|\u2ACB\uFE00|\u2ACC\uFE00|\u2AFD\u20E5|[\xA0-\u0113\u0116-\u0122\u0124-\u012B\u012E-\u014D\u0150-\u017E\u0192\u01B5\u01F5\u0237\u02C6\u02C7\u02D8-\u02DD\u0311\u0391-\u03A1\u03A3-\u03A9\u03B1-\u03C9\u03D1\u03D2\u03D5\u03D6\u03DC\u03DD\u03F0\u03F1\u03F5\u03F6\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E\u045F\u2002-\u2005\u2007-\u2010\u2013-\u2016\u2018-\u201A\u201C-\u201E\u2020-\u2022\u2025\u2026\u2030-\u2035\u2039\u203A\u203E\u2041\u2043\u2044\u204F\u2057\u205F-\u2063\u20AC\u20DB\u20DC\u2102\u2105\u210A-\u2113\u2115-\u211E\u2122\u2124\u2127-\u2129\u212C\u212D\u212F-\u2131\u2133-\u2138\u2145-\u2148\u2153-\u215E\u2190-\u219B\u219D-\u21A7\u21A9-\u21AE\u21B0-\u21B3\u21B5-\u21B7\u21BA-\u21DB\u21DD\u21E4\u21E5\u21F5\u21FD-\u2205\u2207-\u2209\u220B\u220C\u220F-\u2214\u2216-\u2218\u221A\u221D-\u2238\u223A-\u2257\u2259\u225A\u225C\u225F-\u2262\u2264-\u228B\u228D-\u229B\u229D-\u22A5\u22A7-\u22B0\u22B2-\u22BB\u22BD-\u22DB\u22DE-\u22E3\u22E6-\u22F7\u22F9-\u22FE\u2305\u2306\u2308-\u2310\u2312\u2313\u2315\u2316\u231C-\u231F\u2322\u2323\u232D\u232E\u2336\u233D\u233F\u237C\u23B0\u23B1\u23B4-\u23B6\u23DC-\u23DF\u23E2\u23E7\u2423\u24C8\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2550-\u256C\u2580\u2584\u2588\u2591-\u2593\u25A1\u25AA\u25AB\u25AD\u25AE\u25B1\u25B3-\u25B5\u25B8\u25B9\u25BD-\u25BF\u25C2\u25C3\u25CA\u25CB\u25EC\u25EF\u25F8-\u25FC\u2605\u2606\u260E\u2640\u2642\u2660\u2663\u2665\u2666\u266A\u266D-\u266F\u2713\u2717\u2720\u2736\u2758\u2772\u2773\u27C8\u27C9\u27E6-\u27ED\u27F5-\u27FA\u27FC\u27FF\u2902-\u2905\u290C-\u2913\u2916\u2919-\u2920\u2923-\u292A\u2933\u2935-\u2939\u293C\u293D\u2945\u2948-\u294B\u294E-\u2976\u2978\u2979\u297B-\u297F\u2985\u2986\u298B-\u2996\u299A\u299C\u299D\u29A4-\u29B7\u29B9\u29BB\u29BC\u29BE-\u29C5\u29C9\u29CD-\u29D0\u29DC-\u29DE\u29E3-\u29E5\u29EB\u29F4\u29F6\u2A00-\u2A02\u2A04\u2A06\u2A0C\u2A0D\u2A10-\u2A17\u2A22-\u2A27\u2A29\u2A2A\u2A2D-\u2A31\u2A33-\u2A3C\u2A3F\u2A40\u2A42-\u2A4D\u2A50\u2A53-\u2A58\u2A5A-\u2A5D\u2A5F\u2A66\u2A6A\u2A6D-\u2A75\u2A77-\u2A9A\u2A9D-\u2AA2\u2AA4-\u2AB0\u2AB3-\u2AC8\u2ACB\u2ACC\u2ACF-\u2ADB\u2AE4\u2AE6-\u2AE9\u2AEB-\u2AF3\u2AFD\uFB00-\uFB04]|\uD835[\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDD6B]/g; var encodeMap = { "\xAD": "shy", "\u200C": "zwnj", "\u200D": "zwj", "\u200E": "lrm", "\u2063": "ic", "\u2062": "it", "\u2061": "af", "\u200F": "rlm", "\u200B": "ZeroWidthSpace", "\u2060": "NoBreak", "\u0311": "DownBreve", "\u20DB": "tdot", "\u20DC": "DotDot", " ": "Tab", "\n": "NewLine", "\u2008": "puncsp", "\u205F": "MediumSpace", "\u2009": "thinsp", "\u200A": "hairsp", "\u2004": "emsp13", "\u2002": "ensp", "\u2005": "emsp14", "\u2003": "emsp", "\u2007": "numsp", "\xA0": "nbsp", "\u205F\u200A": "ThickSpace", "\u203E": "oline", "_": "lowbar", "\u2010": "dash", "\u2013": "ndash", "\u2014": "mdash", "\u2015": "horbar", ",": "comma", ";": "semi", "\u204F": "bsemi", ":": "colon", "\u2A74": "Colone", "!": "excl", "\xA1": "iexcl", "?": "quest", "\xBF": "iquest", ".": "period", "\u2025": "nldr", "\u2026": "mldr", "\xB7": "middot", "'": "apos", "\u2018": "lsquo", "\u2019": "rsquo", "\u201A": "sbquo", "\u2039": "lsaquo", "\u203A": "rsaquo", '"': "quot", "\u201C": "ldquo", "\u201D": "rdquo", "\u201E": "bdquo", "\xAB": "laquo", "\xBB": "raquo", "(": "lpar", ")": "rpar", "[": "lsqb", "]": "rsqb", "{": "lcub", "}": "rcub", "\u2308": "lceil", "\u2309": "rceil", "\u230A": "lfloor", "\u230B": "rfloor", "\u2985": "lopar", "\u2986": "ropar", "\u298B": "lbrke", "\u298C": "rbrke", "\u298D": "lbrkslu", "\u298E": "rbrksld", "\u298F": "lbrksld", "\u2990": "rbrkslu", "\u2991": "langd", "\u2992": "rangd", "\u2993": "lparlt", "\u2994": "rpargt", "\u2995": "gtlPar", "\u2996": "ltrPar", "\u27E6": "lobrk", "\u27E7": "robrk", "\u27E8": "lang", "\u27E9": "rang", "\u27EA": "Lang", "\u27EB": "Rang", "\u27EC": "loang", "\u27ED": "roang", "\u2772": "lbbrk", "\u2773": "rbbrk", "\u2016": "Vert", "\xA7": "sect", "\xB6": "para", "@": "commat", "*": "ast", "/": "sol", "undefined": null, "&": "amp", "#": "num", "%": "percnt", "\u2030": "permil", "\u2031": "pertenk", "\u2020": "dagger", "\u2021": "Dagger", "\u2022": "bull", "\u2043": "hybull", "\u2032": "prime", "\u2033": "Prime", "\u2034": "tprime", "\u2057": "qprime", "\u2035": "bprime", "\u2041": "caret", "`": "grave", "\xB4": "acute", "\u02DC": "tilde", "^": "Hat", "\xAF": "macr", "\u02D8": "breve", "\u02D9": "dot", "\xA8": "die", "\u02DA": "ring", "\u02DD": "dblac", "\xB8": "cedil", "\u02DB": "ogon", "\u02C6": "circ", "\u02C7": "caron", "\xB0": "deg", "\xA9": "copy", "\xAE": "reg", "\u2117": "copysr", "\u2118": "wp", "\u211E": "rx", "\u2127": "mho", "\u2129": "iiota", "\u2190": "larr", "\u219A": "nlarr", "\u2192": "rarr", "\u219B": "nrarr", "\u2191": "uarr", "\u2193": "darr", "\u2194": "harr", "\u21AE": "nharr", "\u2195": "varr", "\u2196": "nwarr", "\u2197": "nearr", "\u2198": "searr", "\u2199": "swarr", "\u219D": "rarrw", "\u219D\u0338": "nrarrw", "\u219E": "Larr", "\u219F": "Uarr", "\u21A0": "Rarr", "\u21A1": "Darr", "\u21A2": "larrtl", "\u21A3": "rarrtl", "\u21A4": "mapstoleft", "\u21A5": "mapstoup", "\u21A6": "map", "\u21A7": "mapstodown", "\u21A9": "larrhk", "\u21AA": "rarrhk", "\u21AB": "larrlp", "\u21AC": "rarrlp", "\u21AD": "harrw", "\u21B0": "lsh", "\u21B1": "rsh", "\u21B2": "ldsh", "\u21B3": "rdsh", "\u21B5": "crarr", "\u21B6": "cularr", "\u21B7": "curarr", "\u21BA": "olarr", "\u21BB": "orarr", "\u21BC": "lharu", "\u21BD": "lhard", "\u21BE": "uharr", "\u21BF": "uharl", "\u21C0": "rharu", "\u21C1": "rhard", "\u21C2": "dharr", "\u21C3": "dharl", "\u21C4": "rlarr", "\u21C5": "udarr", "\u21C6": "lrarr", "\u21C7": "llarr", "\u21C8": "uuarr", "\u21C9": "rrarr", "\u21CA": "ddarr", "\u21CB": "lrhar", "\u21CC": "rlhar", "\u21D0": "lArr", "\u21CD": "nlArr", "\u21D1": "uArr", "\u21D2": "rArr", "\u21CF": "nrArr", "\u21D3": "dArr", "\u21D4": "iff", "\u21CE": "nhArr", "\u21D5": "vArr", "\u21D6": "nwArr", "\u21D7": "neArr", "\u21D8": "seArr", "\u21D9": "swArr", "\u21DA": "lAarr", "\u21DB": "rAarr", "\u21DD": "zigrarr", "\u21E4": "larrb", "\u21E5": "rarrb", "\u21F5": "duarr", "\u21FD": "loarr", "\u21FE": "roarr", "\u21FF": "hoarr", "\u2200": "forall", "\u2201": "comp", "\u2202": "part", "\u2202\u0338": "npart", "\u2203": "exist", "\u2204": "nexist", "\u2205": "empty", "\u2207": "Del", "\u2208": "in", "\u2209": "notin", "\u220B": "ni", "\u220C": "notni", "\u03F6": "bepsi", "\u220F": "prod", "\u2210": "coprod", "\u2211": "sum", "+": "plus", "\xB1": "pm", "\xF7": "div", "\xD7": "times", "<": "lt", "\u226E": "nlt", "<\u20D2": "nvlt", "=": "equals", "\u2260": "ne", "=\u20E5": "bne", "\u2A75": "Equal", ">": "gt", "\u226F": "ngt", ">\u20D2": "nvgt", "\xAC": "not", "|": "vert", "\xA6": "brvbar", "\u2212": "minus", "\u2213": "mp", "\u2214": "plusdo", "\u2044": "frasl", "\u2216": "setmn", "\u2217": "lowast", "\u2218": "compfn", "\u221A": "Sqrt", "\u221D": "prop", "\u221E": "infin", "\u221F": "angrt", "\u2220": "ang", "\u2220\u20D2": "nang", "\u2221": "angmsd", "\u2222": "angsph", "\u2223": "mid", "\u2224": "nmid", "\u2225": "par", "\u2226": "npar", "\u2227": "and", "\u2228": "or", "\u2229": "cap", "\u2229\uFE00": "caps", "\u222A": "cup", "\u222A\uFE00": "cups", "\u222B": "int", "\u222C": "Int", "\u222D": "tint", "\u2A0C": "qint", "\u222E": "oint", "\u222F": "Conint", "\u2230": "Cconint", "\u2231": "cwint", "\u2232": "cwconint", "\u2233": "awconint", "\u2234": "there4", "\u2235": "becaus", "\u2236": "ratio", "\u2237": "Colon", "\u2238": "minusd", "\u223A": "mDDot", "\u223B": "homtht", "\u223C": "sim", "\u2241": "nsim", "\u223C\u20D2": "nvsim", "\u223D": "bsim", "\u223D\u0331": "race", "\u223E": "ac", "\u223E\u0333": "acE", "\u223F": "acd", "\u2240": "wr", "\u2242": "esim", "\u2242\u0338": "nesim", "\u2243": "sime", "\u2244": "nsime", "\u2245": "cong", "\u2247": "ncong", "\u2246": "simne", "\u2248": "ap", "\u2249": "nap", "\u224A": "ape", "\u224B": "apid", "\u224B\u0338": "napid", "\u224C": "bcong", "\u224D": "CupCap", "\u226D": "NotCupCap", "\u224D\u20D2": "nvap", "\u224E": "bump", "\u224E\u0338": "nbump", "\u224F": "bumpe", "\u224F\u0338": "nbumpe", "\u2250": "doteq", "\u2250\u0338": "nedot", "\u2251": "eDot", "\u2252": "efDot", "\u2253": "erDot", "\u2254": "colone", "\u2255": "ecolon", "\u2256": "ecir", "\u2257": "cire", "\u2259": "wedgeq", "\u225A": "veeeq", "\u225C": "trie", "\u225F": "equest", "\u2261": "equiv", "\u2262": "nequiv", "\u2261\u20E5": "bnequiv", "\u2264": "le", "\u2270": "nle", "\u2264\u20D2": "nvle", "\u2265": "ge", "\u2271": "nge", "\u2265\u20D2": "nvge", "\u2266": "lE", "\u2266\u0338": "nlE", "\u2267": "gE", "\u2267\u0338": "ngE", "\u2268\uFE00": "lvnE", "\u2268": "lnE", "\u2269": "gnE", "\u2269\uFE00": "gvnE", "\u226A": "ll", "\u226A\u0338": "nLtv", "\u226A\u20D2": "nLt", "\u226B": "gg", "\u226B\u0338": "nGtv", "\u226B\u20D2": "nGt", "\u226C": "twixt", "\u2272": "lsim", "\u2274": "nlsim", "\u2273": "gsim", "\u2275": "ngsim", "\u2276": "lg", "\u2278": "ntlg", "\u2277": "gl", "\u2279": "ntgl", "\u227A": "pr", "\u2280": "npr", "\u227B": "sc", "\u2281": "nsc", "\u227C": "prcue", "\u22E0": "nprcue", "\u227D": "sccue", "\u22E1": "nsccue", "\u227E": "prsim", "\u227F": "scsim", "\u227F\u0338": "NotSucceedsTilde", "\u2282": "sub", "\u2284": "nsub", "\u2282\u20D2": "vnsub", "\u2283": "sup", "\u2285": "nsup", "\u2283\u20D2": "vnsup", "\u2286": "sube", "\u2288": "nsube", "\u2287": "supe", "\u2289": "nsupe", "\u228A\uFE00": "vsubne", "\u228A": "subne", "\u228B\uFE00": "vsupne", "\u228B": "supne", "\u228D": "cupdot", "\u228E": "uplus", "\u228F": "sqsub", "\u228F\u0338": "NotSquareSubset", "\u2290": "sqsup", "\u2290\u0338": "NotSquareSuperset", "\u2291": "sqsube", "\u22E2": "nsqsube", "\u2292": "sqsupe", "\u22E3": "nsqsupe", "\u2293": "sqcap", "\u2293\uFE00": "sqcaps", "\u2294": "sqcup", "\u2294\uFE00": "sqcups", "\u2295": "oplus", "\u2296": "ominus", "\u2297": "otimes", "\u2298": "osol", "\u2299": "odot", "\u229A": "ocir", "\u229B": "oast", "\u229D": "odash", "\u229E": "plusb", "\u229F": "minusb", "\u22A0": "timesb", "\u22A1": "sdotb", "\u22A2": "vdash", "\u22AC": "nvdash", "\u22A3": "dashv", "\u22A4": "top", "\u22A5": "bot", "\u22A7": "models", "\u22A8": "vDash", "\u22AD": "nvDash", "\u22A9": "Vdash", "\u22AE": "nVdash", "\u22AA": "Vvdash", "\u22AB": "VDash", "\u22AF": "nVDash", "\u22B0": "prurel", "\u22B2": "vltri", "\u22EA": "nltri", "\u22B3": "vrtri", "\u22EB": "nrtri", "\u22B4": "ltrie", "\u22EC": "nltrie", "\u22B4\u20D2": "nvltrie", "\u22B5": "rtrie", "\u22ED": "nrtrie", "\u22B5\u20D2": "nvrtrie", "\u22B6": "origof", "\u22B7": "imof", "\u22B8": "mumap", "\u22B9": "hercon", "\u22BA": "intcal", "\u22BB": "veebar", "\u22BD": "barvee", "\u22BE": "angrtvb", "\u22BF": "lrtri", "\u22C0": "Wedge", "\u22C1": "Vee", "\u22C2": "xcap", "\u22C3": "xcup", "\u22C4": "diam", "\u22C5": "sdot", "\u22C6": "Star", "\u22C7": "divonx", "\u22C8": "bowtie", "\u22C9": "ltimes", "\u22CA": "rtimes", "\u22CB": "lthree", "\u22CC": "rthree", "\u22CD": "bsime", "\u22CE": "cuvee", "\u22CF": "cuwed", "\u22D0": "Sub", "\u22D1": "Sup", "\u22D2": "Cap", "\u22D3": "Cup", "\u22D4": "fork", "\u22D5": "epar", "\u22D6": "ltdot", "\u22D7": "gtdot", "\u22D8": "Ll", "\u22D8\u0338": "nLl", "\u22D9": "Gg", "\u22D9\u0338": "nGg", "\u22DA\uFE00": "lesg", "\u22DA": "leg", "\u22DB": "gel", "\u22DB\uFE00": "gesl", "\u22DE": "cuepr", "\u22DF": "cuesc", "\u22E6": "lnsim", "\u22E7": "gnsim", "\u22E8": "prnsim", "\u22E9": "scnsim", "\u22EE": "vellip", "\u22EF": "ctdot", "\u22F0": "utdot", "\u22F1": "dtdot", "\u22F2": "disin", "\u22F3": "isinsv", "\u22F4": "isins", "\u22F5": "isindot", "\u22F5\u0338": "notindot", "\u22F6": "notinvc", "\u22F7": "notinvb", "\u22F9": "isinE", "\u22F9\u0338": "notinE", "\u22FA": "nisd", "\u22FB": "xnis", "\u22FC": "nis", "\u22FD": "notnivc", "\u22FE": "notnivb", "\u2305": "barwed", "\u2306": "Barwed", "\u230C": "drcrop", "\u230D": "dlcrop", "\u230E": "urcrop", "\u230F": "ulcrop", "\u2310": "bnot", "\u2312": "profline", "\u2313": "profsurf", "\u2315": "telrec", "\u2316": "target", "\u231C": "ulcorn", "\u231D": "urcorn", "\u231E": "dlcorn", "\u231F": "drcorn", "\u2322": "frown", "\u2323": "smile", "\u232D": "cylcty", "\u232E": "profalar", "\u2336": "topbot", "\u233D": "ovbar", "\u233F": "solbar", "\u237C": "angzarr", "\u23B0": "lmoust", "\u23B1": "rmoust", "\u23B4": "tbrk", "\u23B5": "bbrk", "\u23B6": "bbrktbrk", "\u23DC": "OverParenthesis", "\u23DD": "UnderParenthesis", "\u23DE": "OverBrace", "\u23DF": "UnderBrace", "\u23E2": "trpezium", "\u23E7": "elinters", "\u2423": "blank", "\u2500": "boxh", "\u2502": "boxv", "\u250C": "boxdr", "\u2510": "boxdl", "\u2514": "boxur", "\u2518": "boxul", "\u251C": "boxvr", "\u2524": "boxvl", "\u252C": "boxhd", "\u2534": "boxhu", "\u253C": "boxvh", "\u2550": "boxH", "\u2551": "boxV", "\u2552": "boxdR", "\u2553": "boxDr", "\u2554": "boxDR", "\u2555": "boxdL", "\u2556": "boxDl", "\u2557": "boxDL", "\u2558": "boxuR", "\u2559": "boxUr", "\u255A": "boxUR", "\u255B": "boxuL", "\u255C": "boxUl", "\u255D": "boxUL", "\u255E": "boxvR", "\u255F": "boxVr", "\u2560": "boxVR", "\u2561": "boxvL", "\u2562": "boxVl", "\u2563": "boxVL", "\u2564": "boxHd", "\u2565": "boxhD", "\u2566": "boxHD", "\u2567": "boxHu", "\u2568": "boxhU", "\u2569": "boxHU", "\u256A": "boxvH", "\u256B": "boxVh", "\u256C": "boxVH", "\u2580": "uhblk", "\u2584": "lhblk", "\u2588": "block", "\u2591": "blk14", "\u2592": "blk12", "\u2593": "blk34", "\u25A1": "squ", "\u25AA": "squf", "\u25AB": "EmptyVerySmallSquare", "\u25AD": "rect", "\u25AE": "marker", "\u25B1": "fltns", "\u25B3": "xutri", "\u25B4": "utrif", "\u25B5": "utri", "\u25B8": "rtrif", "\u25B9": "rtri", "\u25BD": "xdtri", "\u25BE": "dtrif", "\u25BF": "dtri", "\u25C2": "ltrif", "\u25C3": "ltri", "\u25CA": "loz", "\u25CB": "cir", "\u25EC": "tridot", "\u25EF": "xcirc", "\u25F8": "ultri", "\u25F9": "urtri", "\u25FA": "lltri", "\u25FB": "EmptySmallSquare", "\u25FC": "FilledSmallSquare", "\u2605": "starf", "\u2606": "star", "\u260E": "phone", "\u2640": "female", "\u2642": "male", "\u2660": "spades", "\u2663": "clubs", "\u2665": "hearts", "\u2666": "diams", "\u266A": "sung", "\u2713": "check", "\u2717": "cross", "\u2720": "malt", "\u2736": "sext", "\u2758": "VerticalSeparator", "\u27C8": "bsolhsub", "\u27C9": "suphsol", "\u27F5": "xlarr", "\u27F6": "xrarr", "\u27F7": "xharr", "\u27F8": "xlArr", "\u27F9": "xrArr", "\u27FA": "xhArr", "\u27FC": "xmap", "\u27FF": "dzigrarr", "\u2902": "nvlArr", "\u2903": "nvrArr", "\u2904": "nvHarr", "\u2905": "Map", "\u290C": "lbarr", "\u290D": "rbarr", "\u290E": "lBarr", "\u290F": "rBarr", "\u2910": "RBarr", "\u2911": "DDotrahd", "\u2912": "UpArrowBar", "\u2913": "DownArrowBar", "\u2916": "Rarrtl", "\u2919": "latail", "\u291A": "ratail", "\u291B": "lAtail", "\u291C": "rAtail", "\u291D": "larrfs", "\u291E": "rarrfs", "\u291F": "larrbfs", "\u2920": "rarrbfs", "\u2923": "nwarhk", "\u2924": "nearhk", "\u2925": "searhk", "\u2926": "swarhk", "\u2927": "nwnear", "\u2928": "toea", "\u2929": "tosa", "\u292A": "swnwar", "\u2933": "rarrc", "\u2933\u0338": "nrarrc", "\u2935": "cudarrr", "\u2936": "ldca", "\u2937": "rdca", "\u2938": "cudarrl", "\u2939": "larrpl", "\u293C": "curarrm", "\u293D": "cularrp", "\u2945": "rarrpl", "\u2948": "harrcir", "\u2949": "Uarrocir", "\u294A": "lurdshar", "\u294B": "ldrushar", "\u294E": "LeftRightVector", "\u294F": "RightUpDownVector", "\u2950": "DownLeftRightVector", "\u2951": "LeftUpDownVector", "\u2952": "LeftVectorBar", "\u2953": "RightVectorBar", "\u2954": "RightUpVectorBar", "\u2955": "RightDownVectorBar", "\u2956": "DownLeftVectorBar", "\u2957": "DownRightVectorBar", "\u2958": "LeftUpVectorBar", "\u2959": "LeftDownVectorBar", "\u295A": "LeftTeeVector", "\u295B": "RightTeeVector", "\u295C": "RightUpTeeVector", "\u295D": "RightDownTeeVector", "\u295E": "DownLeftTeeVector", "\u295F": "DownRightTeeVector", "\u2960": "LeftUpTeeVector", "\u2961": "LeftDownTeeVector", "\u2962": "lHar", "\u2963": "uHar", "\u2964": "rHar", "\u2965": "dHar", "\u2966": "luruhar", "\u2967": "ldrdhar", "\u2968": "ruluhar", "\u2969": "rdldhar", "\u296A": "lharul", "\u296B": "llhard", "\u296C": "rharul", "\u296D": "lrhard", "\u296E": "udhar", "\u296F": "duhar", "\u2970": "RoundImplies", "\u2971": "erarr", "\u2972": "simrarr", "\u2973": "larrsim", "\u2974": "rarrsim", "\u2975": "rarrap", "\u2976": "ltlarr", "\u2978": "gtrarr", "\u2979": "subrarr", "\u297B": "suplarr", "\u297C": "lfisht", "\u297D": "rfisht", "\u297E": "ufisht", "\u297F": "dfisht", "\u299A": "vzigzag", "\u299C": "vangrt", "\u299D": "angrtvbd", "\u29A4": "ange", "\u29A5": "range", "\u29A6": "dwangle", "\u29A7": "uwangle", "\u29A8": "angmsdaa", "\u29A9": "angmsdab", "\u29AA": "angmsdac", "\u29AB": "angmsdad", "\u29AC": "angmsdae", "\u29AD": "angmsdaf", "\u29AE": "angmsdag", "\u29AF": "angmsdah", "\u29B0": "bemptyv", "\u29B1": "demptyv", "\u29B2": "cemptyv", "\u29B3": "raemptyv", "\u29B4": "laemptyv", "\u29B5": "ohbar", "\u29B6": "omid", "\u29B7": "opar", "\u29B9": "operp", "\u29BB": "olcross", "\u29BC": "odsold", "\u29BE": "olcir", "\u29BF": "ofcir", "\u29C0": "olt", "\u29C1": "ogt", "\u29C2": "cirscir", "\u29C3": "cirE", "\u29C4": "solb", "\u29C5": "bsolb", "\u29C9": "boxbox", "\u29CD": "trisb", "\u29CE": "rtriltri", "\u29CF": "LeftTriangleBar", "\u29CF\u0338": "NotLeftTriangleBar", "\u29D0": "RightTriangleBar", "\u29D0\u0338": "NotRightTriangleBar", "\u29DC": "iinfin", "\u29DD": "infintie", "\u29DE": "nvinfin", "\u29E3": "eparsl", "\u29E4": "smeparsl", "\u29E5": "eqvparsl", "\u29EB": "lozf", "\u29F4": "RuleDelayed", "\u29F6": "dsol", "\u2A00": "xodot", "\u2A01": "xoplus", "\u2A02": "xotime", "\u2A04": "xuplus", "\u2A06": "xsqcup", "\u2A0D": "fpartint", "\u2A10": "cirfnint", "\u2A11": "awint", "\u2A12": "rppolint", "\u2A13": "scpolint", "\u2A14": "npolint", "\u2A15": "pointint", "\u2A16": "quatint", "\u2A17": "intlarhk", "\u2A22": "pluscir", "\u2A23": "plusacir", "\u2A24": "simplus", "\u2A25": "plusdu", "\u2A26": "plussim", "\u2A27": "plustwo", "\u2A29": "mcomma", "\u2A2A": "minusdu", "\u2A2D": "loplus", "\u2A2E": "roplus", "\u2A2F": "Cross", "\u2A30": "timesd", "\u2A31": "timesbar", "\u2A33": "smashp", "\u2A34": "lotimes", "\u2A35": "rotimes", "\u2A36": "otimesas", "\u2A37": "Otimes", "\u2A38": "odiv", "\u2A39": "triplus", "\u2A3A": "triminus", "\u2A3B": "tritime", "\u2A3C": "iprod", "\u2A3F": "amalg", "\u2A40": "capdot", "\u2A42": "ncup", "\u2A43": "ncap", "\u2A44": "capand", "\u2A45": "cupor", "\u2A46": "cupcap", "\u2A47": "capcup", "\u2A48": "cupbrcap", "\u2A49": "capbrcup", "\u2A4A": "cupcup", "\u2A4B": "capcap", "\u2A4C": "ccups", "\u2A4D": "ccaps", "\u2A50": "ccupssm", "\u2A53": "And", "\u2A54": "Or", "\u2A55": "andand", "\u2A56": "oror", "\u2A57": "orslope", "\u2A58": "andslope", "\u2A5A": "andv", "\u2A5B": "orv", "\u2A5C": "andd", "\u2A5D": "ord", "\u2A5F": "wedbar", "\u2A66": "sdote", "\u2A6A": "simdot", "\u2A6D": "congdot", "\u2A6D\u0338": "ncongdot", "\u2A6E": "easter", "\u2A6F": "apacir", "\u2A70": "apE", "\u2A70\u0338": "napE", "\u2A71": "eplus", "\u2A72": "pluse", "\u2A73": "Esim", "\u2A77": "eDDot", "\u2A78": "equivDD", "\u2A79": "ltcir", "\u2A7A": "gtcir", "\u2A7B": "ltquest", "\u2A7C": "gtquest", "\u2A7D": "les", "\u2A7D\u0338": "nles", "\u2A7E": "ges", "\u2A7E\u0338": "nges", "\u2A7F": "lesdot", "\u2A80": "gesdot", "\u2A81": "lesdoto", "\u2A82": "gesdoto", "\u2A83": "lesdotor", "\u2A84": "gesdotol", "\u2A85": "lap", "\u2A86": "gap", "\u2A87": "lne", "\u2A88": "gne", "\u2A89": "lnap", "\u2A8A": "gnap", "\u2A8B": "lEg", "\u2A8C": "gEl", "\u2A8D": "lsime", "\u2A8E": "gsime", "\u2A8F": "lsimg", "\u2A90": "gsiml", "\u2A91": "lgE", "\u2A92": "glE", "\u2A93": "lesges", "\u2A94": "gesles", "\u2A95": "els", "\u2A96": "egs", "\u2A97": "elsdot", "\u2A98": "egsdot", "\u2A99": "el", "\u2A9A": "eg", "\u2A9D": "siml", "\u2A9E": "simg", "\u2A9F": "simlE", "\u2AA0": "simgE", "\u2AA1": "LessLess", "\u2AA1\u0338": "NotNestedLessLess", "\u2AA2": "GreaterGreater", "\u2AA2\u0338": "NotNestedGreaterGreater", "\u2AA4": "glj", "\u2AA5": "gla", "\u2AA6": "ltcc", "\u2AA7": "gtcc", "\u2AA8": "lescc", "\u2AA9": "gescc", "\u2AAA": "smt", "\u2AAB": "lat", "\u2AAC": "smte", "\u2AAC\uFE00": "smtes", "\u2AAD": "late", "\u2AAD\uFE00": "lates", "\u2AAE": "bumpE", "\u2AAF": "pre", "\u2AAF\u0338": "npre", "\u2AB0": "sce", "\u2AB0\u0338": "nsce", "\u2AB3": "prE", "\u2AB4": "scE", "\u2AB5": "prnE", "\u2AB6": "scnE", "\u2AB7": "prap", "\u2AB8": "scap", "\u2AB9": "prnap", "\u2ABA": "scnap", "\u2ABB": "Pr", "\u2ABC": "Sc", "\u2ABD": "subdot", "\u2ABE": "supdot", "\u2ABF": "subplus", "\u2AC0": "supplus", "\u2AC1": "submult", "\u2AC2": "supmult", "\u2AC3": "subedot", "\u2AC4": "supedot", "\u2AC5": "subE", "\u2AC5\u0338": "nsubE", "\u2AC6": "supE", "\u2AC6\u0338": "nsupE", "\u2AC7": "subsim", "\u2AC8": "supsim", "\u2ACB\uFE00": "vsubnE", "\u2ACB": "subnE", "\u2ACC\uFE00": "vsupnE", "\u2ACC": "supnE", "\u2ACF": "csub", "\u2AD0": "csup", "\u2AD1": "csube", "\u2AD2": "csupe", "\u2AD3": "subsup", "\u2AD4": "supsub", "\u2AD5": "subsub", "\u2AD6": "supsup", "\u2AD7": "suphsub", "\u2AD8": "supdsub", "\u2AD9": "forkv", "\u2ADA": "topfork", "\u2ADB": "mlcp", "\u2AE4": "Dashv", "\u2AE6": "Vdashl", "\u2AE7": "Barv", "\u2AE8": "vBar", "\u2AE9": "vBarv", "\u2AEB": "Vbar", "\u2AEC": "Not", "\u2AED": "bNot", "\u2AEE": "rnmid", "\u2AEF": "cirmid", "\u2AF0": "midcir", "\u2AF1": "topcir", "\u2AF2": "nhpar", "\u2AF3": "parsim", "\u2AFD": "parsl", "\u2AFD\u20E5": "nparsl", "\u266D": "flat", "\u266E": "natur", "\u266F": "sharp", "\xA4": "curren", "\xA2": "cent", "$": "dollar", "\xA3": "pound", "\xA5": "yen", "\u20AC": "euro", "\xB9": "sup1", "\xBD": "half", "\u2153": "frac13", "\xBC": "frac14", "\u2155": "frac15", "\u2159": "frac16", "\u215B": "frac18", "\xB2": "sup2", "\u2154": "frac23", "\u2156": "frac25", "\xB3": "sup3", "\xBE": "frac34", "\u2157": "frac35", "\u215C": "frac38", "\u2158": "frac45", "\u215A": "frac56", "\u215D": "frac58", "\u215E": "frac78", "\u{1D4B6}": "ascr", "\u{1D552}": "aopf", "\u{1D51E}": "afr", "\u{1D538}": "Aopf", "\u{1D504}": "Afr", "\u{1D49C}": "Ascr", "\xAA": "ordf", "\xE1": "aacute", "\xC1": "Aacute", "\xE0": "agrave", "\xC0": "Agrave", "\u0103": "abreve", "\u0102": "Abreve", "\xE2": "acirc", "\xC2": "Acirc", "\xE5": "aring", "\xC5": "angst", "\xE4": "auml", "\xC4": "Auml", "\xE3": "atilde", "\xC3": "Atilde", "\u0105": "aogon", "\u0104": "Aogon", "\u0101": "amacr", "\u0100": "Amacr", "\xE6": "aelig", "\xC6": "AElig", "\u{1D4B7}": "bscr", "\u{1D553}": "bopf", "\u{1D51F}": "bfr", "\u{1D539}": "Bopf", "\u212C": "Bscr", "\u{1D505}": "Bfr", "\u{1D520}": "cfr", "\u{1D4B8}": "cscr", "\u{1D554}": "copf", "\u212D": "Cfr", "\u{1D49E}": "Cscr", "\u2102": "Copf", "\u0107": "cacute", "\u0106": "Cacute", "\u0109": "ccirc", "\u0108": "Ccirc", "\u010D": "ccaron", "\u010C": "Ccaron", "\u010B": "cdot", "\u010A": "Cdot", "\xE7": "ccedil", "\xC7": "Ccedil", "\u2105": "incare", "\u{1D521}": "dfr", "\u2146": "dd", "\u{1D555}": "dopf", "\u{1D4B9}": "dscr", "\u{1D49F}": "Dscr", "\u{1D507}": "Dfr", "\u2145": "DD", "\u{1D53B}": "Dopf", "\u010F": "dcaron", "\u010E": "Dcaron", "\u0111": "dstrok", "\u0110": "Dstrok", "\xF0": "eth", "\xD0": "ETH", "\u2147": "ee", "\u212F": "escr", "\u{1D522}": "efr", "\u{1D556}": "eopf", "\u2130": "Escr", "\u{1D508}": "Efr", "\u{1D53C}": "Eopf", "\xE9": "eacute", "\xC9": "Eacute", "\xE8": "egrave", "\xC8": "Egrave", "\xEA": "ecirc", "\xCA": "Ecirc", "\u011B": "ecaron", "\u011A": "Ecaron", "\xEB": "euml", "\xCB": "Euml", "\u0117": "edot", "\u0116": "Edot", "\u0119": "eogon", "\u0118": "Eogon", "\u0113": "emacr", "\u0112": "Emacr", "\u{1D523}": "ffr", "\u{1D557}": "fopf", "\u{1D4BB}": "fscr", "\u{1D509}": "Ffr", "\u{1D53D}": "Fopf", "\u2131": "Fscr", "\uFB00": "fflig", "\uFB03": "ffilig", "\uFB04": "ffllig", "\uFB01": "filig", "fj": "fjlig", "\uFB02": "fllig", "\u0192": "fnof", "\u210A": "gscr", "\u{1D558}": "gopf", "\u{1D524}": "gfr", "\u{1D4A2}": "Gscr", "\u{1D53E}": "Gopf", "\u{1D50A}": "Gfr", "\u01F5": "gacute", "\u011F": "gbreve", "\u011E": "Gbreve", "\u011D": "gcirc", "\u011C": "Gcirc", "\u0121": "gdot", "\u0120": "Gdot", "\u0122": "Gcedil", "\u{1D525}": "hfr", "\u210E": "planckh", "\u{1D4BD}": "hscr", "\u{1D559}": "hopf", "\u210B": "Hscr", "\u210C": "Hfr", "\u210D": "Hopf", "\u0125": "hcirc", "\u0124": "Hcirc", "\u210F": "hbar", "\u0127": "hstrok", "\u0126": "Hstrok", "\u{1D55A}": "iopf", "\u{1D526}": "ifr", "\u{1D4BE}": "iscr", "\u2148": "ii", "\u{1D540}": "Iopf", "\u2110": "Iscr", "\u2111": "Im", "\xED": "iacute", "\xCD": "Iacute", "\xEC": "igrave", "\xCC": "Igrave", "\xEE": "icirc", "\xCE": "Icirc", "\xEF": "iuml", "\xCF": "Iuml", "\u0129": "itilde", "\u0128": "Itilde", "\u0130": "Idot", "\u012F": "iogon", "\u012E": "Iogon", "\u012B": "imacr", "\u012A": "Imacr", "\u0133": "ijlig", "\u0132": "IJlig", "\u0131": "imath", "\u{1D4BF}": "jscr", "\u{1D55B}": "jopf", "\u{1D527}": "jfr", "\u{1D4A5}": "Jscr", "\u{1D50D}": "Jfr", "\u{1D541}": "Jopf", "\u0135": "jcirc", "\u0134": "Jcirc", "\u0237": "jmath", "\u{1D55C}": "kopf", "\u{1D4C0}": "kscr", "\u{1D528}": "kfr", "\u{1D4A6}": "Kscr", "\u{1D542}": "Kopf", "\u{1D50E}": "Kfr", "\u0137": "kcedil", "\u0136": "Kcedil", "\u{1D529}": "lfr", "\u{1D4C1}": "lscr", "\u2113": "ell", "\u{1D55D}": "lopf", "\u2112": "Lscr", "\u{1D50F}": "Lfr", "\u{1D543}": "Lopf", "\u013A": "lacute", "\u0139": "Lacute", "\u013E": "lcaron", "\u013D": "Lcaron", "\u013C": "lcedil", "\u013B": "Lcedil", "\u0142": "lstrok", "\u0141": "Lstrok", "\u0140": "lmidot", "\u013F": "Lmidot", "\u{1D52A}": "mfr", "\u{1D55E}": "mopf", "\u{1D4C2}": "mscr", "\u{1D510}": "Mfr", "\u{1D544}": "Mopf", "\u2133": "Mscr", "\u{1D52B}": "nfr", "\u{1D55F}": "nopf", "\u{1D4C3}": "nscr", "\u2115": "Nopf", "\u{1D4A9}": "Nscr", "\u{1D511}": "Nfr", "\u0144": "nacute", "\u0143": "Nacute", "\u0148": "ncaron", "\u0147": "Ncaron", "\xF1": "ntilde", "\xD1": "Ntilde", "\u0146": "ncedil", "\u0145": "Ncedil", "\u2116": "numero", "\u014B": "eng", "\u014A": "ENG", "\u{1D560}": "oopf", "\u{1D52C}": "ofr", "\u2134": "oscr", "\u{1D4AA}": "Oscr", "\u{1D512}": "Ofr", "\u{1D546}": "Oopf", "\xBA": "ordm", "\xF3": "oacute", "\xD3": "Oacute", "\xF2": "ograve", "\xD2": "Ograve", "\xF4": "ocirc", "\xD4": "Ocirc", "\xF6": "ouml", "\xD6": "Ouml", "\u0151": "odblac", "\u0150": "Odblac", "\xF5": "otilde", "\xD5": "Otilde", "\xF8": "oslash", "\xD8": "Oslash", "\u014D": "omacr", "\u014C": "Omacr", "\u0153": "oelig", "\u0152": "OElig", "\u{1D52D}": "pfr", "\u{1D4C5}": "pscr", "\u{1D561}": "popf", "\u2119": "Popf", "\u{1D513}": "Pfr", "\u{1D4AB}": "Pscr", "\u{1D562}": "qopf", "\u{1D52E}": "qfr", "\u{1D4C6}": "qscr", "\u{1D4AC}": "Qscr", "\u{1D514}": "Qfr", "\u211A": "Qopf", "\u0138": "kgreen", "\u{1D52F}": "rfr", "\u{1D563}": "ropf", "\u{1D4C7}": "rscr", "\u211B": "Rscr", "\u211C": "Re", "\u211D": "Ropf", "\u0155": "racute", "\u0154": "Racute", "\u0159": "rcaron", "\u0158": "Rcaron", "\u0157": "rcedil", "\u0156": "Rcedil", "\u{1D564}": "sopf", "\u{1D4C8}": "sscr", "\u{1D530}": "sfr", "\u{1D54A}": "Sopf", "\u{1D516}": "Sfr", "\u{1D4AE}": "Sscr", "\u24C8": "oS", "\u015B": "sacute", "\u015A": "Sacute", "\u015D": "scirc", "\u015C": "Scirc", "\u0161": "scaron", "\u0160": "Scaron", "\u015F": "scedil", "\u015E": "Scedil", "\xDF": "szlig", "\u{1D531}": "tfr", "\u{1D4C9}": "tscr", "\u{1D565}": "topf", "\u{1D4AF}": "Tscr", "\u{1D517}": "Tfr", "\u{1D54B}": "Topf", "\u0165": "tcaron", "\u0164": "Tcaron", "\u0163": "tcedil", "\u0162": "Tcedil", "\u2122": "trade", "\u0167": "tstrok", "\u0166": "Tstrok", "\u{1D4CA}": "uscr", "\u{1D566}": "uopf", "\u{1D532}": "ufr", "\u{1D54C}": "Uopf", "\u{1D518}": "Ufr", "\u{1D4B0}": "Uscr", "\xFA": "uacute", "\xDA": "Uacute", "\xF9": "ugrave", "\xD9": "Ugrave", "\u016D": "ubreve", "\u016C": "Ubreve", "\xFB": "ucirc", "\xDB": "Ucirc", "\u016F": "uring", "\u016E": "Uring", "\xFC": "uuml", "\xDC": "Uuml", "\u0171": "udblac", "\u0170": "Udblac", "\u0169": "utilde", "\u0168": "Utilde", "\u0173": "uogon", "\u0172": "Uogon", "\u016B": "umacr", "\u016A": "Umacr", "\u{1D533}": "vfr", "\u{1D567}": "vopf", "\u{1D4CB}": "vscr", "\u{1D519}": "Vfr", "\u{1D54D}": "Vopf", "\u{1D4B1}": "Vscr", "\u{1D568}": "wopf", "\u{1D4CC}": "wscr", "\u{1D534}": "wfr", "\u{1D4B2}": "Wscr", "\u{1D54E}": "Wopf", "\u{1D51A}": "Wfr", "\u0175": "wcirc", "\u0174": "Wcirc", "\u{1D535}": "xfr", "\u{1D4CD}": "xscr", "\u{1D569}": "xopf", "\u{1D54F}": "Xopf", "\u{1D51B}": "Xfr", "\u{1D4B3}": "Xscr", "\u{1D536}": "yfr", "\u{1D4CE}": "yscr", "\u{1D56A}": "yopf", "\u{1D4B4}": "Yscr", "\u{1D51C}": "Yfr", "\u{1D550}": "Yopf", "\xFD": "yacute", "\xDD": "Yacute", "\u0177": "ycirc", "\u0176": "Ycirc", "\xFF": "yuml", "\u0178": "Yuml", "\u{1D4CF}": "zscr", "\u{1D537}": "zfr", "\u{1D56B}": "zopf", "\u2128": "Zfr", "\u2124": "Zopf", "\u{1D4B5}": "Zscr", "\u017A": "zacute", "\u0179": "Zacute", "\u017E": "zcaron", "\u017D": "Zcaron", "\u017C": "zdot", "\u017B": "Zdot", "\u01B5": "imped", "\xFE": "thorn", "\xDE": "THORN", "\u0149": "napos", "\u03B1": "alpha", "\u0391": "Alpha", "\u03B2": "beta", "\u0392": "Beta", "\u03B3": "gamma", "\u0393": "Gamma", "\u03B4": "delta", "\u0394": "Delta", "\u03B5": "epsi", "\u03F5": "epsiv", "\u0395": "Epsilon", "\u03DD": "gammad", "\u03DC": "Gammad", "\u03B6": "zeta", "\u0396": "Zeta", "\u03B7": "eta", "\u0397": "Eta", "\u03B8": "theta", "\u03D1": "thetav", "\u0398": "Theta", "\u03B9": "iota", "\u0399": "Iota", "\u03BA": "kappa", "\u03F0": "kappav", "\u039A": "Kappa", "\u03BB": "lambda", "\u039B": "Lambda", "\u03BC": "mu", "\xB5": "micro", "\u039C": "Mu", "\u03BD": "nu", "\u039D": "Nu", "\u03BE": "xi", "\u039E": "Xi", "\u03BF": "omicron", "\u039F": "Omicron", "\u03C0": "pi", "\u03D6": "piv", "\u03A0": "Pi", "\u03C1": "rho", "\u03F1": "rhov", "\u03A1": "Rho", "\u03C3": "sigma", "\u03A3": "Sigma", "\u03C2": "sigmaf", "\u03C4": "tau", "\u03A4": "Tau", "\u03C5": "upsi", "\u03A5": "Upsilon", "\u03D2": "Upsi", "\u03C6": "phi", "\u03D5": "phiv", "\u03A6": "Phi", "\u03C7": "chi", "\u03A7": "Chi", "\u03C8": "psi", "\u03A8": "Psi", "\u03C9": "omega", "\u03A9": "ohm", "\u0430": "acy", "\u0410": "Acy", "\u0431": "bcy", "\u0411": "Bcy", "\u0432": "vcy", "\u0412": "Vcy", "\u0433": "gcy", "\u0413": "Gcy", "\u0453": "gjcy", "\u0403": "GJcy", "\u0434": "dcy", "\u0414": "Dcy", "\u0452": "djcy", "\u0402": "DJcy", "\u0435": "iecy", "\u0415": "IEcy", "\u0451": "iocy", "\u0401": "IOcy", "\u0454": "jukcy", "\u0404": "Jukcy", "\u0436": "zhcy", "\u0416": "ZHcy", "\u0437": "zcy", "\u0417": "Zcy", "\u0455": "dscy", "\u0405": "DScy", "\u0438": "icy", "\u0418": "Icy", "\u0456": "iukcy", "\u0406": "Iukcy", "\u0457": "yicy", "\u0407": "YIcy", "\u0439": "jcy", "\u0419": "Jcy", "\u0458": "jsercy", "\u0408": "Jsercy", "\u043A": "kcy", "\u041A": "Kcy", "\u045C": "kjcy", "\u040C": "KJcy", "\u043B": "lcy", "\u041B": "Lcy", "\u0459": "ljcy", "\u0409": "LJcy", "\u043C": "mcy", "\u041C": "Mcy", "\u043D": "ncy", "\u041D": "Ncy", "\u045A": "njcy", "\u040A": "NJcy", "\u043E": "ocy", "\u041E": "Ocy", "\u043F": "pcy", "\u041F": "Pcy", "\u0440": "rcy", "\u0420": "Rcy", "\u0441": "scy", "\u0421": "Scy", "\u0442": "tcy", "\u0422": "Tcy", "\u045B": "tshcy", "\u040B": "TSHcy", "\u0443": "ucy", "\u0423": "Ucy", "\u045E": "ubrcy", "\u040E": "Ubrcy", "\u0444": "fcy", "\u0424": "Fcy", "\u0445": "khcy", "\u0425": "KHcy", "\u0446": "tscy", "\u0426": "TScy", "\u0447": "chcy", "\u0427": "CHcy", "\u045F": "dzcy", "\u040F": "DZcy", "\u0448": "shcy", "\u0428": "SHcy", "\u0449": "shchcy", "\u0429": "SHCHcy", "\u044A": "hardcy", "\u042A": "HARDcy", "\u044B": "ycy", "\u042B": "Ycy", "\u044C": "softcy", "\u042C": "SOFTcy", "\u044D": "ecy", "\u042D": "Ecy", "\u044E": "yucy", "\u042E": "YUcy", "\u044F": "yacy", "\u042F": "YAcy", "\u2135": "aleph", "\u2136": "beth", "\u2137": "gimel", "\u2138": "daleth" }; var regexEscape = /["&'<>`]/g; var escapeMap = { '"': """, "&": "&", "'": "'", "<": "<", ">": ">", "`": "`" }; var regexInvalidEntity = /&#(?:[xX][^a-fA-F0-9]|[^0-9xX])/; var regexInvalidRawCodePoint = /[\0-\x08\x0B\x0E-\x1F\x7F-\x9F\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; var regexDecode = /&(CounterClockwiseContourIntegral|DoubleLongLeftRightArrow|ClockwiseContourIntegral|NotNestedGreaterGreater|NotSquareSupersetEqual|DiacriticalDoubleAcute|NotRightTriangleEqual|NotSucceedsSlantEqual|NotPrecedesSlantEqual|CloseCurlyDoubleQuote|NegativeVeryThinSpace|DoubleContourIntegral|FilledVerySmallSquare|CapitalDifferentialD|OpenCurlyDoubleQuote|EmptyVerySmallSquare|NestedGreaterGreater|DoubleLongRightArrow|NotLeftTriangleEqual|NotGreaterSlantEqual|ReverseUpEquilibrium|DoubleLeftRightArrow|NotSquareSubsetEqual|NotDoubleVerticalBar|RightArrowLeftArrow|NotGreaterFullEqual|NotRightTriangleBar|SquareSupersetEqual|DownLeftRightVector|DoubleLongLeftArrow|leftrightsquigarrow|LeftArrowRightArrow|NegativeMediumSpace|blacktriangleright|RightDownVectorBar|PrecedesSlantEqual|RightDoubleBracket|SucceedsSlantEqual|NotLeftTriangleBar|RightTriangleEqual|SquareIntersection|RightDownTeeVector|ReverseEquilibrium|NegativeThickSpace|longleftrightarrow|Longleftrightarrow|LongLeftRightArrow|DownRightTeeVector|DownRightVectorBar|GreaterSlantEqual|SquareSubsetEqual|LeftDownVectorBar|LeftDoubleBracket|VerticalSeparator|rightleftharpoons|NotGreaterGreater|NotSquareSuperset|blacktriangleleft|blacktriangledown|NegativeThinSpace|LeftDownTeeVector|NotLessSlantEqual|leftrightharpoons|DoubleUpDownArrow|DoubleVerticalBar|LeftTriangleEqual|FilledSmallSquare|twoheadrightarrow|NotNestedLessLess|DownLeftTeeVector|DownLeftVectorBar|RightAngleBracket|NotTildeFullEqual|NotReverseElement|RightUpDownVector|DiacriticalTilde|NotSucceedsTilde|circlearrowright|NotPrecedesEqual|rightharpoondown|DoubleRightArrow|NotSucceedsEqual|NonBreakingSpace|NotRightTriangle|LessEqualGreater|RightUpTeeVector|LeftAngleBracket|GreaterFullEqual|DownArrowUpArrow|RightUpVectorBar|twoheadleftarrow|GreaterEqualLess|downharpoonright|RightTriangleBar|ntrianglerighteq|NotSupersetEqual|LeftUpDownVector|DiacriticalAcute|rightrightarrows|vartriangleright|UpArrowDownArrow|DiacriticalGrave|UnderParenthesis|EmptySmallSquare|LeftUpVectorBar|leftrightarrows|DownRightVector|downharpoonleft|trianglerighteq|ShortRightArrow|OverParenthesis|DoubleLeftArrow|DoubleDownArrow|NotSquareSubset|bigtriangledown|ntrianglelefteq|UpperRightArrow|curvearrowright|vartriangleleft|NotLeftTriangle|nleftrightarrow|LowerRightArrow|NotHumpDownHump|NotGreaterTilde|rightthreetimes|LeftUpTeeVector|NotGreaterEqual|straightepsilon|LeftTriangleBar|rightsquigarrow|ContourIntegral|rightleftarrows|CloseCurlyQuote|RightDownVector|LeftRightVector|nLeftrightarrow|leftharpoondown|circlearrowleft|SquareSuperset|OpenCurlyQuote|hookrightarrow|HorizontalLine|DiacriticalDot|NotLessGreater|ntriangleright|DoubleRightTee|InvisibleComma|InvisibleTimes|LowerLeftArrow|DownLeftVector|NotSubsetEqual|curvearrowleft|trianglelefteq|NotVerticalBar|TildeFullEqual|downdownarrows|NotGreaterLess|RightTeeVector|ZeroWidthSpace|looparrowright|LongRightArrow|doublebarwedge|ShortLeftArrow|ShortDownArrow|RightVectorBar|GreaterGreater|ReverseElement|rightharpoonup|LessSlantEqual|leftthreetimes|upharpoonright|rightarrowtail|LeftDownVector|Longrightarrow|NestedLessLess|UpperLeftArrow|nshortparallel|leftleftarrows|leftrightarrow|Leftrightarrow|LeftRightArrow|longrightarrow|upharpoonleft|RightArrowBar|ApplyFunction|LeftTeeVector|leftarrowtail|NotEqualTilde|varsubsetneqq|varsupsetneqq|RightTeeArrow|SucceedsEqual|SucceedsTilde|LeftVectorBar|SupersetEqual|hookleftarrow|DifferentialD|VerticalTilde|VeryThinSpace|blacktriangle|bigtriangleup|LessFullEqual|divideontimes|leftharpoonup|UpEquilibrium|ntriangleleft|RightTriangle|measuredangle|shortparallel|longleftarrow|Longleftarrow|LongLeftArrow|DoubleLeftTee|Poincareplane|PrecedesEqual|triangleright|DoubleUpArrow|RightUpVector|fallingdotseq|looparrowleft|PrecedesTilde|NotTildeEqual|NotTildeTilde|smallsetminus|Proportional|triangleleft|triangledown|UnderBracket|NotHumpEqual|exponentiale|ExponentialE|NotLessTilde|HilbertSpace|RightCeiling|blacklozenge|varsupsetneq|HumpDownHump|GreaterEqual|VerticalLine|LeftTeeArrow|NotLessEqual|DownTeeArrow|LeftTriangle|varsubsetneq|Intersection|NotCongruent|DownArrowBar|LeftUpVector|LeftArrowBar|risingdotseq|GreaterTilde|RoundImplies|SquareSubset|ShortUpArrow|NotSuperset|quaternions|precnapprox|backepsilon|preccurlyeq|OverBracket|blacksquare|MediumSpace|VerticalBar|circledcirc|circleddash|CircleMinus|CircleTimes|LessGreater|curlyeqprec|curlyeqsucc|diamondsuit|UpDownArrow|Updownarrow|RuleDelayed|Rrightarrow|updownarrow|RightVector|nRightarrow|nrightarrow|eqslantless|LeftCeiling|Equilibrium|SmallCircle|expectation|NotSucceeds|thickapprox|GreaterLess|SquareUnion|NotPrecedes|NotLessLess|straightphi|succnapprox|succcurlyeq|SubsetEqual|sqsupseteq|Proportion|Laplacetrf|ImaginaryI|supsetneqq|NotGreater|gtreqqless|NotElement|ThickSpace|TildeEqual|TildeTilde|Fouriertrf|rmoustache|EqualTilde|eqslantgtr|UnderBrace|LeftVector|UpArrowBar|nLeftarrow|nsubseteqq|subsetneqq|nsupseteqq|nleftarrow|succapprox|lessapprox|UpTeeArrow|upuparrows|curlywedge|lesseqqgtr|varepsilon|varnothing|RightFloor|complement|CirclePlus|sqsubseteq|Lleftarrow|circledast|RightArrow|Rightarrow|rightarrow|lmoustache|Bernoullis|precapprox|mapstoleft|mapstodown|longmapsto|dotsquare|downarrow|DoubleDot|nsubseteq|supsetneq|leftarrow|nsupseteq|subsetneq|ThinSpace|ngeqslant|subseteqq|HumpEqual|NotSubset|triangleq|NotCupCap|lesseqgtr|heartsuit|TripleDot|Leftarrow|Coproduct|Congruent|varpropto|complexes|gvertneqq|LeftArrow|LessTilde|supseteqq|MinusPlus|CircleDot|nleqslant|NotExists|gtreqless|nparallel|UnionPlus|LeftFloor|checkmark|CenterDot|centerdot|Mellintrf|gtrapprox|bigotimes|OverBrace|spadesuit|therefore|pitchfork|rationals|PlusMinus|Backslash|Therefore|DownBreve|backsimeq|backprime|DownArrow|nshortmid|Downarrow|lvertneqq|eqvparsl|imagline|imagpart|infintie|integers|Integral|intercal|LessLess|Uarrocir|intlarhk|sqsupset|angmsdaf|sqsubset|llcorner|vartheta|cupbrcap|lnapprox|Superset|SuchThat|succnsim|succneqq|angmsdag|biguplus|curlyvee|trpezium|Succeeds|NotTilde|bigwedge|angmsdah|angrtvbd|triminus|cwconint|fpartint|lrcorner|smeparsl|subseteq|urcorner|lurdshar|laemptyv|DDotrahd|approxeq|ldrushar|awconint|mapstoup|backcong|shortmid|triangle|geqslant|gesdotol|timesbar|circledR|circledS|setminus|multimap|naturals|scpolint|ncongdot|RightTee|boxminus|gnapprox|boxtimes|andslope|thicksim|angmsdaa|varsigma|cirfnint|rtriltri|angmsdab|rppolint|angmsdac|barwedge|drbkarow|clubsuit|thetasym|bsolhsub|capbrcup|dzigrarr|doteqdot|DotEqual|dotminus|UnderBar|NotEqual|realpart|otimesas|ulcorner|hksearow|hkswarow|parallel|PartialD|elinters|emptyset|plusacir|bbrktbrk|angmsdad|pointint|bigoplus|angmsdae|Precedes|bigsqcup|varkappa|notindot|supseteq|precneqq|precnsim|profalar|profline|profsurf|leqslant|lesdotor|raemptyv|subplus|notnivb|notnivc|subrarr|zigrarr|vzigzag|submult|subedot|Element|between|cirscir|larrbfs|larrsim|lotimes|lbrksld|lbrkslu|lozenge|ldrdhar|dbkarow|bigcirc|epsilon|simrarr|simplus|ltquest|Epsilon|luruhar|gtquest|maltese|npolint|eqcolon|npreceq|bigodot|ddagger|gtrless|bnequiv|harrcir|ddotseq|equivDD|backsim|demptyv|nsqsube|nsqsupe|Upsilon|nsubset|upsilon|minusdu|nsucceq|swarrow|nsupset|coloneq|searrow|boxplus|napprox|natural|asympeq|alefsym|congdot|nearrow|bigstar|diamond|supplus|tritime|LeftTee|nvinfin|triplus|NewLine|nvltrie|nvrtrie|nwarrow|nexists|Diamond|ruluhar|Implies|supmult|angzarr|suplarr|suphsub|questeq|because|digamma|Because|olcross|bemptyv|omicron|Omicron|rotimes|NoBreak|intprod|angrtvb|orderof|uwangle|suphsol|lesdoto|orslope|DownTee|realine|cudarrl|rdldhar|OverBar|supedot|lessdot|supdsub|topfork|succsim|rbrkslu|rbrksld|pertenk|cudarrr|isindot|planckh|lessgtr|pluscir|gesdoto|plussim|plustwo|lesssim|cularrp|rarrsim|Cayleys|notinva|notinvb|notinvc|UpArrow|Uparrow|uparrow|NotLess|dwangle|precsim|Product|curarrm|Cconint|dotplus|rarrbfs|ccupssm|Cedilla|cemptyv|notniva|quatint|frac35|frac38|frac45|frac56|frac58|frac78|tridot|xoplus|gacute|gammad|Gammad|lfisht|lfloor|bigcup|sqsupe|gbreve|Gbreve|lharul|sqsube|sqcups|Gcedil|apacir|llhard|lmidot|Lmidot|lmoust|andand|sqcaps|approx|Abreve|spades|circeq|tprime|divide|topcir|Assign|topbot|gesdot|divonx|xuplus|timesd|gesles|atilde|solbar|SOFTcy|loplus|timesb|lowast|lowbar|dlcorn|dlcrop|softcy|dollar|lparlt|thksim|lrhard|Atilde|lsaquo|smashp|bigvee|thinsp|wreath|bkarow|lsquor|lstrok|Lstrok|lthree|ltimes|ltlarr|DotDot|simdot|ltrPar|weierp|xsqcup|angmsd|sigmav|sigmaf|zeetrf|Zcaron|zcaron|mapsto|vsupne|thetav|cirmid|marker|mcomma|Zacute|vsubnE|there4|gtlPar|vsubne|bottom|gtrarr|SHCHcy|shchcy|midast|midcir|middot|minusb|minusd|gtrdot|bowtie|sfrown|mnplus|models|colone|seswar|Colone|mstpos|searhk|gtrsim|nacute|Nacute|boxbox|telrec|hairsp|Tcedil|nbumpe|scnsim|ncaron|Ncaron|ncedil|Ncedil|hamilt|Scedil|nearhk|hardcy|HARDcy|tcedil|Tcaron|commat|nequiv|nesear|tcaron|target|hearts|nexist|varrho|scedil|Scaron|scaron|hellip|Sacute|sacute|hercon|swnwar|compfn|rtimes|rthree|rsquor|rsaquo|zacute|wedgeq|homtht|barvee|barwed|Barwed|rpargt|horbar|conint|swarhk|roplus|nltrie|hslash|hstrok|Hstrok|rmoust|Conint|bprime|hybull|hyphen|iacute|Iacute|supsup|supsub|supsim|varphi|coprod|brvbar|agrave|Supset|supset|igrave|Igrave|notinE|Agrave|iiiint|iinfin|copysr|wedbar|Verbar|vangrt|becaus|incare|verbar|inodot|bullet|drcorn|intcal|drcrop|cularr|vellip|Utilde|bumpeq|cupcap|dstrok|Dstrok|CupCap|cupcup|cupdot|eacute|Eacute|supdot|iquest|easter|ecaron|Ecaron|ecolon|isinsv|utilde|itilde|Itilde|curarr|succeq|Bumpeq|cacute|ulcrop|nparsl|Cacute|nprcue|egrave|Egrave|nrarrc|nrarrw|subsup|subsub|nrtrie|jsercy|nsccue|Jsercy|kappav|kcedil|Kcedil|subsim|ulcorn|nsimeq|egsdot|veebar|kgreen|capand|elsdot|Subset|subset|curren|aacute|lacute|Lacute|emptyv|ntilde|Ntilde|lagran|lambda|Lambda|capcap|Ugrave|langle|subdot|emsp13|numero|emsp14|nvdash|nvDash|nVdash|nVDash|ugrave|ufisht|nvHarr|larrfs|nvlArr|larrhk|larrlp|larrpl|nvrArr|Udblac|nwarhk|larrtl|nwnear|oacute|Oacute|latail|lAtail|sstarf|lbrace|odblac|Odblac|lbrack|udblac|odsold|eparsl|lcaron|Lcaron|ograve|Ograve|lcedil|Lcedil|Aacute|ssmile|ssetmn|squarf|ldquor|capcup|ominus|cylcty|rharul|eqcirc|dagger|rfloor|rfisht|Dagger|daleth|equals|origof|capdot|equest|dcaron|Dcaron|rdquor|oslash|Oslash|otilde|Otilde|otimes|Otimes|urcrop|Ubreve|ubreve|Yacute|Uacute|uacute|Rcedil|rcedil|urcorn|parsim|Rcaron|Vdashl|rcaron|Tstrok|percnt|period|permil|Exists|yacute|rbrack|rbrace|phmmat|ccaron|Ccaron|planck|ccedil|plankv|tstrok|female|plusdo|plusdu|ffilig|plusmn|ffllig|Ccedil|rAtail|dfisht|bernou|ratail|Rarrtl|rarrtl|angsph|rarrpl|rarrlp|rarrhk|xwedge|xotime|forall|ForAll|Vvdash|vsupnE|preceq|bigcap|frac12|frac13|frac14|primes|rarrfs|prnsim|frac15|Square|frac16|square|lesdot|frac18|frac23|propto|prurel|rarrap|rangle|puncsp|frac25|Racute|qprime|racute|lesges|frac34|abreve|AElig|eqsim|utdot|setmn|urtri|Equal|Uring|seArr|uring|searr|dashv|Dashv|mumap|nabla|iogon|Iogon|sdote|sdotb|scsim|napid|napos|equiv|natur|Acirc|dblac|erarr|nbump|iprod|erDot|ucirc|awint|esdot|angrt|ncong|isinE|scnap|Scirc|scirc|ndash|isins|Ubrcy|nearr|neArr|isinv|nedot|ubrcy|acute|Ycirc|iukcy|Iukcy|xutri|nesim|caret|jcirc|Jcirc|caron|twixt|ddarr|sccue|exist|jmath|sbquo|ngeqq|angst|ccaps|lceil|ngsim|UpTee|delta|Delta|rtrif|nharr|nhArr|nhpar|rtrie|jukcy|Jukcy|kappa|rsquo|Kappa|nlarr|nlArr|TSHcy|rrarr|aogon|Aogon|fflig|xrarr|tshcy|ccirc|nleqq|filig|upsih|nless|dharl|nlsim|fjlig|ropar|nltri|dharr|robrk|roarr|fllig|fltns|roang|rnmid|subnE|subne|lAarr|trisb|Ccirc|acirc|ccups|blank|VDash|forkv|Vdash|langd|cedil|blk12|blk14|laquo|strns|diams|notin|vDash|larrb|blk34|block|disin|uplus|vdash|vBarv|aelig|starf|Wedge|check|xrArr|lates|lbarr|lBarr|notni|lbbrk|bcong|frasl|lbrke|frown|vrtri|vprop|vnsup|gamma|Gamma|wedge|xodot|bdquo|srarr|doteq|ldquo|boxdl|boxdL|gcirc|Gcirc|boxDl|boxDL|boxdr|boxdR|boxDr|TRADE|trade|rlhar|boxDR|vnsub|npart|vltri|rlarr|boxhd|boxhD|nprec|gescc|nrarr|nrArr|boxHd|boxHD|boxhu|boxhU|nrtri|boxHu|clubs|boxHU|times|colon|Colon|gimel|xlArr|Tilde|nsime|tilde|nsmid|nspar|THORN|thorn|xlarr|nsube|nsubE|thkap|xhArr|comma|nsucc|boxul|boxuL|nsupe|nsupE|gneqq|gnsim|boxUl|boxUL|grave|boxur|boxuR|boxUr|boxUR|lescc|angle|bepsi|boxvh|varpi|boxvH|numsp|Theta|gsime|gsiml|theta|boxVh|boxVH|boxvl|gtcir|gtdot|boxvL|boxVl|boxVL|crarr|cross|Cross|nvsim|boxvr|nwarr|nwArr|sqsup|dtdot|Uogon|lhard|lharu|dtrif|ocirc|Ocirc|lhblk|duarr|odash|sqsub|Hacek|sqcup|llarr|duhar|oelig|OElig|ofcir|boxvR|uogon|lltri|boxVr|csube|uuarr|ohbar|csupe|ctdot|olarr|olcir|harrw|oline|sqcap|omacr|Omacr|omega|Omega|boxVR|aleph|lneqq|lnsim|loang|loarr|rharu|lobrk|hcirc|operp|oplus|rhard|Hcirc|orarr|Union|order|ecirc|Ecirc|cuepr|szlig|cuesc|breve|reals|eDDot|Breve|hoarr|lopar|utrif|rdquo|Umacr|umacr|efDot|swArr|ultri|alpha|rceil|ovbar|swarr|Wcirc|wcirc|smtes|smile|bsemi|lrarr|aring|parsl|lrhar|bsime|uhblk|lrtri|cupor|Aring|uharr|uharl|slarr|rbrke|bsolb|lsime|rbbrk|RBarr|lsimg|phone|rBarr|rbarr|icirc|lsquo|Icirc|emacr|Emacr|ratio|simne|plusb|simlE|simgE|simeq|pluse|ltcir|ltdot|empty|xharr|xdtri|iexcl|Alpha|ltrie|rarrw|pound|ltrif|xcirc|bumpe|prcue|bumpE|asymp|amacr|cuvee|Sigma|sigma|iiint|udhar|iiota|ijlig|IJlig|supnE|imacr|Imacr|prime|Prime|image|prnap|eogon|Eogon|rarrc|mdash|mDDot|cuwed|imath|supne|imped|Amacr|udarr|prsim|micro|rarrb|cwint|raquo|infin|eplus|range|rangd|Ucirc|radic|minus|amalg|veeeq|rAarr|epsiv|ycirc|quest|sharp|quot|zwnj|Qscr|race|qscr|Qopf|qopf|qint|rang|Rang|Zscr|zscr|Zopf|zopf|rarr|rArr|Rarr|Pscr|pscr|prop|prod|prnE|prec|ZHcy|zhcy|prap|Zeta|zeta|Popf|popf|Zdot|plus|zdot|Yuml|yuml|phiv|YUcy|yucy|Yscr|yscr|perp|Yopf|yopf|part|para|YIcy|Ouml|rcub|yicy|YAcy|rdca|ouml|osol|Oscr|rdsh|yacy|real|oscr|xvee|andd|rect|andv|Xscr|oror|ordm|ordf|xscr|ange|aopf|Aopf|rHar|Xopf|opar|Oopf|xopf|xnis|rhov|oopf|omid|xmap|oint|apid|apos|ogon|ascr|Ascr|odot|odiv|xcup|xcap|ocir|oast|nvlt|nvle|nvgt|nvge|nvap|Wscr|wscr|auml|ntlg|ntgl|nsup|nsub|nsim|Nscr|nscr|nsce|Wopf|ring|npre|wopf|npar|Auml|Barv|bbrk|Nopf|nopf|nmid|nLtv|beta|ropf|Ropf|Beta|beth|nles|rpar|nleq|bnot|bNot|nldr|NJcy|rscr|Rscr|Vscr|vscr|rsqb|njcy|bopf|nisd|Bopf|rtri|Vopf|nGtv|ngtr|vopf|boxh|boxH|boxv|nges|ngeq|boxV|bscr|scap|Bscr|bsim|Vert|vert|bsol|bull|bump|caps|cdot|ncup|scnE|ncap|nbsp|napE|Cdot|cent|sdot|Vbar|nang|vBar|chcy|Mscr|mscr|sect|semi|CHcy|Mopf|mopf|sext|circ|cire|mldr|mlcp|cirE|comp|shcy|SHcy|vArr|varr|cong|copf|Copf|copy|COPY|malt|male|macr|lvnE|cscr|ltri|sime|ltcc|simg|Cscr|siml|csub|Uuml|lsqb|lsim|uuml|csup|Lscr|lscr|utri|smid|lpar|cups|smte|lozf|darr|Lopf|Uscr|solb|lopf|sopf|Sopf|lneq|uscr|spar|dArr|lnap|Darr|dash|Sqrt|LJcy|ljcy|lHar|dHar|Upsi|upsi|diam|lesg|djcy|DJcy|leqq|dopf|Dopf|dscr|Dscr|dscy|ldsh|ldca|squf|DScy|sscr|Sscr|dsol|lcub|late|star|Star|Uopf|Larr|lArr|larr|uopf|dtri|dzcy|sube|subE|Lang|lang|Kscr|kscr|Kopf|kopf|KJcy|kjcy|KHcy|khcy|DZcy|ecir|edot|eDot|Jscr|jscr|succ|Jopf|jopf|Edot|uHar|emsp|ensp|Iuml|iuml|eopf|isin|Iscr|iscr|Eopf|epar|sung|epsi|escr|sup1|sup2|sup3|Iota|iota|supe|supE|Iopf|iopf|IOcy|iocy|Escr|esim|Esim|imof|Uarr|QUOT|uArr|uarr|euml|IEcy|iecy|Idot|Euml|euro|excl|Hscr|hscr|Hopf|hopf|TScy|tscy|Tscr|hbar|tscr|flat|tbrk|fnof|hArr|harr|half|fopf|Fopf|tdot|gvnE|fork|trie|gtcc|fscr|Fscr|gdot|gsim|Gscr|gscr|Gopf|gopf|gneq|Gdot|tosa|gnap|Topf|topf|geqq|toea|GJcy|gjcy|tint|gesl|mid|Sfr|ggg|top|ges|gla|glE|glj|geq|gne|gEl|gel|gnE|Gcy|gcy|gap|Tfr|tfr|Tcy|tcy|Hat|Tau|Ffr|tau|Tab|hfr|Hfr|ffr|Fcy|fcy|icy|Icy|iff|ETH|eth|ifr|Ifr|Eta|eta|int|Int|Sup|sup|ucy|Ucy|Sum|sum|jcy|ENG|ufr|Ufr|eng|Jcy|jfr|els|ell|egs|Efr|efr|Jfr|uml|kcy|Kcy|Ecy|ecy|kfr|Kfr|lap|Sub|sub|lat|lcy|Lcy|leg|Dot|dot|lEg|leq|les|squ|div|die|lfr|Lfr|lgE|Dfr|dfr|Del|deg|Dcy|dcy|lne|lnE|sol|loz|smt|Cup|lrm|cup|lsh|Lsh|sim|shy|map|Map|mcy|Mcy|mfr|Mfr|mho|gfr|Gfr|sfr|cir|Chi|chi|nap|Cfr|vcy|Vcy|cfr|Scy|scy|ncy|Ncy|vee|Vee|Cap|cap|nfr|scE|sce|Nfr|nge|ngE|nGg|vfr|Vfr|ngt|bot|nGt|nis|niv|Rsh|rsh|nle|nlE|bne|Bfr|bfr|nLl|nlt|nLt|Bcy|bcy|not|Not|rlm|wfr|Wfr|npr|nsc|num|ocy|ast|Ocy|ofr|xfr|Xfr|Ofr|ogt|ohm|apE|olt|Rho|ape|rho|Rfr|rfr|ord|REG|ang|reg|orv|And|and|AMP|Rcy|amp|Afr|ycy|Ycy|yen|yfr|Yfr|rcy|par|pcy|Pcy|pfr|Pfr|phi|Phi|afr|Acy|acy|zcy|Zcy|piv|acE|acd|zfr|Zfr|pre|prE|psi|Psi|qfr|Qfr|zwj|Or|ge|Gg|gt|gg|el|oS|lt|Lt|LT|Re|lg|gl|eg|ne|Im|it|le|DD|wp|wr|nu|Nu|dd|lE|Sc|sc|pi|Pi|ee|af|ll|Ll|rx|gE|xi|pm|Xi|ic|pr|Pr|in|ni|mp|mu|ac|Mu|or|ap|Gt|GT|ii);|&(Aacute|Agrave|Atilde|Ccedil|Eacute|Egrave|Iacute|Igrave|Ntilde|Oacute|Ograve|Oslash|Otilde|Uacute|Ugrave|Yacute|aacute|agrave|atilde|brvbar|ccedil|curren|divide|eacute|egrave|frac12|frac14|frac34|iacute|igrave|iquest|middot|ntilde|oacute|ograve|oslash|otilde|plusmn|uacute|ugrave|yacute|AElig|Acirc|Aring|Ecirc|Icirc|Ocirc|THORN|Ucirc|acirc|acute|aelig|aring|cedil|ecirc|icirc|iexcl|laquo|micro|ocirc|pound|raquo|szlig|thorn|times|ucirc|Auml|COPY|Euml|Iuml|Ouml|QUOT|Uuml|auml|cent|copy|euml|iuml|macr|nbsp|ordf|ordm|ouml|para|quot|sect|sup1|sup2|sup3|uuml|yuml|AMP|ETH|REG|amp|deg|eth|not|reg|shy|uml|yen|GT|LT|gt|lt)(?!;)([=a-zA-Z0-9]?)|&#([0-9]+)(;?)|&#[xX]([a-fA-F0-9]+)(;?)|&([0-9a-zA-Z]+)/g; var decodeMap = { "aacute": "\xE1", "Aacute": "\xC1", "abreve": "\u0103", "Abreve": "\u0102", "ac": "\u223E", "acd": "\u223F", "acE": "\u223E\u0333", "acirc": "\xE2", "Acirc": "\xC2", "acute": "\xB4", "acy": "\u0430", "Acy": "\u0410", "aelig": "\xE6", "AElig": "\xC6", "af": "\u2061", "afr": "\u{1D51E}", "Afr": "\u{1D504}", "agrave": "\xE0", "Agrave": "\xC0", "alefsym": "\u2135", "aleph": "\u2135", "alpha": "\u03B1", "Alpha": "\u0391", "amacr": "\u0101", "Amacr": "\u0100", "amalg": "\u2A3F", "amp": "&", "AMP": "&", "and": "\u2227", "And": "\u2A53", "andand": "\u2A55", "andd": "\u2A5C", "andslope": "\u2A58", "andv": "\u2A5A", "ang": "\u2220", "ange": "\u29A4", "angle": "\u2220", "angmsd": "\u2221", "angmsdaa": "\u29A8", "angmsdab": "\u29A9", "angmsdac": "\u29AA", "angmsdad": "\u29AB", "angmsdae": "\u29AC", "angmsdaf": "\u29AD", "angmsdag": "\u29AE", "angmsdah": "\u29AF", "angrt": "\u221F", "angrtvb": "\u22BE", "angrtvbd": "\u299D", "angsph": "\u2222", "angst": "\xC5", "angzarr": "\u237C", "aogon": "\u0105", "Aogon": "\u0104", "aopf": "\u{1D552}", "Aopf": "\u{1D538}", "ap": "\u2248", "apacir": "\u2A6F", "ape": "\u224A", "apE": "\u2A70", "apid": "\u224B", "apos": "'", "ApplyFunction": "\u2061", "approx": "\u2248", "approxeq": "\u224A", "aring": "\xE5", "Aring": "\xC5", "ascr": "\u{1D4B6}", "Ascr": "\u{1D49C}", "Assign": "\u2254", "ast": "*", "asymp": "\u2248", "asympeq": "\u224D", "atilde": "\xE3", "Atilde": "\xC3", "auml": "\xE4", "Auml": "\xC4", "awconint": "\u2233", "awint": "\u2A11", "backcong": "\u224C", "backepsilon": "\u03F6", "backprime": "\u2035", "backsim": "\u223D", "backsimeq": "\u22CD", "Backslash": "\u2216", "Barv": "\u2AE7", "barvee": "\u22BD", "barwed": "\u2305", "Barwed": "\u2306", "barwedge": "\u2305", "bbrk": "\u23B5", "bbrktbrk": "\u23B6", "bcong": "\u224C", "bcy": "\u0431", "Bcy": "\u0411", "bdquo": "\u201E", "becaus": "\u2235", "because": "\u2235", "Because": "\u2235", "bemptyv": "\u29B0", "bepsi": "\u03F6", "bernou": "\u212C", "Bernoullis": "\u212C", "beta": "\u03B2", "Beta": "\u0392", "beth": "\u2136", "between": "\u226C", "bfr": "\u{1D51F}", "Bfr": "\u{1D505}", "bigcap": "\u22C2", "bigcirc": "\u25EF", "bigcup": "\u22C3", "bigodot": "\u2A00", "bigoplus": "\u2A01", "bigotimes": "\u2A02", "bigsqcup": "\u2A06", "bigstar": "\u2605", "bigtriangledown": "\u25BD", "bigtriangleup": "\u25B3", "biguplus": "\u2A04", "bigvee": "\u22C1", "bigwedge": "\u22C0", "bkarow": "\u290D", "blacklozenge": "\u29EB", "blacksquare": "\u25AA", "blacktriangle": "\u25B4", "blacktriangledown": "\u25BE", "blacktriangleleft": "\u25C2", "blacktriangleright": "\u25B8", "blank": "\u2423", "blk12": "\u2592", "blk14": "\u2591", "blk34": "\u2593", "block": "\u2588", "bne": "=\u20E5", "bnequiv": "\u2261\u20E5", "bnot": "\u2310", "bNot": "\u2AED", "bopf": "\u{1D553}", "Bopf": "\u{1D539}", "bot": "\u22A5", "bottom": "\u22A5", "bowtie": "\u22C8", "boxbox": "\u29C9", "boxdl": "\u2510", "boxdL": "\u2555", "boxDl": "\u2556", "boxDL": "\u2557", "boxdr": "\u250C", "boxdR": "\u2552", "boxDr": "\u2553", "boxDR": "\u2554", "boxh": "\u2500", "boxH": "\u2550", "boxhd": "\u252C", "boxhD": "\u2565", "boxHd": "\u2564", "boxHD": "\u2566", "boxhu": "\u2534", "boxhU": "\u2568", "boxHu": "\u2567", "boxHU": "\u2569", "boxminus": "\u229F", "boxplus": "\u229E", "boxtimes": "\u22A0", "boxul": "\u2518", "boxuL": "\u255B", "boxUl": "\u255C", "boxUL": "\u255D", "boxur": "\u2514", "boxuR": "\u2558", "boxUr": "\u2559", "boxUR": "\u255A", "boxv": "\u2502", "boxV": "\u2551", "boxvh": "\u253C", "boxvH": "\u256A", "boxVh": "\u256B", "boxVH": "\u256C", "boxvl": "\u2524", "boxvL": "\u2561", "boxVl": "\u2562", "boxVL": "\u2563", "boxvr": "\u251C", "boxvR": "\u255E", "boxVr": "\u255F", "boxVR": "\u2560", "bprime": "\u2035", "breve": "\u02D8", "Breve": "\u02D8", "brvbar": "\xA6", "bscr": "\u{1D4B7}", "Bscr": "\u212C", "bsemi": "\u204F", "bsim": "\u223D", "bsime": "\u22CD", "bsol": "\\", "bsolb": "\u29C5", "bsolhsub": "\u27C8", "bull": "\u2022", "bullet": "\u2022", "bump": "\u224E", "bumpe": "\u224F", "bumpE": "\u2AAE", "bumpeq": "\u224F", "Bumpeq": "\u224E", "cacute": "\u0107", "Cacute": "\u0106", "cap": "\u2229", "Cap": "\u22D2", "capand": "\u2A44", "capbrcup": "\u2A49", "capcap": "\u2A4B", "capcup": "\u2A47", "capdot": "\u2A40", "CapitalDifferentialD": "\u2145", "caps": "\u2229\uFE00", "caret": "\u2041", "caron": "\u02C7", "Cayleys": "\u212D", "ccaps": "\u2A4D", "ccaron": "\u010D", "Ccaron": "\u010C", "ccedil": "\xE7", "Ccedil": "\xC7", "ccirc": "\u0109", "Ccirc": "\u0108", "Cconint": "\u2230", "ccups": "\u2A4C", "ccupssm": "\u2A50", "cdot": "\u010B", "Cdot": "\u010A", "cedil": "\xB8", "Cedilla": "\xB8", "cemptyv": "\u29B2", "cent": "\xA2", "centerdot": "\xB7", "CenterDot": "\xB7", "cfr": "\u{1D520}", "Cfr": "\u212D", "chcy": "\u0447", "CHcy": "\u0427", "check": "\u2713", "checkmark": "\u2713", "chi": "\u03C7", "Chi": "\u03A7", "cir": "\u25CB", "circ": "\u02C6", "circeq": "\u2257", "circlearrowleft": "\u21BA", "circlearrowright": "\u21BB", "circledast": "\u229B", "circledcirc": "\u229A", "circleddash": "\u229D", "CircleDot": "\u2299", "circledR": "\xAE", "circledS": "\u24C8", "CircleMinus": "\u2296", "CirclePlus": "\u2295", "CircleTimes": "\u2297", "cire": "\u2257", "cirE": "\u29C3", "cirfnint": "\u2A10", "cirmid": "\u2AEF", "cirscir": "\u29C2", "ClockwiseContourIntegral": "\u2232", "CloseCurlyDoubleQuote": "\u201D", "CloseCurlyQuote": "\u2019", "clubs": "\u2663", "clubsuit": "\u2663", "colon": ":", "Colon": "\u2237", "colone": "\u2254", "Colone": "\u2A74", "coloneq": "\u2254", "comma": ",", "commat": "@", "comp": "\u2201", "compfn": "\u2218", "complement": "\u2201", "complexes": "\u2102", "cong": "\u2245", "congdot": "\u2A6D", "Congruent": "\u2261", "conint": "\u222E", "Conint": "\u222F", "ContourIntegral": "\u222E", "copf": "\u{1D554}", "Copf": "\u2102", "coprod": "\u2210", "Coproduct": "\u2210", "copy": "\xA9", "COPY": "\xA9", "copysr": "\u2117", "CounterClockwiseContourIntegral": "\u2233", "crarr": "\u21B5", "cross": "\u2717", "Cross": "\u2A2F", "cscr": "\u{1D4B8}", "Cscr": "\u{1D49E}", "csub": "\u2ACF", "csube": "\u2AD1", "csup": "\u2AD0", "csupe": "\u2AD2", "ctdot": "\u22EF", "cudarrl": "\u2938", "cudarrr": "\u2935", "cuepr": "\u22DE", "cuesc": "\u22DF", "cularr": "\u21B6", "cularrp": "\u293D", "cup": "\u222A", "Cup": "\u22D3", "cupbrcap": "\u2A48", "cupcap": "\u2A46", "CupCap": "\u224D", "cupcup": "\u2A4A", "cupdot": "\u228D", "cupor": "\u2A45", "cups": "\u222A\uFE00", "curarr": "\u21B7", "curarrm": "\u293C", "curlyeqprec": "\u22DE", "curlyeqsucc": "\u22DF", "curlyvee": "\u22CE", "curlywedge": "\u22CF", "curren": "\xA4", "curvearrowleft": "\u21B6", "curvearrowright": "\u21B7", "cuvee": "\u22CE", "cuwed": "\u22CF", "cwconint": "\u2232", "cwint": "\u2231", "cylcty": "\u232D", "dagger": "\u2020", "Dagger": "\u2021", "daleth": "\u2138", "darr": "\u2193", "dArr": "\u21D3", "Darr": "\u21A1", "dash": "\u2010", "dashv": "\u22A3", "Dashv": "\u2AE4", "dbkarow": "\u290F", "dblac": "\u02DD", "dcaron": "\u010F", "Dcaron": "\u010E", "dcy": "\u0434", "Dcy": "\u0414", "dd": "\u2146", "DD": "\u2145", "ddagger": "\u2021", "ddarr": "\u21CA", "DDotrahd": "\u2911", "ddotseq": "\u2A77", "deg": "\xB0", "Del": "\u2207", "delta": "\u03B4", "Delta": "\u0394", "demptyv": "\u29B1", "dfisht": "\u297F", "dfr": "\u{1D521}", "Dfr": "\u{1D507}", "dHar": "\u2965", "dharl": "\u21C3", "dharr": "\u21C2", "DiacriticalAcute": "\xB4", "DiacriticalDot": "\u02D9", "DiacriticalDoubleAcute": "\u02DD", "DiacriticalGrave": "`", "DiacriticalTilde": "\u02DC", "diam": "\u22C4", "diamond": "\u22C4", "Diamond": "\u22C4", "diamondsuit": "\u2666", "diams": "\u2666", "die": "\xA8", "DifferentialD": "\u2146", "digamma": "\u03DD", "disin": "\u22F2", "div": "\xF7", "divide": "\xF7", "divideontimes": "\u22C7", "divonx": "\u22C7", "djcy": "\u0452", "DJcy": "\u0402", "dlcorn": "\u231E", "dlcrop": "\u230D", "dollar": "$", "dopf": "\u{1D555}", "Dopf": "\u{1D53B}", "dot": "\u02D9", "Dot": "\xA8", "DotDot": "\u20DC", "doteq": "\u2250", "doteqdot": "\u2251", "DotEqual": "\u2250", "dotminus": "\u2238", "dotplus": "\u2214", "dotsquare": "\u22A1", "doublebarwedge": "\u2306", "DoubleContourIntegral": "\u222F", "DoubleDot": "\xA8", "DoubleDownArrow": "\u21D3", "DoubleLeftArrow": "\u21D0", "DoubleLeftRightArrow": "\u21D4", "DoubleLeftTee": "\u2AE4", "DoubleLongLeftArrow": "\u27F8", "DoubleLongLeftRightArrow": "\u27FA", "DoubleLongRightArrow": "\u27F9", "DoubleRightArrow": "\u21D2", "DoubleRightTee": "\u22A8", "DoubleUpArrow": "\u21D1", "DoubleUpDownArrow": "\u21D5", "DoubleVerticalBar": "\u2225", "downarrow": "\u2193", "Downarrow": "\u21D3", "DownArrow": "\u2193", "DownArrowBar": "\u2913", "DownArrowUpArrow": "\u21F5", "DownBreve": "\u0311", "downdownarrows": "\u21CA", "downharpoonleft": "\u21C3", "downharpoonright": "\u21C2", "DownLeftRightVector": "\u2950", "DownLeftTeeVector": "\u295E", "DownLeftVector": "\u21BD", "DownLeftVectorBar": "\u2956", "DownRightTeeVector": "\u295F", "DownRightVector": "\u21C1", "DownRightVectorBar": "\u2957", "DownTee": "\u22A4", "DownTeeArrow": "\u21A7", "drbkarow": "\u2910", "drcorn": "\u231F", "drcrop": "\u230C", "dscr": "\u{1D4B9}", "Dscr": "\u{1D49F}", "dscy": "\u0455", "DScy": "\u0405", "dsol": "\u29F6", "dstrok": "\u0111", "Dstrok": "\u0110", "dtdot": "\u22F1", "dtri": "\u25BF", "dtrif": "\u25BE", "duarr": "\u21F5", "duhar": "\u296F", "dwangle": "\u29A6", "dzcy": "\u045F", "DZcy": "\u040F", "dzigrarr": "\u27FF", "eacute": "\xE9", "Eacute": "\xC9", "easter": "\u2A6E", "ecaron": "\u011B", "Ecaron": "\u011A", "ecir": "\u2256", "ecirc": "\xEA", "Ecirc": "\xCA", "ecolon": "\u2255", "ecy": "\u044D", "Ecy": "\u042D", "eDDot": "\u2A77", "edot": "\u0117", "eDot": "\u2251", "Edot": "\u0116", "ee": "\u2147", "efDot": "\u2252", "efr": "\u{1D522}", "Efr": "\u{1D508}", "eg": "\u2A9A", "egrave": "\xE8", "Egrave": "\xC8", "egs": "\u2A96", "egsdot": "\u2A98", "el": "\u2A99", "Element": "\u2208", "elinters": "\u23E7", "ell": "\u2113", "els": "\u2A95", "elsdot": "\u2A97", "emacr": "\u0113", "Emacr": "\u0112", "empty": "\u2205", "emptyset": "\u2205", "EmptySmallSquare": "\u25FB", "emptyv": "\u2205", "EmptyVerySmallSquare": "\u25AB", "emsp": "\u2003", "emsp13": "\u2004", "emsp14": "\u2005", "eng": "\u014B", "ENG": "\u014A", "ensp": "\u2002", "eogon": "\u0119", "Eogon": "\u0118", "eopf": "\u{1D556}", "Eopf": "\u{1D53C}", "epar": "\u22D5", "eparsl": "\u29E3", "eplus": "\u2A71", "epsi": "\u03B5", "epsilon": "\u03B5", "Epsilon": "\u0395", "epsiv": "\u03F5", "eqcirc": "\u2256", "eqcolon": "\u2255", "eqsim": "\u2242", "eqslantgtr": "\u2A96", "eqslantless": "\u2A95", "Equal": "\u2A75", "equals": "=", "EqualTilde": "\u2242", "equest": "\u225F", "Equilibrium": "\u21CC", "equiv": "\u2261", "equivDD": "\u2A78", "eqvparsl": "\u29E5", "erarr": "\u2971", "erDot": "\u2253", "escr": "\u212F", "Escr": "\u2130", "esdot": "\u2250", "esim": "\u2242", "Esim": "\u2A73", "eta": "\u03B7", "Eta": "\u0397", "eth": "\xF0", "ETH": "\xD0", "euml": "\xEB", "Euml": "\xCB", "euro": "\u20AC", "excl": "!", "exist": "\u2203", "Exists": "\u2203", "expectation": "\u2130", "exponentiale": "\u2147", "ExponentialE": "\u2147", "fallingdotseq": "\u2252", "fcy": "\u0444", "Fcy": "\u0424", "female": "\u2640", "ffilig": "\uFB03", "fflig": "\uFB00", "ffllig": "\uFB04", "ffr": "\u{1D523}", "Ffr": "\u{1D509}", "filig": "\uFB01", "FilledSmallSquare": "\u25FC", "FilledVerySmallSquare": "\u25AA", "fjlig": "fj", "flat": "\u266D", "fllig": "\uFB02", "fltns": "\u25B1", "fnof": "\u0192", "fopf": "\u{1D557}", "Fopf": "\u{1D53D}", "forall": "\u2200", "ForAll": "\u2200", "fork": "\u22D4", "forkv": "\u2AD9", "Fouriertrf": "\u2131", "fpartint": "\u2A0D", "frac12": "\xBD", "frac13": "\u2153", "frac14": "\xBC", "frac15": "\u2155", "frac16": "\u2159", "frac18": "\u215B", "frac23": "\u2154", "frac25": "\u2156", "frac34": "\xBE", "frac35": "\u2157", "frac38": "\u215C", "frac45": "\u2158", "frac56": "\u215A", "frac58": "\u215D", "frac78": "\u215E", "frasl": "\u2044", "frown": "\u2322", "fscr": "\u{1D4BB}", "Fscr": "\u2131", "gacute": "\u01F5", "gamma": "\u03B3", "Gamma": "\u0393", "gammad": "\u03DD", "Gammad": "\u03DC", "gap": "\u2A86", "gbreve": "\u011F", "Gbreve": "\u011E", "Gcedil": "\u0122", "gcirc": "\u011D", "Gcirc": "\u011C", "gcy": "\u0433", "Gcy": "\u0413", "gdot": "\u0121", "Gdot": "\u0120", "ge": "\u2265", "gE": "\u2267", "gel": "\u22DB", "gEl": "\u2A8C", "geq": "\u2265", "geqq": "\u2267", "geqslant": "\u2A7E", "ges": "\u2A7E", "gescc": "\u2AA9", "gesdot": "\u2A80", "gesdoto": "\u2A82", "gesdotol": "\u2A84", "gesl": "\u22DB\uFE00", "gesles": "\u2A94", "gfr": "\u{1D524}", "Gfr": "\u{1D50A}", "gg": "\u226B", "Gg": "\u22D9", "ggg": "\u22D9", "gimel": "\u2137", "gjcy": "\u0453", "GJcy": "\u0403", "gl": "\u2277", "gla": "\u2AA5", "glE": "\u2A92", "glj": "\u2AA4", "gnap": "\u2A8A", "gnapprox": "\u2A8A", "gne": "\u2A88", "gnE": "\u2269", "gneq": "\u2A88", "gneqq": "\u2269", "gnsim": "\u22E7", "gopf": "\u{1D558}", "Gopf": "\u{1D53E}", "grave": "`", "GreaterEqual": "\u2265", "GreaterEqualLess": "\u22DB", "GreaterFullEqual": "\u2267", "GreaterGreater": "\u2AA2", "GreaterLess": "\u2277", "GreaterSlantEqual": "\u2A7E", "GreaterTilde": "\u2273", "gscr": "\u210A", "Gscr": "\u{1D4A2}", "gsim": "\u2273", "gsime": "\u2A8E", "gsiml": "\u2A90", "gt": ">", "Gt": "\u226B", "GT": ">", "gtcc": "\u2AA7", "gtcir": "\u2A7A", "gtdot": "\u22D7", "gtlPar": "\u2995", "gtquest": "\u2A7C", "gtrapprox": "\u2A86", "gtrarr": "\u2978", "gtrdot": "\u22D7", "gtreqless": "\u22DB", "gtreqqless": "\u2A8C", "gtrless": "\u2277", "gtrsim": "\u2273", "gvertneqq": "\u2269\uFE00", "gvnE": "\u2269\uFE00", "Hacek": "\u02C7", "hairsp": "\u200A", "half": "\xBD", "hamilt": "\u210B", "hardcy": "\u044A", "HARDcy": "\u042A", "harr": "\u2194", "hArr": "\u21D4", "harrcir": "\u2948", "harrw": "\u21AD", "Hat": "^", "hbar": "\u210F", "hcirc": "\u0125", "Hcirc": "\u0124", "hearts": "\u2665", "heartsuit": "\u2665", "hellip": "\u2026", "hercon": "\u22B9", "hfr": "\u{1D525}", "Hfr": "\u210C", "HilbertSpace": "\u210B", "hksearow": "\u2925", "hkswarow": "\u2926", "hoarr": "\u21FF", "homtht": "\u223B", "hookleftarrow": "\u21A9", "hookrightarrow": "\u21AA", "hopf": "\u{1D559}", "Hopf": "\u210D", "horbar": "\u2015", "HorizontalLine": "\u2500", "hscr": "\u{1D4BD}", "Hscr": "\u210B", "hslash": "\u210F", "hstrok": "\u0127", "Hstrok": "\u0126", "HumpDownHump": "\u224E", "HumpEqual": "\u224F", "hybull": "\u2043", "hyphen": "\u2010", "iacute": "\xED", "Iacute": "\xCD", "ic": "\u2063", "icirc": "\xEE", "Icirc": "\xCE", "icy": "\u0438", "Icy": "\u0418", "Idot": "\u0130", "iecy": "\u0435", "IEcy": "\u0415", "iexcl": "\xA1", "iff": "\u21D4", "ifr": "\u{1D526}", "Ifr": "\u2111", "igrave": "\xEC", "Igrave": "\xCC", "ii": "\u2148", "iiiint": "\u2A0C", "iiint": "\u222D", "iinfin": "\u29DC", "iiota": "\u2129", "ijlig": "\u0133", "IJlig": "\u0132", "Im": "\u2111", "imacr": "\u012B", "Imacr": "\u012A", "image": "\u2111", "ImaginaryI": "\u2148", "imagline": "\u2110", "imagpart": "\u2111", "imath": "\u0131", "imof": "\u22B7", "imped": "\u01B5", "Implies": "\u21D2", "in": "\u2208", "incare": "\u2105", "infin": "\u221E", "infintie": "\u29DD", "inodot": "\u0131", "int": "\u222B", "Int": "\u222C", "intcal": "\u22BA", "integers": "\u2124", "Integral": "\u222B", "intercal": "\u22BA", "Intersection": "\u22C2", "intlarhk": "\u2A17", "intprod": "\u2A3C", "InvisibleComma": "\u2063", "InvisibleTimes": "\u2062", "iocy": "\u0451", "IOcy": "\u0401", "iogon": "\u012F", "Iogon": "\u012E", "iopf": "\u{1D55A}", "Iopf": "\u{1D540}", "iota": "\u03B9", "Iota": "\u0399", "iprod": "\u2A3C", "iquest": "\xBF", "iscr": "\u{1D4BE}", "Iscr": "\u2110", "isin": "\u2208", "isindot": "\u22F5", "isinE": "\u22F9", "isins": "\u22F4", "isinsv": "\u22F3", "isinv": "\u2208", "it": "\u2062", "itilde": "\u0129", "Itilde": "\u0128", "iukcy": "\u0456", "Iukcy": "\u0406", "iuml": "\xEF", "Iuml": "\xCF", "jcirc": "\u0135", "Jcirc": "\u0134", "jcy": "\u0439", "Jcy": "\u0419", "jfr": "\u{1D527}", "Jfr": "\u{1D50D}", "jmath": "\u0237", "jopf": "\u{1D55B}", "Jopf": "\u{1D541}", "jscr": "\u{1D4BF}", "Jscr": "\u{1D4A5}", "jsercy": "\u0458", "Jsercy": "\u0408", "jukcy": "\u0454", "Jukcy": "\u0404", "kappa": "\u03BA", "Kappa": "\u039A", "kappav": "\u03F0", "kcedil": "\u0137", "Kcedil": "\u0136", "kcy": "\u043A", "Kcy": "\u041A", "kfr": "\u{1D528}", "Kfr": "\u{1D50E}", "kgreen": "\u0138", "khcy": "\u0445", "KHcy": "\u0425", "kjcy": "\u045C", "KJcy": "\u040C", "kopf": "\u{1D55C}", "Kopf": "\u{1D542}", "kscr": "\u{1D4C0}", "Kscr": "\u{1D4A6}", "lAarr": "\u21DA", "lacute": "\u013A", "Lacute": "\u0139", "laemptyv": "\u29B4", "lagran": "\u2112", "lambda": "\u03BB", "Lambda": "\u039B", "lang": "\u27E8", "Lang": "\u27EA", "langd": "\u2991", "langle": "\u27E8", "lap": "\u2A85", "Laplacetrf": "\u2112", "laquo": "\xAB", "larr": "\u2190", "lArr": "\u21D0", "Larr": "\u219E", "larrb": "\u21E4", "larrbfs": "\u291F", "larrfs": "\u291D", "larrhk": "\u21A9", "larrlp": "\u21AB", "larrpl": "\u2939", "larrsim": "\u2973", "larrtl": "\u21A2", "lat": "\u2AAB", "latail": "\u2919", "lAtail": "\u291B", "late": "\u2AAD", "lates": "\u2AAD\uFE00", "lbarr": "\u290C", "lBarr": "\u290E", "lbbrk": "\u2772", "lbrace": "{", "lbrack": "[", "lbrke": "\u298B", "lbrksld": "\u298F", "lbrkslu": "\u298D", "lcaron": "\u013E", "Lcaron": "\u013D", "lcedil": "\u013C", "Lcedil": "\u013B", "lceil": "\u2308", "lcub": "{", "lcy": "\u043B", "Lcy": "\u041B", "ldca": "\u2936", "ldquo": "\u201C", "ldquor": "\u201E", "ldrdhar": "\u2967", "ldrushar": "\u294B", "ldsh": "\u21B2", "le": "\u2264", "lE": "\u2266", "LeftAngleBracket": "\u27E8", "leftarrow": "\u2190", "Leftarrow": "\u21D0", "LeftArrow": "\u2190", "LeftArrowBar": "\u21E4", "LeftArrowRightArrow": "\u21C6", "leftarrowtail": "\u21A2", "LeftCeiling": "\u2308", "LeftDoubleBracket": "\u27E6", "LeftDownTeeVector": "\u2961", "LeftDownVector": "\u21C3", "LeftDownVectorBar": "\u2959", "LeftFloor": "\u230A", "leftharpoondown": "\u21BD", "leftharpoonup": "\u21BC", "leftleftarrows": "\u21C7", "leftrightarrow": "\u2194", "Leftrightarrow": "\u21D4", "LeftRightArrow": "\u2194", "leftrightarrows": "\u21C6", "leftrightharpoons": "\u21CB", "leftrightsquigarrow": "\u21AD", "LeftRightVector": "\u294E", "LeftTee": "\u22A3", "LeftTeeArrow": "\u21A4", "LeftTeeVector": "\u295A", "leftthreetimes": "\u22CB", "LeftTriangle": "\u22B2", "LeftTriangleBar": "\u29CF", "LeftTriangleEqual": "\u22B4", "LeftUpDownVector": "\u2951", "LeftUpTeeVector": "\u2960", "LeftUpVector": "\u21BF", "LeftUpVectorBar": "\u2958", "LeftVector": "\u21BC", "LeftVectorBar": "\u2952", "leg": "\u22DA", "lEg": "\u2A8B", "leq": "\u2264", "leqq": "\u2266", "leqslant": "\u2A7D", "les": "\u2A7D", "lescc": "\u2AA8", "lesdot": "\u2A7F", "lesdoto": "\u2A81", "lesdotor": "\u2A83", "lesg": "\u22DA\uFE00", "lesges": "\u2A93", "lessapprox": "\u2A85", "lessdot": "\u22D6", "lesseqgtr": "\u22DA", "lesseqqgtr": "\u2A8B", "LessEqualGreater": "\u22DA", "LessFullEqual": "\u2266", "LessGreater": "\u2276", "lessgtr": "\u2276", "LessLess": "\u2AA1", "lesssim": "\u2272", "LessSlantEqual": "\u2A7D", "LessTilde": "\u2272", "lfisht": "\u297C", "lfloor": "\u230A", "lfr": "\u{1D529}", "Lfr": "\u{1D50F}", "lg": "\u2276", "lgE": "\u2A91", "lHar": "\u2962", "lhard": "\u21BD", "lharu": "\u21BC", "lharul": "\u296A", "lhblk": "\u2584", "ljcy": "\u0459", "LJcy": "\u0409", "ll": "\u226A", "Ll": "\u22D8", "llarr": "\u21C7", "llcorner": "\u231E", "Lleftarrow": "\u21DA", "llhard": "\u296B", "lltri": "\u25FA", "lmidot": "\u0140", "Lmidot": "\u013F", "lmoust": "\u23B0", "lmoustache": "\u23B0", "lnap": "\u2A89", "lnapprox": "\u2A89", "lne": "\u2A87", "lnE": "\u2268", "lneq": "\u2A87", "lneqq": "\u2268", "lnsim": "\u22E6", "loang": "\u27EC", "loarr": "\u21FD", "lobrk": "\u27E6", "longleftarrow": "\u27F5", "Longleftarrow": "\u27F8", "LongLeftArrow": "\u27F5", "longleftrightarrow": "\u27F7", "Longleftrightarrow": "\u27FA", "LongLeftRightArrow": "\u27F7", "longmapsto": "\u27FC", "longrightarrow": "\u27F6", "Longrightarrow": "\u27F9", "LongRightArrow": "\u27F6", "looparrowleft": "\u21AB", "looparrowright": "\u21AC", "lopar": "\u2985", "lopf": "\u{1D55D}", "Lopf": "\u{1D543}", "loplus": "\u2A2D", "lotimes": "\u2A34", "lowast": "\u2217", "lowbar": "_", "LowerLeftArrow": "\u2199", "LowerRightArrow": "\u2198", "loz": "\u25CA", "lozenge": "\u25CA", "lozf": "\u29EB", "lpar": "(", "lparlt": "\u2993", "lrarr": "\u21C6", "lrcorner": "\u231F", "lrhar": "\u21CB", "lrhard": "\u296D", "lrm": "\u200E", "lrtri": "\u22BF", "lsaquo": "\u2039", "lscr": "\u{1D4C1}", "Lscr": "\u2112", "lsh": "\u21B0", "Lsh": "\u21B0", "lsim": "\u2272", "lsime": "\u2A8D", "lsimg": "\u2A8F", "lsqb": "[", "lsquo": "\u2018", "lsquor": "\u201A", "lstrok": "\u0142", "Lstrok": "\u0141", "lt": "<", "Lt": "\u226A", "LT": "<", "ltcc": "\u2AA6", "ltcir": "\u2A79", "ltdot": "\u22D6", "lthree": "\u22CB", "ltimes": "\u22C9", "ltlarr": "\u2976", "ltquest": "\u2A7B", "ltri": "\u25C3", "ltrie": "\u22B4", "ltrif": "\u25C2", "ltrPar": "\u2996", "lurdshar": "\u294A", "luruhar": "\u2966", "lvertneqq": "\u2268\uFE00", "lvnE": "\u2268\uFE00", "macr": "\xAF", "male": "\u2642", "malt": "\u2720", "maltese": "\u2720", "map": "\u21A6", "Map": "\u2905", "mapsto": "\u21A6", "mapstodown": "\u21A7", "mapstoleft": "\u21A4", "mapstoup": "\u21A5", "marker": "\u25AE", "mcomma": "\u2A29", "mcy": "\u043C", "Mcy": "\u041C", "mdash": "\u2014", "mDDot": "\u223A", "measuredangle": "\u2221", "MediumSpace": "\u205F", "Mellintrf": "\u2133", "mfr": "\u{1D52A}", "Mfr": "\u{1D510}", "mho": "\u2127", "micro": "\xB5", "mid": "\u2223", "midast": "*", "midcir": "\u2AF0", "middot": "\xB7", "minus": "\u2212", "minusb": "\u229F", "minusd": "\u2238", "minusdu": "\u2A2A", "MinusPlus": "\u2213", "mlcp": "\u2ADB", "mldr": "\u2026", "mnplus": "\u2213", "models": "\u22A7", "mopf": "\u{1D55E}", "Mopf": "\u{1D544}", "mp": "\u2213", "mscr": "\u{1D4C2}", "Mscr": "\u2133", "mstpos": "\u223E", "mu": "\u03BC", "Mu": "\u039C", "multimap": "\u22B8", "mumap": "\u22B8", "nabla": "\u2207", "nacute": "\u0144", "Nacute": "\u0143", "nang": "\u2220\u20D2", "nap": "\u2249", "napE": "\u2A70\u0338", "napid": "\u224B\u0338", "napos": "\u0149", "napprox": "\u2249", "natur": "\u266E", "natural": "\u266E", "naturals": "\u2115", "nbsp": "\xA0", "nbump": "\u224E\u0338", "nbumpe": "\u224F\u0338", "ncap": "\u2A43", "ncaron": "\u0148", "Ncaron": "\u0147", "ncedil": "\u0146", "Ncedil": "\u0145", "ncong": "\u2247", "ncongdot": "\u2A6D\u0338", "ncup": "\u2A42", "ncy": "\u043D", "Ncy": "\u041D", "ndash": "\u2013", "ne": "\u2260", "nearhk": "\u2924", "nearr": "\u2197", "neArr": "\u21D7", "nearrow": "\u2197", "nedot": "\u2250\u0338", "NegativeMediumSpace": "\u200B", "NegativeThickSpace": "\u200B", "NegativeThinSpace": "\u200B", "NegativeVeryThinSpace": "\u200B", "nequiv": "\u2262", "nesear": "\u2928", "nesim": "\u2242\u0338", "NestedGreaterGreater": "\u226B", "NestedLessLess": "\u226A", "NewLine": "\n", "nexist": "\u2204", "nexists": "\u2204", "nfr": "\u{1D52B}", "Nfr": "\u{1D511}", "nge": "\u2271", "ngE": "\u2267\u0338", "ngeq": "\u2271", "ngeqq": "\u2267\u0338", "ngeqslant": "\u2A7E\u0338", "nges": "\u2A7E\u0338", "nGg": "\u22D9\u0338", "ngsim": "\u2275", "ngt": "\u226F", "nGt": "\u226B\u20D2", "ngtr": "\u226F", "nGtv": "\u226B\u0338", "nharr": "\u21AE", "nhArr": "\u21CE", "nhpar": "\u2AF2", "ni": "\u220B", "nis": "\u22FC", "nisd": "\u22FA", "niv": "\u220B", "njcy": "\u045A", "NJcy": "\u040A", "nlarr": "\u219A", "nlArr": "\u21CD", "nldr": "\u2025", "nle": "\u2270", "nlE": "\u2266\u0338", "nleftarrow": "\u219A", "nLeftarrow": "\u21CD", "nleftrightarrow": "\u21AE", "nLeftrightarrow": "\u21CE", "nleq": "\u2270", "nleqq": "\u2266\u0338", "nleqslant": "\u2A7D\u0338", "nles": "\u2A7D\u0338", "nless": "\u226E", "nLl": "\u22D8\u0338", "nlsim": "\u2274", "nlt": "\u226E", "nLt": "\u226A\u20D2", "nltri": "\u22EA", "nltrie": "\u22EC", "nLtv": "\u226A\u0338", "nmid": "\u2224", "NoBreak": "\u2060", "NonBreakingSpace": "\xA0", "nopf": "\u{1D55F}", "Nopf": "\u2115", "not": "\xAC", "Not": "\u2AEC", "NotCongruent": "\u2262", "NotCupCap": "\u226D", "NotDoubleVerticalBar": "\u2226", "NotElement": "\u2209", "NotEqual": "\u2260", "NotEqualTilde": "\u2242\u0338", "NotExists": "\u2204", "NotGreater": "\u226F", "NotGreaterEqual": "\u2271", "NotGreaterFullEqual": "\u2267\u0338", "NotGreaterGreater": "\u226B\u0338", "NotGreaterLess": "\u2279", "NotGreaterSlantEqual": "\u2A7E\u0338", "NotGreaterTilde": "\u2275", "NotHumpDownHump": "\u224E\u0338", "NotHumpEqual": "\u224F\u0338", "notin": "\u2209", "notindot": "\u22F5\u0338", "notinE": "\u22F9\u0338", "notinva": "\u2209", "notinvb": "\u22F7", "notinvc": "\u22F6", "NotLeftTriangle": "\u22EA", "NotLeftTriangleBar": "\u29CF\u0338", "NotLeftTriangleEqual": "\u22EC", "NotLess": "\u226E", "NotLessEqual": "\u2270", "NotLessGreater": "\u2278", "NotLessLess": "\u226A\u0338", "NotLessSlantEqual": "\u2A7D\u0338", "NotLessTilde": "\u2274", "NotNestedGreaterGreater": "\u2AA2\u0338", "NotNestedLessLess": "\u2AA1\u0338", "notni": "\u220C", "notniva": "\u220C", "notnivb": "\u22FE", "notnivc": "\u22FD", "NotPrecedes": "\u2280", "NotPrecedesEqual": "\u2AAF\u0338", "NotPrecedesSlantEqual": "\u22E0", "NotReverseElement": "\u220C", "NotRightTriangle": "\u22EB", "NotRightTriangleBar": "\u29D0\u0338", "NotRightTriangleEqual": "\u22ED", "NotSquareSubset": "\u228F\u0338", "NotSquareSubsetEqual": "\u22E2", "NotSquareSuperset": "\u2290\u0338", "NotSquareSupersetEqual": "\u22E3", "NotSubset": "\u2282\u20D2", "NotSubsetEqual": "\u2288", "NotSucceeds": "\u2281", "NotSucceedsEqual": "\u2AB0\u0338", "NotSucceedsSlantEqual": "\u22E1", "NotSucceedsTilde": "\u227F\u0338", "NotSuperset": "\u2283\u20D2", "NotSupersetEqual": "\u2289", "NotTilde": "\u2241", "NotTildeEqual": "\u2244", "NotTildeFullEqual": "\u2247", "NotTildeTilde": "\u2249", "NotVerticalBar": "\u2224", "npar": "\u2226", "nparallel": "\u2226", "nparsl": "\u2AFD\u20E5", "npart": "\u2202\u0338", "npolint": "\u2A14", "npr": "\u2280", "nprcue": "\u22E0", "npre": "\u2AAF\u0338", "nprec": "\u2280", "npreceq": "\u2AAF\u0338", "nrarr": "\u219B", "nrArr": "\u21CF", "nrarrc": "\u2933\u0338", "nrarrw": "\u219D\u0338", "nrightarrow": "\u219B", "nRightarrow": "\u21CF", "nrtri": "\u22EB", "nrtrie": "\u22ED", "nsc": "\u2281", "nsccue": "\u22E1", "nsce": "\u2AB0\u0338", "nscr": "\u{1D4C3}", "Nscr": "\u{1D4A9}", "nshortmid": "\u2224", "nshortparallel": "\u2226", "nsim": "\u2241", "nsime": "\u2244", "nsimeq": "\u2244", "nsmid": "\u2224", "nspar": "\u2226", "nsqsube": "\u22E2", "nsqsupe": "\u22E3", "nsub": "\u2284", "nsube": "\u2288", "nsubE": "\u2AC5\u0338", "nsubset": "\u2282\u20D2", "nsubseteq": "\u2288", "nsubseteqq": "\u2AC5\u0338", "nsucc": "\u2281", "nsucceq": "\u2AB0\u0338", "nsup": "\u2285", "nsupe": "\u2289", "nsupE": "\u2AC6\u0338", "nsupset": "\u2283\u20D2", "nsupseteq": "\u2289", "nsupseteqq": "\u2AC6\u0338", "ntgl": "\u2279", "ntilde": "\xF1", "Ntilde": "\xD1", "ntlg": "\u2278", "ntriangleleft": "\u22EA", "ntrianglelefteq": "\u22EC", "ntriangleright": "\u22EB", "ntrianglerighteq": "\u22ED", "nu": "\u03BD", "Nu": "\u039D", "num": "#", "numero": "\u2116", "numsp": "\u2007", "nvap": "\u224D\u20D2", "nvdash": "\u22AC", "nvDash": "\u22AD", "nVdash": "\u22AE", "nVDash": "\u22AF", "nvge": "\u2265\u20D2", "nvgt": ">\u20D2", "nvHarr": "\u2904", "nvinfin": "\u29DE", "nvlArr": "\u2902", "nvle": "\u2264\u20D2", "nvlt": "<\u20D2", "nvltrie": "\u22B4\u20D2", "nvrArr": "\u2903", "nvrtrie": "\u22B5\u20D2", "nvsim": "\u223C\u20D2", "nwarhk": "\u2923", "nwarr": "\u2196", "nwArr": "\u21D6", "nwarrow": "\u2196", "nwnear": "\u2927", "oacute": "\xF3", "Oacute": "\xD3", "oast": "\u229B", "ocir": "\u229A", "ocirc": "\xF4", "Ocirc": "\xD4", "ocy": "\u043E", "Ocy": "\u041E", "odash": "\u229D", "odblac": "\u0151", "Odblac": "\u0150", "odiv": "\u2A38", "odot": "\u2299", "odsold": "\u29BC", "oelig": "\u0153", "OElig": "\u0152", "ofcir": "\u29BF", "ofr": "\u{1D52C}", "Ofr": "\u{1D512}", "ogon": "\u02DB", "ograve": "\xF2", "Ograve": "\xD2", "ogt": "\u29C1", "ohbar": "\u29B5", "ohm": "\u03A9", "oint": "\u222E", "olarr": "\u21BA", "olcir": "\u29BE", "olcross": "\u29BB", "oline": "\u203E", "olt": "\u29C0", "omacr": "\u014D", "Omacr": "\u014C", "omega": "\u03C9", "Omega": "\u03A9", "omicron": "\u03BF", "Omicron": "\u039F", "omid": "\u29B6", "ominus": "\u2296", "oopf": "\u{1D560}", "Oopf": "\u{1D546}", "opar": "\u29B7", "OpenCurlyDoubleQuote": "\u201C", "OpenCurlyQuote": "\u2018", "operp": "\u29B9", "oplus": "\u2295", "or": "\u2228", "Or": "\u2A54", "orarr": "\u21BB", "ord": "\u2A5D", "order": "\u2134", "orderof": "\u2134", "ordf": "\xAA", "ordm": "\xBA", "origof": "\u22B6", "oror": "\u2A56", "orslope": "\u2A57", "orv": "\u2A5B", "oS": "\u24C8", "oscr": "\u2134", "Oscr": "\u{1D4AA}", "oslash": "\xF8", "Oslash": "\xD8", "osol": "\u2298", "otilde": "\xF5", "Otilde": "\xD5", "otimes": "\u2297", "Otimes": "\u2A37", "otimesas": "\u2A36", "ouml": "\xF6", "Ouml": "\xD6", "ovbar": "\u233D", "OverBar": "\u203E", "OverBrace": "\u23DE", "OverBracket": "\u23B4", "OverParenthesis": "\u23DC", "par": "\u2225", "para": "\xB6", "parallel": "\u2225", "parsim": "\u2AF3", "parsl": "\u2AFD", "part": "\u2202", "PartialD": "\u2202", "pcy": "\u043F", "Pcy": "\u041F", "percnt": "%", "period": ".", "permil": "\u2030", "perp": "\u22A5", "pertenk": "\u2031", "pfr": "\u{1D52D}", "Pfr": "\u{1D513}", "phi": "\u03C6", "Phi": "\u03A6", "phiv": "\u03D5", "phmmat": "\u2133", "phone": "\u260E", "pi": "\u03C0", "Pi": "\u03A0", "pitchfork": "\u22D4", "piv": "\u03D6", "planck": "\u210F", "planckh": "\u210E", "plankv": "\u210F", "plus": "+", "plusacir": "\u2A23", "plusb": "\u229E", "pluscir": "\u2A22", "plusdo": "\u2214", "plusdu": "\u2A25", "pluse": "\u2A72", "PlusMinus": "\xB1", "plusmn": "\xB1", "plussim": "\u2A26", "plustwo": "\u2A27", "pm": "\xB1", "Poincareplane": "\u210C", "pointint": "\u2A15", "popf": "\u{1D561}", "Popf": "\u2119", "pound": "\xA3", "pr": "\u227A", "Pr": "\u2ABB", "prap": "\u2AB7", "prcue": "\u227C", "pre": "\u2AAF", "prE": "\u2AB3", "prec": "\u227A", "precapprox": "\u2AB7", "preccurlyeq": "\u227C", "Precedes": "\u227A", "PrecedesEqual": "\u2AAF", "PrecedesSlantEqual": "\u227C", "PrecedesTilde": "\u227E", "preceq": "\u2AAF", "precnapprox": "\u2AB9", "precneqq": "\u2AB5", "precnsim": "\u22E8", "precsim": "\u227E", "prime": "\u2032", "Prime": "\u2033", "primes": "\u2119", "prnap": "\u2AB9", "prnE": "\u2AB5", "prnsim": "\u22E8", "prod": "\u220F", "Product": "\u220F", "profalar": "\u232E", "profline": "\u2312", "profsurf": "\u2313", "prop": "\u221D", "Proportion": "\u2237", "Proportional": "\u221D", "propto": "\u221D", "prsim": "\u227E", "prurel": "\u22B0", "pscr": "\u{1D4C5}", "Pscr": "\u{1D4AB}", "psi": "\u03C8", "Psi": "\u03A8", "puncsp": "\u2008", "qfr": "\u{1D52E}", "Qfr": "\u{1D514}", "qint": "\u2A0C", "qopf": "\u{1D562}", "Qopf": "\u211A", "qprime": "\u2057", "qscr": "\u{1D4C6}", "Qscr": "\u{1D4AC}", "quaternions": "\u210D", "quatint": "\u2A16", "quest": "?", "questeq": "\u225F", "quot": '"', "QUOT": '"', "rAarr": "\u21DB", "race": "\u223D\u0331", "racute": "\u0155", "Racute": "\u0154", "radic": "\u221A", "raemptyv": "\u29B3", "rang": "\u27E9", "Rang": "\u27EB", "rangd": "\u2992", "range": "\u29A5", "rangle": "\u27E9", "raquo": "\xBB", "rarr": "\u2192", "rArr": "\u21D2", "Rarr": "\u21A0", "rarrap": "\u2975", "rarrb": "\u21E5", "rarrbfs": "\u2920", "rarrc": "\u2933", "rarrfs": "\u291E", "rarrhk": "\u21AA", "rarrlp": "\u21AC", "rarrpl": "\u2945", "rarrsim": "\u2974", "rarrtl": "\u21A3", "Rarrtl": "\u2916", "rarrw": "\u219D", "ratail": "\u291A", "rAtail": "\u291C", "ratio": "\u2236", "rationals": "\u211A", "rbarr": "\u290D", "rBarr": "\u290F", "RBarr": "\u2910", "rbbrk": "\u2773", "rbrace": "}", "rbrack": "]", "rbrke": "\u298C", "rbrksld": "\u298E", "rbrkslu": "\u2990", "rcaron": "\u0159", "Rcaron": "\u0158", "rcedil": "\u0157", "Rcedil": "\u0156", "rceil": "\u2309", "rcub": "}", "rcy": "\u0440", "Rcy": "\u0420", "rdca": "\u2937", "rdldhar": "\u2969", "rdquo": "\u201D", "rdquor": "\u201D", "rdsh": "\u21B3", "Re": "\u211C", "real": "\u211C", "realine": "\u211B", "realpart": "\u211C", "reals": "\u211D", "rect": "\u25AD", "reg": "\xAE", "REG": "\xAE", "ReverseElement": "\u220B", "ReverseEquilibrium": "\u21CB", "ReverseUpEquilibrium": "\u296F", "rfisht": "\u297D", "rfloor": "\u230B", "rfr": "\u{1D52F}", "Rfr": "\u211C", "rHar": "\u2964", "rhard": "\u21C1", "rharu": "\u21C0", "rharul": "\u296C", "rho": "\u03C1", "Rho": "\u03A1", "rhov": "\u03F1", "RightAngleBracket": "\u27E9", "rightarrow": "\u2192", "Rightarrow": "\u21D2", "RightArrow": "\u2192", "RightArrowBar": "\u21E5", "RightArrowLeftArrow": "\u21C4", "rightarrowtail": "\u21A3", "RightCeiling": "\u2309", "RightDoubleBracket": "\u27E7", "RightDownTeeVector": "\u295D", "RightDownVector": "\u21C2", "RightDownVectorBar": "\u2955", "RightFloor": "\u230B", "rightharpoondown": "\u21C1", "rightharpoonup": "\u21C0", "rightleftarrows": "\u21C4", "rightleftharpoons": "\u21CC", "rightrightarrows": "\u21C9", "rightsquigarrow": "\u219D", "RightTee": "\u22A2", "RightTeeArrow": "\u21A6", "RightTeeVector": "\u295B", "rightthreetimes": "\u22CC", "RightTriangle": "\u22B3", "RightTriangleBar": "\u29D0", "RightTriangleEqual": "\u22B5", "RightUpDownVector": "\u294F", "RightUpTeeVector": "\u295C", "RightUpVector": "\u21BE", "RightUpVectorBar": "\u2954", "RightVector": "\u21C0", "RightVectorBar": "\u2953", "ring": "\u02DA", "risingdotseq": "\u2253", "rlarr": "\u21C4", "rlhar": "\u21CC", "rlm": "\u200F", "rmoust": "\u23B1", "rmoustache": "\u23B1", "rnmid": "\u2AEE", "roang": "\u27ED", "roarr": "\u21FE", "robrk": "\u27E7", "ropar": "\u2986", "ropf": "\u{1D563}", "Ropf": "\u211D", "roplus": "\u2A2E", "rotimes": "\u2A35", "RoundImplies": "\u2970", "rpar": ")", "rpargt": "\u2994", "rppolint": "\u2A12", "rrarr": "\u21C9", "Rrightarrow": "\u21DB", "rsaquo": "\u203A", "rscr": "\u{1D4C7}", "Rscr": "\u211B", "rsh": "\u21B1", "Rsh": "\u21B1", "rsqb": "]", "rsquo": "\u2019", "rsquor": "\u2019", "rthree": "\u22CC", "rtimes": "\u22CA", "rtri": "\u25B9", "rtrie": "\u22B5", "rtrif": "\u25B8", "rtriltri": "\u29CE", "RuleDelayed": "\u29F4", "ruluhar": "\u2968", "rx": "\u211E", "sacute": "\u015B", "Sacute": "\u015A", "sbquo": "\u201A", "sc": "\u227B", "Sc": "\u2ABC", "scap": "\u2AB8", "scaron": "\u0161", "Scaron": "\u0160", "sccue": "\u227D", "sce": "\u2AB0", "scE": "\u2AB4", "scedil": "\u015F", "Scedil": "\u015E", "scirc": "\u015D", "Scirc": "\u015C", "scnap": "\u2ABA", "scnE": "\u2AB6", "scnsim": "\u22E9", "scpolint": "\u2A13", "scsim": "\u227F", "scy": "\u0441", "Scy": "\u0421", "sdot": "\u22C5", "sdotb": "\u22A1", "sdote": "\u2A66", "searhk": "\u2925", "searr": "\u2198", "seArr": "\u21D8", "searrow": "\u2198", "sect": "\xA7", "semi": ";", "seswar": "\u2929", "setminus": "\u2216", "setmn": "\u2216", "sext": "\u2736", "sfr": "\u{1D530}", "Sfr": "\u{1D516}", "sfrown": "\u2322", "sharp": "\u266F", "shchcy": "\u0449", "SHCHcy": "\u0429", "shcy": "\u0448", "SHcy": "\u0428", "ShortDownArrow": "\u2193", "ShortLeftArrow": "\u2190", "shortmid": "\u2223", "shortparallel": "\u2225", "ShortRightArrow": "\u2192", "ShortUpArrow": "\u2191", "shy": "\xAD", "sigma": "\u03C3", "Sigma": "\u03A3", "sigmaf": "\u03C2", "sigmav": "\u03C2", "sim": "\u223C", "simdot": "\u2A6A", "sime": "\u2243", "simeq": "\u2243", "simg": "\u2A9E", "simgE": "\u2AA0", "siml": "\u2A9D", "simlE": "\u2A9F", "simne": "\u2246", "simplus": "\u2A24", "simrarr": "\u2972", "slarr": "\u2190", "SmallCircle": "\u2218", "smallsetminus": "\u2216", "smashp": "\u2A33", "smeparsl": "\u29E4", "smid": "\u2223", "smile": "\u2323", "smt": "\u2AAA", "smte": "\u2AAC", "smtes": "\u2AAC\uFE00", "softcy": "\u044C", "SOFTcy": "\u042C", "sol": "/", "solb": "\u29C4", "solbar": "\u233F", "sopf": "\u{1D564}", "Sopf": "\u{1D54A}", "spades": "\u2660", "spadesuit": "\u2660", "spar": "\u2225", "sqcap": "\u2293", "sqcaps": "\u2293\uFE00", "sqcup": "\u2294", "sqcups": "\u2294\uFE00", "Sqrt": "\u221A", "sqsub": "\u228F", "sqsube": "\u2291", "sqsubset": "\u228F", "sqsubseteq": "\u2291", "sqsup": "\u2290", "sqsupe": "\u2292", "sqsupset": "\u2290", "sqsupseteq": "\u2292", "squ": "\u25A1", "square": "\u25A1", "Square": "\u25A1", "SquareIntersection": "\u2293", "SquareSubset": "\u228F", "SquareSubsetEqual": "\u2291", "SquareSuperset": "\u2290", "SquareSupersetEqual": "\u2292", "SquareUnion": "\u2294", "squarf": "\u25AA", "squf": "\u25AA", "srarr": "\u2192", "sscr": "\u{1D4C8}", "Sscr": "\u{1D4AE}", "ssetmn": "\u2216", "ssmile": "\u2323", "sstarf": "\u22C6", "star": "\u2606", "Star": "\u22C6", "starf": "\u2605", "straightepsilon": "\u03F5", "straightphi": "\u03D5", "strns": "\xAF", "sub": "\u2282", "Sub": "\u22D0", "subdot": "\u2ABD", "sube": "\u2286", "subE": "\u2AC5", "subedot": "\u2AC3", "submult": "\u2AC1", "subne": "\u228A", "subnE": "\u2ACB", "subplus": "\u2ABF", "subrarr": "\u2979", "subset": "\u2282", "Subset": "\u22D0", "subseteq": "\u2286", "subseteqq": "\u2AC5", "SubsetEqual": "\u2286", "subsetneq": "\u228A", "subsetneqq": "\u2ACB", "subsim": "\u2AC7", "subsub": "\u2AD5", "subsup": "\u2AD3", "succ": "\u227B", "succapprox": "\u2AB8", "succcurlyeq": "\u227D", "Succeeds": "\u227B", "SucceedsEqual": "\u2AB0", "SucceedsSlantEqual": "\u227D", "SucceedsTilde": "\u227F", "succeq": "\u2AB0", "succnapprox": "\u2ABA", "succneqq": "\u2AB6", "succnsim": "\u22E9", "succsim": "\u227F", "SuchThat": "\u220B", "sum": "\u2211", "Sum": "\u2211", "sung": "\u266A", "sup": "\u2283", "Sup": "\u22D1", "sup1": "\xB9", "sup2": "\xB2", "sup3": "\xB3", "supdot": "\u2ABE", "supdsub": "\u2AD8", "supe": "\u2287", "supE": "\u2AC6", "supedot": "\u2AC4", "Superset": "\u2283", "SupersetEqual": "\u2287", "suphsol": "\u27C9", "suphsub": "\u2AD7", "suplarr": "\u297B", "supmult": "\u2AC2", "supne": "\u228B", "supnE": "\u2ACC", "supplus": "\u2AC0", "supset": "\u2283", "Supset": "\u22D1", "supseteq": "\u2287", "supseteqq": "\u2AC6", "supsetneq": "\u228B", "supsetneqq": "\u2ACC", "supsim": "\u2AC8", "supsub": "\u2AD4", "supsup": "\u2AD6", "swarhk": "\u2926", "swarr": "\u2199", "swArr": "\u21D9", "swarrow": "\u2199", "swnwar": "\u292A", "szlig": "\xDF", "Tab": " ", "target": "\u2316", "tau": "\u03C4", "Tau": "\u03A4", "tbrk": "\u23B4", "tcaron": "\u0165", "Tcaron": "\u0164", "tcedil": "\u0163", "Tcedil": "\u0162", "tcy": "\u0442", "Tcy": "\u0422", "tdot": "\u20DB", "telrec": "\u2315", "tfr": "\u{1D531}", "Tfr": "\u{1D517}", "there4": "\u2234", "therefore": "\u2234", "Therefore": "\u2234", "theta": "\u03B8", "Theta": "\u0398", "thetasym": "\u03D1", "thetav": "\u03D1", "thickapprox": "\u2248", "thicksim": "\u223C", "ThickSpace": "\u205F\u200A", "thinsp": "\u2009", "ThinSpace": "\u2009", "thkap": "\u2248", "thksim": "\u223C", "thorn": "\xFE", "THORN": "\xDE", "tilde": "\u02DC", "Tilde": "\u223C", "TildeEqual": "\u2243", "TildeFullEqual": "\u2245", "TildeTilde": "\u2248", "times": "\xD7", "timesb": "\u22A0", "timesbar": "\u2A31", "timesd": "\u2A30", "tint": "\u222D", "toea": "\u2928", "top": "\u22A4", "topbot": "\u2336", "topcir": "\u2AF1", "topf": "\u{1D565}", "Topf": "\u{1D54B}", "topfork": "\u2ADA", "tosa": "\u2929", "tprime": "\u2034", "trade": "\u2122", "TRADE": "\u2122", "triangle": "\u25B5", "triangledown": "\u25BF", "triangleleft": "\u25C3", "trianglelefteq": "\u22B4", "triangleq": "\u225C", "triangleright": "\u25B9", "trianglerighteq": "\u22B5", "tridot": "\u25EC", "trie": "\u225C", "triminus": "\u2A3A", "TripleDot": "\u20DB", "triplus": "\u2A39", "trisb": "\u29CD", "tritime": "\u2A3B", "trpezium": "\u23E2", "tscr": "\u{1D4C9}", "Tscr": "\u{1D4AF}", "tscy": "\u0446", "TScy": "\u0426", "tshcy": "\u045B", "TSHcy": "\u040B", "tstrok": "\u0167", "Tstrok": "\u0166", "twixt": "\u226C", "twoheadleftarrow": "\u219E", "twoheadrightarrow": "\u21A0", "uacute": "\xFA", "Uacute": "\xDA", "uarr": "\u2191", "uArr": "\u21D1", "Uarr": "\u219F", "Uarrocir": "\u2949", "ubrcy": "\u045E", "Ubrcy": "\u040E", "ubreve": "\u016D", "Ubreve": "\u016C", "ucirc": "\xFB", "Ucirc": "\xDB", "ucy": "\u0443", "Ucy": "\u0423", "udarr": "\u21C5", "udblac": "\u0171", "Udblac": "\u0170", "udhar": "\u296E", "ufisht": "\u297E", "ufr": "\u{1D532}", "Ufr": "\u{1D518}", "ugrave": "\xF9", "Ugrave": "\xD9", "uHar": "\u2963", "uharl": "\u21BF", "uharr": "\u21BE", "uhblk": "\u2580", "ulcorn": "\u231C", "ulcorner": "\u231C", "ulcrop": "\u230F", "ultri": "\u25F8", "umacr": "\u016B", "Umacr": "\u016A", "uml": "\xA8", "UnderBar": "_", "UnderBrace": "\u23DF", "UnderBracket": "\u23B5", "UnderParenthesis": "\u23DD", "Union": "\u22C3", "UnionPlus": "\u228E", "uogon": "\u0173", "Uogon": "\u0172", "uopf": "\u{1D566}", "Uopf": "\u{1D54C}", "uparrow": "\u2191", "Uparrow": "\u21D1", "UpArrow": "\u2191", "UpArrowBar": "\u2912", "UpArrowDownArrow": "\u21C5", "updownarrow": "\u2195", "Updownarrow": "\u21D5", "UpDownArrow": "\u2195", "UpEquilibrium": "\u296E", "upharpoonleft": "\u21BF", "upharpoonright": "\u21BE", "uplus": "\u228E", "UpperLeftArrow": "\u2196", "UpperRightArrow": "\u2197", "upsi": "\u03C5", "Upsi": "\u03D2", "upsih": "\u03D2", "upsilon": "\u03C5", "Upsilon": "\u03A5", "UpTee": "\u22A5", "UpTeeArrow": "\u21A5", "upuparrows": "\u21C8", "urcorn": "\u231D", "urcorner": "\u231D", "urcrop": "\u230E", "uring": "\u016F", "Uring": "\u016E", "urtri": "\u25F9", "uscr": "\u{1D4CA}", "Uscr": "\u{1D4B0}", "utdot": "\u22F0", "utilde": "\u0169", "Utilde": "\u0168", "utri": "\u25B5", "utrif": "\u25B4", "uuarr": "\u21C8", "uuml": "\xFC", "Uuml": "\xDC", "uwangle": "\u29A7", "vangrt": "\u299C", "varepsilon": "\u03F5", "varkappa": "\u03F0", "varnothing": "\u2205", "varphi": "\u03D5", "varpi": "\u03D6", "varpropto": "\u221D", "varr": "\u2195", "vArr": "\u21D5", "varrho": "\u03F1", "varsigma": "\u03C2", "varsubsetneq": "\u228A\uFE00", "varsubsetneqq": "\u2ACB\uFE00", "varsupsetneq": "\u228B\uFE00", "varsupsetneqq": "\u2ACC\uFE00", "vartheta": "\u03D1", "vartriangleleft": "\u22B2", "vartriangleright": "\u22B3", "vBar": "\u2AE8", "Vbar": "\u2AEB", "vBarv": "\u2AE9", "vcy": "\u0432", "Vcy": "\u0412", "vdash": "\u22A2", "vDash": "\u22A8", "Vdash": "\u22A9", "VDash": "\u22AB", "Vdashl": "\u2AE6", "vee": "\u2228", "Vee": "\u22C1", "veebar": "\u22BB", "veeeq": "\u225A", "vellip": "\u22EE", "verbar": "|", "Verbar": "\u2016", "vert": "|", "Vert": "\u2016", "VerticalBar": "\u2223", "VerticalLine": "|", "VerticalSeparator": "\u2758", "VerticalTilde": "\u2240", "VeryThinSpace": "\u200A", "vfr": "\u{1D533}", "Vfr": "\u{1D519}", "vltri": "\u22B2", "vnsub": "\u2282\u20D2", "vnsup": "\u2283\u20D2", "vopf": "\u{1D567}", "Vopf": "\u{1D54D}", "vprop": "\u221D", "vrtri": "\u22B3", "vscr": "\u{1D4CB}", "Vscr": "\u{1D4B1}", "vsubne": "\u228A\uFE00", "vsubnE": "\u2ACB\uFE00", "vsupne": "\u228B\uFE00", "vsupnE": "\u2ACC\uFE00", "Vvdash": "\u22AA", "vzigzag": "\u299A", "wcirc": "\u0175", "Wcirc": "\u0174", "wedbar": "\u2A5F", "wedge": "\u2227", "Wedge": "\u22C0", "wedgeq": "\u2259", "weierp": "\u2118", "wfr": "\u{1D534}", "Wfr": "\u{1D51A}", "wopf": "\u{1D568}", "Wopf": "\u{1D54E}", "wp": "\u2118", "wr": "\u2240", "wreath": "\u2240", "wscr": "\u{1D4CC}", "Wscr": "\u{1D4B2}", "xcap": "\u22C2", "xcirc": "\u25EF", "xcup": "\u22C3", "xdtri": "\u25BD", "xfr": "\u{1D535}", "Xfr": "\u{1D51B}", "xharr": "\u27F7", "xhArr": "\u27FA", "xi": "\u03BE", "Xi": "\u039E", "xlarr": "\u27F5", "xlArr": "\u27F8", "xmap": "\u27FC", "xnis": "\u22FB", "xodot": "\u2A00", "xopf": "\u{1D569}", "Xopf": "\u{1D54F}", "xoplus": "\u2A01", "xotime": "\u2A02", "xrarr": "\u27F6", "xrArr": "\u27F9", "xscr": "\u{1D4CD}", "Xscr": "\u{1D4B3}", "xsqcup": "\u2A06", "xuplus": "\u2A04", "xutri": "\u25B3", "xvee": "\u22C1", "xwedge": "\u22C0", "yacute": "\xFD", "Yacute": "\xDD", "yacy": "\u044F", "YAcy": "\u042F", "ycirc": "\u0177", "Ycirc": "\u0176", "ycy": "\u044B", "Ycy": "\u042B", "yen": "\xA5", "yfr": "\u{1D536}", "Yfr": "\u{1D51C}", "yicy": "\u0457", "YIcy": "\u0407", "yopf": "\u{1D56A}", "Yopf": "\u{1D550}", "yscr": "\u{1D4CE}", "Yscr": "\u{1D4B4}", "yucy": "\u044E", "YUcy": "\u042E", "yuml": "\xFF", "Yuml": "\u0178", "zacute": "\u017A", "Zacute": "\u0179", "zcaron": "\u017E", "Zcaron": "\u017D", "zcy": "\u0437", "Zcy": "\u0417", "zdot": "\u017C", "Zdot": "\u017B", "zeetrf": "\u2128", "ZeroWidthSpace": "\u200B", "zeta": "\u03B6", "Zeta": "\u0396", "zfr": "\u{1D537}", "Zfr": "\u2128", "zhcy": "\u0436", "ZHcy": "\u0416", "zigrarr": "\u21DD", "zopf": "\u{1D56B}", "Zopf": "\u2124", "zscr": "\u{1D4CF}", "Zscr": "\u{1D4B5}", "zwj": "\u200D", "zwnj": "\u200C" }; var decodeMapLegacy = { "aacute": "\xE1", "Aacute": "\xC1", "acirc": "\xE2", "Acirc": "\xC2", "acute": "\xB4", "aelig": "\xE6", "AElig": "\xC6", "agrave": "\xE0", "Agrave": "\xC0", "amp": "&", "AMP": "&", "aring": "\xE5", "Aring": "\xC5", "atilde": "\xE3", "Atilde": "\xC3", "auml": "\xE4", "Auml": "\xC4", "brvbar": "\xA6", "ccedil": "\xE7", "Ccedil": "\xC7", "cedil": "\xB8", "cent": "\xA2", "copy": "\xA9", "COPY": "\xA9", "curren": "\xA4", "deg": "\xB0", "divide": "\xF7", "eacute": "\xE9", "Eacute": "\xC9", "ecirc": "\xEA", "Ecirc": "\xCA", "egrave": "\xE8", "Egrave": "\xC8", "eth": "\xF0", "ETH": "\xD0", "euml": "\xEB", "Euml": "\xCB", "frac12": "\xBD", "frac14": "\xBC", "frac34": "\xBE", "gt": ">", "GT": ">", "iacute": "\xED", "Iacute": "\xCD", "icirc": "\xEE", "Icirc": "\xCE", "iexcl": "\xA1", "igrave": "\xEC", "Igrave": "\xCC", "iquest": "\xBF", "iuml": "\xEF", "Iuml": "\xCF", "laquo": "\xAB", "lt": "<", "LT": "<", "macr": "\xAF", "micro": "\xB5", "middot": "\xB7", "nbsp": "\xA0", "not": "\xAC", "ntilde": "\xF1", "Ntilde": "\xD1", "oacute": "\xF3", "Oacute": "\xD3", "ocirc": "\xF4", "Ocirc": "\xD4", "ograve": "\xF2", "Ograve": "\xD2", "ordf": "\xAA", "ordm": "\xBA", "oslash": "\xF8", "Oslash": "\xD8", "otilde": "\xF5", "Otilde": "\xD5", "ouml": "\xF6", "Ouml": "\xD6", "para": "\xB6", "plusmn": "\xB1", "pound": "\xA3", "quot": '"', "QUOT": '"', "raquo": "\xBB", "reg": "\xAE", "REG": "\xAE", "sect": "\xA7", "shy": "\xAD", "sup1": "\xB9", "sup2": "\xB2", "sup3": "\xB3", "szlig": "\xDF", "thorn": "\xFE", "THORN": "\xDE", "times": "\xD7", "uacute": "\xFA", "Uacute": "\xDA", "ucirc": "\xFB", "Ucirc": "\xDB", "ugrave": "\xF9", "Ugrave": "\xD9", "uml": "\xA8", "uuml": "\xFC", "Uuml": "\xDC", "yacute": "\xFD", "Yacute": "\xDD", "yen": "\xA5", "yuml": "\xFF" }; var decodeMapNumeric = { "0": "\uFFFD", "128": "\u20AC", "130": "\u201A", "131": "\u0192", "132": "\u201E", "133": "\u2026", "134": "\u2020", "135": "\u2021", "136": "\u02C6", "137": "\u2030", "138": "\u0160", "139": "\u2039", "140": "\u0152", "142": "\u017D", "145": "\u2018", "146": "\u2019", "147": "\u201C", "148": "\u201D", "149": "\u2022", "150": "\u2013", "151": "\u2014", "152": "\u02DC", "153": "\u2122", "154": "\u0161", "155": "\u203A", "156": "\u0153", "158": "\u017E", "159": "\u0178" }; var invalidReferenceCodePoints = [1, 2, 3, 4, 5, 6, 7, 8, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 64976, 64977, 64978, 64979, 64980, 64981, 64982, 64983, 64984, 64985, 64986, 64987, 64988, 64989, 64990, 64991, 64992, 64993, 64994, 64995, 64996, 64997, 64998, 64999, 65e3, 65001, 65002, 65003, 65004, 65005, 65006, 65007, 65534, 65535, 131070, 131071, 196606, 196607, 262142, 262143, 327678, 327679, 393214, 393215, 458750, 458751, 524286, 524287, 589822, 589823, 655358, 655359, 720894, 720895, 786430, 786431, 851966, 851967, 917502, 917503, 983038, 983039, 1048574, 1048575, 1114110, 1114111]; var stringFromCharCode = String.fromCharCode; var object = {}; var hasOwnProperty = object.hasOwnProperty; var has = function(object2, propertyName) { return hasOwnProperty.call(object2, propertyName); }; var contains = function(array, value) { var index = -1; var length = array.length; while (++index < length) { if (array[index] == value) { return true; } } return false; }; var merge = function(options, defaults) { if (!options) { return defaults; } var result = {}; var key2; for (key2 in defaults) { result[key2] = has(options, key2) ? options[key2] : defaults[key2]; } return result; }; var codePointToSymbol = function(codePoint, strict) { var output = ""; if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) { if (strict) { parseError("character reference outside the permissible Unicode range"); } return "\uFFFD"; } if (has(decodeMapNumeric, codePoint)) { if (strict) { parseError("disallowed character reference"); } return decodeMapNumeric[codePoint]; } if (strict && contains(invalidReferenceCodePoints, codePoint)) { parseError("disallowed character reference"); } if (codePoint > 65535) { codePoint -= 65536; output += stringFromCharCode(codePoint >>> 10 & 1023 | 55296); codePoint = 56320 | codePoint & 1023; } output += stringFromCharCode(codePoint); return output; }; var hexEscape = function(codePoint) { return "&#x" + codePoint.toString(16).toUpperCase() + ";"; }; var decEscape = function(codePoint) { return "&#" + codePoint + ";"; }; var parseError = function(message) { throw Error("Parse error: " + message); }; var encode = function(string, options) { options = merge(options, encode.options); var strict = options.strict; if (strict && regexInvalidRawCodePoint.test(string)) { parseError("forbidden code point"); } var encodeEverything = options.encodeEverything; var useNamedReferences = options.useNamedReferences; var allowUnsafeSymbols = options.allowUnsafeSymbols; var escapeCodePoint = options.decimal ? decEscape : hexEscape; var escapeBmpSymbol = function(symbol) { return escapeCodePoint(symbol.charCodeAt(0)); }; if (encodeEverything) { string = string.replace(regexAsciiWhitelist, function(symbol) { if (useNamedReferences && has(encodeMap, symbol)) { return "&" + encodeMap[symbol] + ";"; } return escapeBmpSymbol(symbol); }); if (useNamedReferences) { string = string.replace(/>\u20D2/g, ">⃒").replace(/<\u20D2/g, "<⃒").replace(/fj/g, "fj"); } if (useNamedReferences) { string = string.replace(regexEncodeNonAscii, function(string2) { return "&" + encodeMap[string2] + ";"; }); } } else if (useNamedReferences) { if (!allowUnsafeSymbols) { string = string.replace(regexEscape, function(string2) { return "&" + encodeMap[string2] + ";"; }); } string = string.replace(/>\u20D2/g, ">⃒").replace(/<\u20D2/g, "<⃒"); string = string.replace(regexEncodeNonAscii, function(string2) { return "&" + encodeMap[string2] + ";"; }); } else if (!allowUnsafeSymbols) { string = string.replace(regexEscape, escapeBmpSymbol); } return string.replace(regexAstralSymbols, function($0) { var high = $0.charCodeAt(0); var low = $0.charCodeAt(1); var codePoint = (high - 55296) * 1024 + low - 56320 + 65536; return escapeCodePoint(codePoint); }).replace(regexBmpWhitelist, escapeBmpSymbol); }; encode.options = { "allowUnsafeSymbols": false, "encodeEverything": false, "strict": false, "useNamedReferences": false, "decimal": false }; var decode2 = function(html, options) { options = merge(options, decode2.options); var strict = options.strict; if (strict && regexInvalidEntity.test(html)) { parseError("malformed character reference"); } return html.replace(regexDecode, function($0, $1, $2, $3, $4, $5, $6, $7, $8) { var codePoint; var semicolon; var decDigits; var hexDigits; var reference; var next; if ($1) { reference = $1; return decodeMap[reference]; } if ($2) { reference = $2; next = $3; if (next && options.isAttributeValue) { if (strict && next == "=") { parseError("`&` did not start a character reference"); } return $0; } else { if (strict) { parseError("named character reference was not terminated by a semicolon"); } return decodeMapLegacy[reference] + (next || ""); } } if ($4) { decDigits = $4; semicolon = $5; if (strict && !semicolon) { parseError("character reference was not terminated by a semicolon"); } codePoint = parseInt(decDigits, 10); return codePointToSymbol(codePoint, strict); } if ($6) { hexDigits = $6; semicolon = $7; if (strict && !semicolon) { parseError("character reference was not terminated by a semicolon"); } codePoint = parseInt(hexDigits, 16); return codePointToSymbol(codePoint, strict); } if (strict) { parseError("named character reference was not terminated by a semicolon"); } return $0; }); }; decode2.options = { "isAttributeValue": false, "strict": false }; var escape2 = function(string) { return string.replace(regexEscape, function($0) { return escapeMap[$0]; }); }; var he = { "version": "1.2.0", "encode": encode, "decode": decode2, "escape": escape2, "unescape": decode2 }; if (typeof define == "function" && typeof define.amd == "object" && define.amd) { define(function() { return he; }); } else if (freeExports && !freeExports.nodeType) { if (freeModule) { freeModule.exports = he; } else { for (var key in he) { has(he, key) && (freeExports[key] = he[key]); } } } else { root.he = he; } })(exports); } }); // src/main.ts __export(exports, { default: () => DiceRollerPlugin }); var import_obsidian8 = __toModule(require("obsidian")); var import_lex = __toModule(require_lexer()); // node_modules/@fortawesome/free-solid-svg-icons/index.es.js var faDice = { prefix: "fas", iconName: "dice", icon: [640, 512, [], "f522", "M592 192H473.26c12.69 29.59 7.12 65.2-17 89.32L320 417.58V464c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48V240c0-26.51-21.49-48-48-48zM480 376c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm-46.37-186.7L258.7 14.37c-19.16-19.16-50.23-19.16-69.39 0L14.37 189.3c-19.16 19.16-19.16 50.23 0 69.39L189.3 433.63c19.16 19.16 50.23 19.16 69.39 0L433.63 258.7c19.16-19.17 19.16-50.24 0-69.4zM96 248c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm128 128c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm0-128c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm0-128c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24zm128 128c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z"] }; // node_modules/@fortawesome/free-regular-svg-icons/index.es.js var faCopy = { prefix: "far", iconName: "copy", icon: [448, 512, [], "f0c5", "M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"] }; // node_modules/@fortawesome/fontawesome-svg-core/index.es.js function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function(obj2) { return typeof obj2; }; } else { _typeof = function(obj2) { return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty(target, key, source[key]); }); } return target; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = void 0; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } var noop = function noop2() { }; var _WINDOW = {}; var _DOCUMENT = {}; var _MUTATION_OBSERVER = null; var _PERFORMANCE = { mark: noop, measure: noop }; try { if (typeof window !== "undefined") _WINDOW = window; if (typeof document !== "undefined") _DOCUMENT = document; if (typeof MutationObserver !== "undefined") _MUTATION_OBSERVER = MutationObserver; if (typeof performance !== "undefined") _PERFORMANCE = performance; } catch (e) { } var _ref = _WINDOW.navigator || {}; var _ref$userAgent = _ref.userAgent; var userAgent = _ref$userAgent === void 0 ? "" : _ref$userAgent; var WINDOW = _WINDOW; var DOCUMENT = _DOCUMENT; var PERFORMANCE = _PERFORMANCE; var IS_BROWSER = !!WINDOW.document; var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === "function" && typeof DOCUMENT.createElement === "function"; var IS_IE = ~userAgent.indexOf("MSIE") || ~userAgent.indexOf("Trident/"); var NAMESPACE_IDENTIFIER = "___FONT_AWESOME___"; var DEFAULT_FAMILY_PREFIX = "fa"; var DEFAULT_REPLACEMENT_CLASS = "svg-inline--fa"; var DATA_FA_I2SVG = "data-fa-i2svg"; var PRODUCTION = function() { try { return false; } catch (e) { return false; } }(); var oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]); var DUOTONE_CLASSES = { GROUP: "group", SWAP_OPACITY: "swap-opacity", PRIMARY: "primary", SECONDARY: "secondary" }; var RESERVED_CLASSES = ["xs", "sm", "lg", "fw", "ul", "li", "border", "pull-left", "pull-right", "spin", "pulse", "rotate-90", "rotate-180", "rotate-270", "flip-horizontal", "flip-vertical", "flip-both", "stack", "stack-1x", "stack-2x", "inverse", "layers", "layers-text", "layers-counter", DUOTONE_CLASSES.GROUP, DUOTONE_CLASSES.SWAP_OPACITY, DUOTONE_CLASSES.PRIMARY, DUOTONE_CLASSES.SECONDARY].concat(oneToTen.map(function(n) { return "".concat(n, "x"); })).concat(oneToTwenty.map(function(n) { return "w-".concat(n); })); var initial = WINDOW.FontAwesomeConfig || {}; function getAttrConfig(attr) { var element = DOCUMENT.querySelector("script[" + attr + "]"); if (element) { return element.getAttribute(attr); } } function coerce(val) { if (val === "") return true; if (val === "false") return false; if (val === "true") return true; return val; } if (DOCUMENT && typeof DOCUMENT.querySelector === "function") { attrs = [["data-family-prefix", "familyPrefix"], ["data-replacement-class", "replacementClass"], ["data-auto-replace-svg", "autoReplaceSvg"], ["data-auto-add-css", "autoAddCss"], ["data-auto-a11y", "autoA11y"], ["data-search-pseudo-elements", "searchPseudoElements"], ["data-observe-mutations", "observeMutations"], ["data-mutate-approach", "mutateApproach"], ["data-keep-original-source", "keepOriginalSource"], ["data-measure-performance", "measurePerformance"], ["data-show-missing-icons", "showMissingIcons"]]; attrs.forEach(function(_ref2) { var _ref22 = _slicedToArray(_ref2, 2), attr = _ref22[0], key = _ref22[1]; var val = coerce(getAttrConfig(attr)); if (val !== void 0 && val !== null) { initial[key] = val; } }); } var attrs; var _default = { familyPrefix: DEFAULT_FAMILY_PREFIX, replacementClass: DEFAULT_REPLACEMENT_CLASS, autoReplaceSvg: true, autoAddCss: true, autoA11y: true, searchPseudoElements: false, observeMutations: true, mutateApproach: "async", keepOriginalSource: true, measurePerformance: false, showMissingIcons: true }; var _config = _objectSpread({}, _default, initial); if (!_config.autoReplaceSvg) _config.observeMutations = false; var config = _objectSpread({}, _config); WINDOW.FontAwesomeConfig = config; var w = WINDOW || {}; if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {}; if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {}; if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {}; if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = []; var namespace = w[NAMESPACE_IDENTIFIER]; var functions = []; var listener = function listener2() { DOCUMENT.removeEventListener("DOMContentLoaded", listener2); loaded = 1; functions.map(function(fn) { return fn(); }); }; var loaded = false; if (IS_DOM) { loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState); if (!loaded) DOCUMENT.addEventListener("DOMContentLoaded", listener); } var PENDING = "pending"; var SETTLED = "settled"; var FULFILLED = "fulfilled"; var REJECTED = "rejected"; var NOOP = function NOOP2() { }; var isNode = typeof global !== "undefined" && typeof global.process !== "undefined" && typeof global.process.emit === "function"; var asyncSetTimer = typeof setImmediate === "undefined" ? setTimeout : setImmediate; var asyncQueue = []; var asyncTimer; function asyncFlush() { for (var i = 0; i < asyncQueue.length; i++) { asyncQueue[i][0](asyncQueue[i][1]); } asyncQueue = []; asyncTimer = false; } function asyncCall(callback, arg) { asyncQueue.push([callback, arg]); if (!asyncTimer) { asyncTimer = true; asyncSetTimer(asyncFlush, 0); } } function invokeResolver(resolver, promise) { function resolvePromise(value) { resolve(promise, value); } function rejectPromise(reason) { reject(promise, reason); } try { resolver(resolvePromise, rejectPromise); } catch (e) { rejectPromise(e); } } function invokeCallback(subscriber) { var owner = subscriber.owner; var settled = owner._state; var value = owner._data; var callback = subscriber[settled]; var promise = subscriber.then; if (typeof callback === "function") { settled = FULFILLED; try { value = callback(value); } catch (e) { reject(promise, e); } } if (!handleThenable(promise, value)) { if (settled === FULFILLED) { resolve(promise, value); } if (settled === REJECTED) { reject(promise, value); } } } function handleThenable(promise, value) { var resolved; try { if (promise === value) { throw new TypeError("A promises callback cannot return that same promise."); } if (value && (typeof value === "function" || _typeof(value) === "object")) { var then2 = value.then; if (typeof then2 === "function") { then2.call(value, function(val) { if (!resolved) { resolved = true; if (value === val) { fulfill(promise, val); } else { resolve(promise, val); } } }, function(reason) { if (!resolved) { resolved = true; reject(promise, reason); } }); return true; } } } catch (e) { if (!resolved) { reject(promise, e); } return true; } return false; } function resolve(promise, value) { if (promise === value || !handleThenable(promise, value)) { fulfill(promise, value); } } function fulfill(promise, value) { if (promise._state === PENDING) { promise._state = SETTLED; promise._data = value; asyncCall(publishFulfillment, promise); } } function reject(promise, reason) { if (promise._state === PENDING) { promise._state = SETTLED; promise._data = reason; asyncCall(publishRejection, promise); } } function publish(promise) { promise._then = promise._then.forEach(invokeCallback); } function publishFulfillment(promise) { promise._state = FULFILLED; publish(promise); } function publishRejection(promise) { promise._state = REJECTED; publish(promise); if (!promise._handled && isNode) { global.process.emit("unhandledRejection", promise._data, promise); } } function notifyRejectionHandled(promise) { global.process.emit("rejectionHandled", promise); } function P(resolver) { if (typeof resolver !== "function") { throw new TypeError("Promise resolver " + resolver + " is not a function"); } if (this instanceof P === false) { throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); } this._then = []; invokeResolver(resolver, this); } P.prototype = { constructor: P, _state: PENDING, _then: null, _data: void 0, _handled: false, then: function then(onFulfillment, onRejection) { var subscriber = { owner: this, then: new this.constructor(NOOP), fulfilled: onFulfillment, rejected: onRejection }; if ((onRejection || onFulfillment) && !this._handled) { this._handled = true; if (this._state === REJECTED && isNode) { asyncCall(notifyRejectionHandled, this); } } if (this._state === FULFILLED || this._state === REJECTED) { asyncCall(invokeCallback, subscriber); } else { this._then.push(subscriber); } return subscriber.then; }, catch: function _catch(onRejection) { return this.then(null, onRejection); } }; P.all = function(promises) { if (!Array.isArray(promises)) { throw new TypeError("You must pass an array to Promise.all()."); } return new P(function(resolve2, reject2) { var results = []; var remaining = 0; function resolver(index) { remaining++; return function(value) { results[index] = value; if (!--remaining) { resolve2(results); } }; } for (var i = 0, promise; i < promises.length; i++) { promise = promises[i]; if (promise && typeof promise.then === "function") { promise.then(resolver(i), reject2); } else { results[i] = promise; } } if (!remaining) { resolve2(results); } }); }; P.race = function(promises) { if (!Array.isArray(promises)) { throw new TypeError("You must pass an array to Promise.race()."); } return new P(function(resolve2, reject2) { for (var i = 0, promise; i < promises.length; i++) { promise = promises[i]; if (promise && typeof promise.then === "function") { promise.then(resolve2, reject2); } else { resolve2(promise); } } }); }; P.resolve = function(value) { if (value && _typeof(value) === "object" && value.constructor === P) { return value; } return new P(function(resolve2) { resolve2(value); }); }; P.reject = function(reason) { return new P(function(resolve2, reject2) { reject2(reason); }); }; var meaninglessTransform = { size: 16, x: 0, y: 0, rotate: 0, flipX: false, flipY: false }; function insertCss(css2) { if (!css2 || !IS_DOM) { return; } var style = DOCUMENT.createElement("style"); style.setAttribute("type", "text/css"); style.innerHTML = css2; var headChildren = DOCUMENT.head.childNodes; var beforeChild = null; for (var i = headChildren.length - 1; i > -1; i--) { var child = headChildren[i]; var tagName = (child.tagName || "").toUpperCase(); if (["STYLE", "LINK"].indexOf(tagName) > -1) { beforeChild = child; } } DOCUMENT.head.insertBefore(style, beforeChild); return css2; } var idPool = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; function nextUniqueId() { var size = 12; var id = ""; while (size-- > 0) { id += idPool[Math.random() * 62 | 0]; } return id; } function htmlEscape(str) { return "".concat(str).replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(//g, ">"); } function joinAttributes(attributes) { return Object.keys(attributes || {}).reduce(function(acc, attributeName) { return acc + "".concat(attributeName, '="').concat(htmlEscape(attributes[attributeName]), '" '); }, "").trim(); } function joinStyles(styles2) { return Object.keys(styles2 || {}).reduce(function(acc, styleName) { return acc + "".concat(styleName, ": ").concat(styles2[styleName], ";"); }, ""); } function transformIsMeaningful(transform) { return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY; } function transformForSvg(_ref2) { var transform = _ref2.transform, containerWidth = _ref2.containerWidth, iconWidth = _ref2.iconWidth; var outer = { transform: "translate(".concat(containerWidth / 2, " 256)") }; var innerTranslate = "translate(".concat(transform.x * 32, ", ").concat(transform.y * 32, ") "); var innerScale = "scale(".concat(transform.size / 16 * (transform.flipX ? -1 : 1), ", ").concat(transform.size / 16 * (transform.flipY ? -1 : 1), ") "); var innerRotate = "rotate(".concat(transform.rotate, " 0 0)"); var inner = { transform: "".concat(innerTranslate, " ").concat(innerScale, " ").concat(innerRotate) }; var path = { transform: "translate(".concat(iconWidth / 2 * -1, " -256)") }; return { outer, inner, path }; } var ALL_SPACE = { x: 0, y: 0, width: "100%", height: "100%" }; function fillBlack(abstract) { var force = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true; if (abstract.attributes && (abstract.attributes.fill || force)) { abstract.attributes.fill = "black"; } return abstract; } function deGroup(abstract) { if (abstract.tag === "g") { return abstract.children; } else { return [abstract]; } } function makeIconMasking(_ref2) { var children = _ref2.children, attributes = _ref2.attributes, main = _ref2.main, mask = _ref2.mask, explicitMaskId = _ref2.maskId, transform = _ref2.transform; var mainWidth = main.width, mainPath = main.icon; var maskWidth = mask.width, maskPath = mask.icon; var trans = transformForSvg({ transform, containerWidth: maskWidth, iconWidth: mainWidth }); var maskRect = { tag: "rect", attributes: _objectSpread({}, ALL_SPACE, { fill: "white" }) }; var maskInnerGroupChildrenMixin = mainPath.children ? { children: mainPath.children.map(fillBlack) } : {}; var maskInnerGroup = { tag: "g", attributes: _objectSpread({}, trans.inner), children: [fillBlack(_objectSpread({ tag: mainPath.tag, attributes: _objectSpread({}, mainPath.attributes, trans.path) }, maskInnerGroupChildrenMixin))] }; var maskOuterGroup = { tag: "g", attributes: _objectSpread({}, trans.outer), children: [maskInnerGroup] }; var maskId = "mask-".concat(explicitMaskId || nextUniqueId()); var clipId = "clip-".concat(explicitMaskId || nextUniqueId()); var maskTag = { tag: "mask", attributes: _objectSpread({}, ALL_SPACE, { id: maskId, maskUnits: "userSpaceOnUse", maskContentUnits: "userSpaceOnUse" }), children: [maskRect, maskOuterGroup] }; var defs = { tag: "defs", children: [{ tag: "clipPath", attributes: { id: clipId }, children: deGroup(maskPath) }, maskTag] }; children.push(defs, { tag: "rect", attributes: _objectSpread({ fill: "currentColor", "clip-path": "url(#".concat(clipId, ")"), mask: "url(#".concat(maskId, ")") }, ALL_SPACE) }); return { children, attributes }; } function makeIconStandard(_ref2) { var children = _ref2.children, attributes = _ref2.attributes, main = _ref2.main, transform = _ref2.transform, styles2 = _ref2.styles; var styleString = joinStyles(styles2); if (styleString.length > 0) { attributes["style"] = styleString; } if (transformIsMeaningful(transform)) { var trans = transformForSvg({ transform, containerWidth: main.width, iconWidth: main.width }); children.push({ tag: "g", attributes: _objectSpread({}, trans.outer), children: [{ tag: "g", attributes: _objectSpread({}, trans.inner), children: [{ tag: main.icon.tag, children: main.icon.children, attributes: _objectSpread({}, main.icon.attributes, trans.path) }] }] }); } else { children.push(main.icon); } return { children, attributes }; } function asIcon(_ref2) { var children = _ref2.children, main = _ref2.main, mask = _ref2.mask, attributes = _ref2.attributes, styles2 = _ref2.styles, transform = _ref2.transform; if (transformIsMeaningful(transform) && main.found && !mask.found) { var width = main.width, height = main.height; var offset = { x: width / height / 2, y: 0.5 }; attributes["style"] = joinStyles(_objectSpread({}, styles2, { "transform-origin": "".concat(offset.x + transform.x / 16, "em ").concat(offset.y + transform.y / 16, "em") })); } return [{ tag: "svg", attributes, children }]; } function asSymbol(_ref2) { var prefix = _ref2.prefix, iconName = _ref2.iconName, children = _ref2.children, attributes = _ref2.attributes, symbol = _ref2.symbol; var id = symbol === true ? "".concat(prefix, "-").concat(config.familyPrefix, "-").concat(iconName) : symbol; return [{ tag: "svg", attributes: { style: "display: none;" }, children: [{ tag: "symbol", attributes: _objectSpread({}, attributes, { id }), children }] }]; } function makeInlineSvgAbstract(params) { var _params$icons = params.icons, main = _params$icons.main, mask = _params$icons.mask, prefix = params.prefix, iconName = params.iconName, transform = params.transform, symbol = params.symbol, title = params.title, maskId = params.maskId, titleId = params.titleId, extra = params.extra, _params$watchable = params.watchable, watchable = _params$watchable === void 0 ? false : _params$watchable; var _ref2 = mask.found ? mask : main, width = _ref2.width, height = _ref2.height; var isUploadedIcon = prefix === "fak"; var widthClass = isUploadedIcon ? "" : "fa-w-".concat(Math.ceil(width / height * 16)); var attrClass = [config.replacementClass, iconName ? "".concat(config.familyPrefix, "-").concat(iconName) : "", widthClass].filter(function(c2) { return extra.classes.indexOf(c2) === -1; }).filter(function(c2) { return c2 !== "" || !!c2; }).concat(extra.classes).join(" "); var content = { children: [], attributes: _objectSpread({}, extra.attributes, { "data-prefix": prefix, "data-icon": iconName, "class": attrClass, "role": extra.attributes.role || "img", "xmlns": "http://www.w3.org/2000/svg", "viewBox": "0 0 ".concat(width, " ").concat(height) }) }; var uploadedIconWidthStyle = isUploadedIcon && !~extra.classes.indexOf("fa-fw") ? { width: "".concat(width / height * 16 * 0.0625, "em") } : {}; if (watchable) { content.attributes[DATA_FA_I2SVG] = ""; } if (title) content.children.push({ tag: "title", attributes: { id: content.attributes["aria-labelledby"] || "title-".concat(titleId || nextUniqueId()) }, children: [title] }); var args = _objectSpread({}, content, { prefix, iconName, main, mask, maskId, transform, symbol, styles: _objectSpread({}, uploadedIconWidthStyle, extra.styles) }); var _ref22 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args), children = _ref22.children, attributes = _ref22.attributes; args.children = children; args.attributes = attributes; if (symbol) { return asSymbol(args); } else { return asIcon(args); } } var noop$1 = function noop3() { }; var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : { mark: noop$1, measure: noop$1 }; var bindInternal4 = function bindInternal42(func, thisContext) { return function(a2, b2, c2, d) { return func.call(thisContext, a2, b2, c2, d); }; }; var reduce = function fastReduceObject(subject, fn, initialValue, thisContext) { var keys = Object.keys(subject), length = keys.length, iterator = thisContext !== void 0 ? bindInternal4(fn, thisContext) : fn, i, key, result; if (initialValue === void 0) { i = 1; result = subject[keys[0]]; } else { i = 0; result = initialValue; } for (; i < length; i++) { key = keys[i]; result = iterator(result, subject[key], key, subject); } return result; }; function defineIcons(prefix, icons) { var params = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}; var _params$skipHooks = params.skipHooks, skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks; var normalized = Object.keys(icons).reduce(function(acc, iconName) { var icon2 = icons[iconName]; var expanded = !!icon2.icon; if (expanded) { acc[icon2.iconName] = icon2.icon; } else { acc[iconName] = icon2; } return acc; }, {}); if (typeof namespace.hooks.addPack === "function" && !skipHooks) { namespace.hooks.addPack(prefix, normalized); } else { namespace.styles[prefix] = _objectSpread({}, namespace.styles[prefix] || {}, normalized); } if (prefix === "fas") { defineIcons("fa", icons); } } var styles = namespace.styles; var shims = namespace.shims; var _byUnicode = {}; var _byLigature = {}; var _byOldName = {}; var build = function build2() { var lookup = function lookup2(reducer) { return reduce(styles, function(o, style, prefix) { o[prefix] = reduce(style, reducer, {}); return o; }, {}); }; _byUnicode = lookup(function(acc, icon2, iconName) { if (icon2[3]) { acc[icon2[3]] = iconName; } return acc; }); _byLigature = lookup(function(acc, icon2, iconName) { var ligatures = icon2[2]; acc[iconName] = iconName; ligatures.forEach(function(ligature) { acc[ligature] = iconName; }); return acc; }); var hasRegular = "far" in styles; _byOldName = reduce(shims, function(acc, shim) { var oldName = shim[0]; var prefix = shim[1]; var iconName = shim[2]; if (prefix === "far" && !hasRegular) { prefix = "fas"; } acc[oldName] = { prefix, iconName }; return acc; }, {}); }; build(); var styles$1 = namespace.styles; function iconFromMapping(mapping, prefix, iconName) { if (mapping && mapping[prefix] && mapping[prefix][iconName]) { return { prefix, iconName, icon: mapping[prefix][iconName] }; } } function toHtml(abstractNodes) { var tag = abstractNodes.tag, _abstractNodes$attrib = abstractNodes.attributes, attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib, _abstractNodes$childr = abstractNodes.children, children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr; if (typeof abstractNodes === "string") { return htmlEscape(abstractNodes); } else { return "<".concat(tag, " ").concat(joinAttributes(attributes), ">").concat(children.map(toHtml).join(""), ""); } } function MissingIcon(error) { this.name = "MissingIcon"; this.message = error || "Icon unavailable"; this.stack = new Error().stack; } MissingIcon.prototype = Object.create(Error.prototype); MissingIcon.prototype.constructor = MissingIcon; var FILL = { fill: "currentColor" }; var ANIMATION_BASE = { attributeType: "XML", repeatCount: "indefinite", dur: "2s" }; var RING = { tag: "path", attributes: _objectSpread({}, FILL, { d: "M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z" }) }; var OPACITY_ANIMATE = _objectSpread({}, ANIMATION_BASE, { attributeName: "opacity" }); var DOT = { tag: "circle", attributes: _objectSpread({}, FILL, { cx: "256", cy: "364", r: "28" }), children: [{ tag: "animate", attributes: _objectSpread({}, ANIMATION_BASE, { attributeName: "r", values: "28;14;28;28;14;28;" }) }, { tag: "animate", attributes: _objectSpread({}, OPACITY_ANIMATE, { values: "1;0;1;1;0;1;" }) }] }; var QUESTION = { tag: "path", attributes: _objectSpread({}, FILL, { opacity: "1", d: "M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z" }), children: [{ tag: "animate", attributes: _objectSpread({}, OPACITY_ANIMATE, { values: "1;0;0;0;0;1;" }) }] }; var EXCLAMATION = { tag: "path", attributes: _objectSpread({}, FILL, { opacity: "0", d: "M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z" }), children: [{ tag: "animate", attributes: _objectSpread({}, OPACITY_ANIMATE, { values: "0;0;1;1;0;0;" }) }] }; var styles$2 = namespace.styles; function asFoundIcon(icon2) { var width = icon2[0]; var height = icon2[1]; var _icon$slice = icon2.slice(4), _icon$slice2 = _slicedToArray(_icon$slice, 1), vectorData = _icon$slice2[0]; var element = null; if (Array.isArray(vectorData)) { element = { tag: "g", attributes: { class: "".concat(config.familyPrefix, "-").concat(DUOTONE_CLASSES.GROUP) }, children: [{ tag: "path", attributes: { class: "".concat(config.familyPrefix, "-").concat(DUOTONE_CLASSES.SECONDARY), fill: "currentColor", d: vectorData[0] } }, { tag: "path", attributes: { class: "".concat(config.familyPrefix, "-").concat(DUOTONE_CLASSES.PRIMARY), fill: "currentColor", d: vectorData[1] } }] }; } else { element = { tag: "path", attributes: { fill: "currentColor", d: vectorData } }; } return { found: true, width, height, icon: element }; } var styles$3 = namespace.styles; var baseStyles = 'svg:not(:root).svg-inline--fa {\n overflow: visible;\n}\n\n.svg-inline--fa {\n display: inline-block;\n font-size: inherit;\n height: 1em;\n overflow: visible;\n vertical-align: -0.125em;\n}\n.svg-inline--fa.fa-lg {\n vertical-align: -0.225em;\n}\n.svg-inline--fa.fa-w-1 {\n width: 0.0625em;\n}\n.svg-inline--fa.fa-w-2 {\n width: 0.125em;\n}\n.svg-inline--fa.fa-w-3 {\n width: 0.1875em;\n}\n.svg-inline--fa.fa-w-4 {\n width: 0.25em;\n}\n.svg-inline--fa.fa-w-5 {\n width: 0.3125em;\n}\n.svg-inline--fa.fa-w-6 {\n width: 0.375em;\n}\n.svg-inline--fa.fa-w-7 {\n width: 0.4375em;\n}\n.svg-inline--fa.fa-w-8 {\n width: 0.5em;\n}\n.svg-inline--fa.fa-w-9 {\n width: 0.5625em;\n}\n.svg-inline--fa.fa-w-10 {\n width: 0.625em;\n}\n.svg-inline--fa.fa-w-11 {\n width: 0.6875em;\n}\n.svg-inline--fa.fa-w-12 {\n width: 0.75em;\n}\n.svg-inline--fa.fa-w-13 {\n width: 0.8125em;\n}\n.svg-inline--fa.fa-w-14 {\n width: 0.875em;\n}\n.svg-inline--fa.fa-w-15 {\n width: 0.9375em;\n}\n.svg-inline--fa.fa-w-16 {\n width: 1em;\n}\n.svg-inline--fa.fa-w-17 {\n width: 1.0625em;\n}\n.svg-inline--fa.fa-w-18 {\n width: 1.125em;\n}\n.svg-inline--fa.fa-w-19 {\n width: 1.1875em;\n}\n.svg-inline--fa.fa-w-20 {\n width: 1.25em;\n}\n.svg-inline--fa.fa-pull-left {\n margin-right: 0.3em;\n width: auto;\n}\n.svg-inline--fa.fa-pull-right {\n margin-left: 0.3em;\n width: auto;\n}\n.svg-inline--fa.fa-border {\n height: 1.5em;\n}\n.svg-inline--fa.fa-li {\n width: 2em;\n}\n.svg-inline--fa.fa-fw {\n width: 1.25em;\n}\n\n.fa-layers svg.svg-inline--fa {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.fa-layers {\n display: inline-block;\n height: 1em;\n position: relative;\n text-align: center;\n vertical-align: -0.125em;\n width: 1em;\n}\n.fa-layers svg.svg-inline--fa {\n -webkit-transform-origin: center center;\n transform-origin: center center;\n}\n\n.fa-layers-counter, .fa-layers-text {\n display: inline-block;\n position: absolute;\n text-align: center;\n}\n\n.fa-layers-text {\n left: 50%;\n top: 50%;\n -webkit-transform: translate(-50%, -50%);\n transform: translate(-50%, -50%);\n -webkit-transform-origin: center center;\n transform-origin: center center;\n}\n\n.fa-layers-counter {\n background-color: #ff253a;\n border-radius: 1em;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n color: #fff;\n height: 1.5em;\n line-height: 1;\n max-width: 5em;\n min-width: 1.5em;\n overflow: hidden;\n padding: 0.25em;\n right: 0;\n text-overflow: ellipsis;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top right;\n transform-origin: top right;\n}\n\n.fa-layers-bottom-right {\n bottom: 0;\n right: 0;\n top: auto;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: bottom right;\n transform-origin: bottom right;\n}\n\n.fa-layers-bottom-left {\n bottom: 0;\n left: 0;\n right: auto;\n top: auto;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: bottom left;\n transform-origin: bottom left;\n}\n\n.fa-layers-top-right {\n right: 0;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top right;\n transform-origin: top right;\n}\n\n.fa-layers-top-left {\n left: 0;\n right: auto;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top left;\n transform-origin: top left;\n}\n\n.fa-lg {\n font-size: 1.3333333333em;\n line-height: 0.75em;\n vertical-align: -0.0667em;\n}\n\n.fa-xs {\n font-size: 0.75em;\n}\n\n.fa-sm {\n font-size: 0.875em;\n}\n\n.fa-1x {\n font-size: 1em;\n}\n\n.fa-2x {\n font-size: 2em;\n}\n\n.fa-3x {\n font-size: 3em;\n}\n\n.fa-4x {\n font-size: 4em;\n}\n\n.fa-5x {\n font-size: 5em;\n}\n\n.fa-6x {\n font-size: 6em;\n}\n\n.fa-7x {\n font-size: 7em;\n}\n\n.fa-8x {\n font-size: 8em;\n}\n\n.fa-9x {\n font-size: 9em;\n}\n\n.fa-10x {\n font-size: 10em;\n}\n\n.fa-fw {\n text-align: center;\n width: 1.25em;\n}\n\n.fa-ul {\n list-style-type: none;\n margin-left: 2.5em;\n padding-left: 0;\n}\n.fa-ul > li {\n position: relative;\n}\n\n.fa-li {\n left: -2em;\n position: absolute;\n text-align: center;\n width: 2em;\n line-height: inherit;\n}\n\n.fa-border {\n border: solid 0.08em #eee;\n border-radius: 0.1em;\n padding: 0.2em 0.25em 0.15em;\n}\n\n.fa-pull-left {\n float: left;\n}\n\n.fa-pull-right {\n float: right;\n}\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n margin-right: 0.3em;\n}\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n margin-left: 0.3em;\n}\n\n.fa-spin {\n -webkit-animation: fa-spin 2s infinite linear;\n animation: fa-spin 2s infinite linear;\n}\n\n.fa-pulse {\n -webkit-animation: fa-spin 1s infinite steps(8);\n animation: fa-spin 1s infinite steps(8);\n}\n\n@-webkit-keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.fa-rotate-90 {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";\n -webkit-transform: rotate(90deg);\n transform: rotate(90deg);\n}\n\n.fa-rotate-180 {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg);\n}\n\n.fa-rotate-270 {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";\n -webkit-transform: rotate(270deg);\n transform: rotate(270deg);\n}\n\n.fa-flip-horizontal {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";\n -webkit-transform: scale(-1, 1);\n transform: scale(-1, 1);\n}\n\n.fa-flip-vertical {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";\n -webkit-transform: scale(1, -1);\n transform: scale(1, -1);\n}\n\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";\n -webkit-transform: scale(-1, -1);\n transform: scale(-1, -1);\n}\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical,\n:root .fa-flip-both {\n -webkit-filter: none;\n filter: none;\n}\n\n.fa-stack {\n display: inline-block;\n height: 2em;\n position: relative;\n width: 2.5em;\n}\n\n.fa-stack-1x,\n.fa-stack-2x {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.svg-inline--fa.fa-stack-1x {\n height: 1em;\n width: 1.25em;\n}\n.svg-inline--fa.fa-stack-2x {\n height: 2em;\n width: 2.5em;\n}\n\n.fa-inverse {\n color: #fff;\n}\n\n.sr-only {\n border: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n clip: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n position: static;\n width: auto;\n}\n\n.svg-inline--fa .fa-primary {\n fill: var(--fa-primary-color, currentColor);\n opacity: 1;\n opacity: var(--fa-primary-opacity, 1);\n}\n\n.svg-inline--fa .fa-secondary {\n fill: var(--fa-secondary-color, currentColor);\n opacity: 0.4;\n opacity: var(--fa-secondary-opacity, 0.4);\n}\n\n.svg-inline--fa.fa-swap-opacity .fa-primary {\n opacity: 0.4;\n opacity: var(--fa-secondary-opacity, 0.4);\n}\n\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\n opacity: 1;\n opacity: var(--fa-primary-opacity, 1);\n}\n\n.svg-inline--fa mask .fa-primary,\n.svg-inline--fa mask .fa-secondary {\n fill: black;\n}\n\n.fad.fa-inverse {\n color: #fff;\n}'; function css() { var dfp = DEFAULT_FAMILY_PREFIX; var drc = DEFAULT_REPLACEMENT_CLASS; var fp = config.familyPrefix; var rc = config.replacementClass; var s = baseStyles; if (fp !== dfp || rc !== drc) { var dPatt = new RegExp("\\.".concat(dfp, "\\-"), "g"); var customPropPatt = new RegExp("\\--".concat(dfp, "\\-"), "g"); var rPatt = new RegExp("\\.".concat(drc), "g"); s = s.replace(dPatt, ".".concat(fp, "-")).replace(customPropPatt, "--".concat(fp, "-")).replace(rPatt, ".".concat(rc)); } return s; } var Library = /* @__PURE__ */ function() { function Library2() { _classCallCheck(this, Library2); this.definitions = {}; } _createClass(Library2, [{ key: "add", value: function add() { var _this = this; for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) { definitions[_key] = arguments[_key]; } var additions2 = definitions.reduce(this._pullDefinitions, {}); Object.keys(additions2).forEach(function(key) { _this.definitions[key] = _objectSpread({}, _this.definitions[key] || {}, additions2[key]); defineIcons(key, additions2[key]); build(); }); } }, { key: "reset", value: function reset() { this.definitions = {}; } }, { key: "_pullDefinitions", value: function _pullDefinitions(additions2, definition) { var normalized = definition.prefix && definition.iconName && definition.icon ? { 0: definition } : definition; Object.keys(normalized).map(function(key) { var _normalized$key = normalized[key], prefix = _normalized$key.prefix, iconName = _normalized$key.iconName, icon2 = _normalized$key.icon; if (!additions2[prefix]) additions2[prefix] = {}; additions2[prefix][iconName] = icon2; }); return additions2; } }]); return Library2; }(); function ensureCss() { if (config.autoAddCss && !_cssInserted) { insertCss(css()); _cssInserted = true; } } function apiObject(val, abstractCreator) { Object.defineProperty(val, "abstract", { get: abstractCreator }); Object.defineProperty(val, "html", { get: function get() { return val.abstract.map(function(a2) { return toHtml(a2); }); } }); Object.defineProperty(val, "node", { get: function get() { if (!IS_DOM) return; var container = DOCUMENT.createElement("div"); container.innerHTML = val.html; return container.children; } }); return val; } function findIconDefinition(iconLookup) { var _iconLookup$prefix = iconLookup.prefix, prefix = _iconLookup$prefix === void 0 ? "fa" : _iconLookup$prefix, iconName = iconLookup.iconName; if (!iconName) return; return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName); } function resolveIcons(next) { return function(maybeIconDefinition) { var params = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {}); var mask = params.mask; if (mask) { mask = (mask || {}).icon ? mask : findIconDefinition(mask || {}); } return next(iconDefinition, _objectSpread({}, params, { mask })); }; } var library = new Library(); var _cssInserted = false; var icon = resolveIcons(function(iconDefinition) { var params = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; var _params$transform = params.transform, transform = _params$transform === void 0 ? meaninglessTransform : _params$transform, _params$symbol = params.symbol, symbol = _params$symbol === void 0 ? false : _params$symbol, _params$mask = params.mask, mask = _params$mask === void 0 ? null : _params$mask, _params$maskId = params.maskId, maskId = _params$maskId === void 0 ? null : _params$maskId, _params$title = params.title, title = _params$title === void 0 ? null : _params$title, _params$titleId = params.titleId, titleId = _params$titleId === void 0 ? null : _params$titleId, _params$classes = params.classes, classes = _params$classes === void 0 ? [] : _params$classes, _params$attributes = params.attributes, attributes = _params$attributes === void 0 ? {} : _params$attributes, _params$styles = params.styles, styles2 = _params$styles === void 0 ? {} : _params$styles; if (!iconDefinition) return; var prefix = iconDefinition.prefix, iconName = iconDefinition.iconName, icon2 = iconDefinition.icon; return apiObject(_objectSpread({ type: "icon" }, iconDefinition), function() { ensureCss(); if (config.autoA11y) { if (title) { attributes["aria-labelledby"] = "".concat(config.replacementClass, "-title-").concat(titleId || nextUniqueId()); } else { attributes["aria-hidden"] = "true"; attributes["focusable"] = "false"; } } return makeInlineSvgAbstract({ icons: { main: asFoundIcon(icon2), mask: mask ? asFoundIcon(mask.icon) : { found: false, width: null, height: null, icon: {} } }, prefix, iconName, transform: _objectSpread({}, meaninglessTransform, transform), symbol, title, maskId, titleId, extra: { attributes, styles: styles2, classes } }); }); }); // src/parser/parser.ts var Parser = class { constructor(table) { this.table = table; } parse(input) { var length = input.length, table = this.table, output = [], stack = [], index = 0; while (index < length) { var token = input[index++]; switch (token.data) { case "(": stack.unshift(token); break; case ")": if (input[index] && input[index].type == "dice" && /^d/.test(input[index].original)) { input[index].parenedDice = true; } while (stack.length) { var token = stack.shift(); if (token.data === "(") break; else { output.push(token); } } if (token.data !== "(") throw new Error("Mismatched parentheses."); break; default: if (table.hasOwnProperty(token.data)) { while (stack.length) { var punctuator = stack[0]; if (punctuator.data === "(") break; var operator = table[token.data], precedence = operator.precedence, antecedence = table[punctuator.data].precedence; if (precedence > antecedence || precedence === antecedence && operator.associativity === "right") break; else output.push(stack.shift()); } stack.unshift(token); } else { output.push(token); } } } while (stack.length) { var token = stack.shift(); if (token.data !== "(") output.push(token); else throw new Error("Mismatched parentheses."); } return output; } }; // node_modules/monkey-around/mjs/index.js function around(obj, factories) { const removers = Object.keys(factories).map((key) => around1(obj, key, factories[key])); return removers.length === 1 ? removers[0] : function() { removers.forEach((r) => r()); }; } function around1(obj, method, createWrapper) { const original = obj[method], hadOwn = obj.hasOwnProperty(method); let current = createWrapper(original); if (original) Object.setPrototypeOf(current, original); Object.setPrototypeOf(wrapper, current); obj[method] = wrapper; return remove; function wrapper(...args) { if (current === original && obj[method] === wrapper) remove(); return current.apply(this, args); } function remove() { if (obj[method] === wrapper) { if (hadOwn) obj[method] = original; else delete obj[method]; } if (current === original) return; current = original; Object.setPrototypeOf(wrapper, original || Function); } } // src/main.ts var import_he = __toModule(require_he()); // src/utils/constants.ts var TAG_REGEX = /(?:(?\d+)[Dd])?#(?[\p{Letter}\p{Emoji_Presentation}\w/-]+)(?:\|(?[\+-]))?(?:\|(?[^\+-]+))?/u; var TABLE_REGEX = /(?:(?\d+)[Dd])?\[\[(?[\s\S]+?)#?\^(?[\s\S]+?)\]\]\|?(?
[\s\S]+)?/; var SECTION_REGEX = /(?:(?\d+)[Dd])?\[\[(?[\s\S]+)\]\]\|?(?[\s\S]+)?/; var MATH_REGEX = /[\(\^\+\-\*\/\)]/; var DICE_REGEX = /(?(?\d+)(?:[Dd]?\[?(?:-?\d+\s?,)?\s?(?:-?\d+|%|F)\]?)?)(?(?:(?:=|=!|<|>|<=|>=|=<|=>|\-=|=\-)\d+)*)?/; var OMITTED_REGEX = /(?\d+)?[Dd](?\[?(?:-?\d+\s?,)?\s?(?:-?\d+|%|F)\]?)?(?(?:(?:=|=!|<|>|<=|>=|=<|=>|\-=|=\-)\d+)*)?/; var CONDITIONAL_REGEX = /(?:(?=|=!|<|>|<=|>=|=<|=>|\-=|=\-)(?\d+))/g; var ICON_DEFINITION = "dice-roller-icon"; var COPY_DEFINITION = "dice-roller-copy"; // src/roller/dice.ts var import_obsidian2 = __toModule(require("obsidian")); // src/utils/util.ts function _insertIntoMap(map, index, value) { let toUpdate = [...map].slice(index).reverse(); toUpdate.forEach(([key, value2]) => { map.set(key + 1, value2); }); map.set(index, value); } // src/roller/roller.ts var import_obsidian = __toModule(require("obsidian")); var BasicRoller = class extends import_obsidian.Events { constructor(plugin, original, lexemes, showDice = plugin.data.showDice) { super(); this.plugin = plugin; this.original = original; this.lexemes = lexemes; this.showDice = showDice; this.loaded = false; this.containerEl = createDiv({ cls: "dice-roller", attr: { "aria-label-position": "top", "data-dice": this.original } }); this.save = false; this.resultEl = this.containerEl.createDiv("dice-roller-result"); if (this.showDice) { const icon2 = this.containerEl.createDiv({ cls: "dice-roller-button" }); (0, import_obsidian.setIcon)(icon2, ICON_DEFINITION); icon2.onclick = this.onClick.bind(this); } else { this.containerEl.addClass("no-icon"); } this.containerEl.onclick = this.onClick.bind(this); } setTooltip() { if (this.plugin.data.displayResultsInline) return; this.containerEl.setAttrs({ "aria-label": this.tooltip }); } getRandomBetween(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } render() { return __async(this, null, function* () { this.setTooltip(); yield this.build(); }); } get inlineText() { return `${this.tooltip.split("\n").join(" -> ")} -> `; } onClick(evt) { return __async(this, null, function* () { var _a; evt.stopPropagation(); evt.stopImmediatePropagation(); if ((_a = window.getSelection()) == null ? void 0 : _a.isCollapsed) { yield this.roll(); } }); } }; var GenericRoller = class extends BasicRoller { }; var GenericFileRoller = class extends GenericRoller { constructor(plugin, original, lexeme, source, showDice = plugin.data.showDice) { super(plugin, original, [lexeme], showDice); this.plugin = plugin; this.original = original; this.lexeme = lexeme; this.source = source; this.getPath(); this.getFile(); } getFile() { return __async(this, null, function* () { this.file = this.plugin.app.metadataCache.getFirstLinkpathDest(this.path, this.source); if (!this.file || !(this.file instanceof import_obsidian.TFile)) throw new Error("Could not load file."); yield this.load(); this.registerFileWatcher(); }); } registerFileWatcher() { this.plugin.registerEvent(this.plugin.app.vault.on("modify", (file) => __async(this, null, function* () { if (this.save) return; if (file !== this.file) return; yield this.getOptions(); }))); } }; // src/roller/dice.ts var DiceRoller = class { constructor(dice, lexeme = { original: dice, conditionals: [], type: "dice", data: dice }) { this.lexeme = lexeme; this.modifiers = /* @__PURE__ */ new Map(); this.modifiersAllowed = true; this.static = false; this.conditions = []; var _a; if (!/(\-?\d+)[dD]?(\d+|%|\[\d+,\s?\d+\])?/.test(dice)) { throw new Error("Non parseable dice string passed to DiceRoll."); } this.dice = dice.split(" ").join(""); if (/^-?\d+$/.test(this.dice)) { this.static = true; this.modifiersAllowed = false; } let [, rolls, min = null, max = 1] = this.dice.match(/(\-?\d+)[dD]\[?(?:(-?\d+)\s?,)?\s?(-?\d+|%|F)\]?/) || [, 1, null, 1]; this.multiplier = rolls < 0 ? -1 : 1; this.rolls = Math.abs(Number(rolls)) || 1; if (Number(max) < 0 && !min) { min = -1; } if (max === "%") max = 100; if (max === "F") { max = 1; min = -1; } if (Number(max) < Number(min)) { [max, min] = [min, max]; } this.faces = { max: max ? Number(max) : 1, min: min ? Number(min) : 1 }; this.conditions = (_a = this.lexeme.conditionals) != null ? _a : []; this.results = new Map([...this.roll()].map((n, i) => { return [ i, { usable: true, value: n, display: `${n}`, modifiers: /* @__PURE__ */ new Set() } ]; })); } get text() { return `${this.result}`; } get result() { if (this.static) { return Number(this.dice); } const results = [...this.results].map(([, { usable, value }]) => usable ? value : 0); return results.reduce((a2, b2) => a2 + b2, 0); } get display() { if (this.static) { return `${this.result}`; } return `[${[...this.results].map(([, { modifiers, display }]) => `${display}${[...modifiers].join("")}`).join(", ")}]`; } keepLow(drop = 1) { if (!this.modifiersAllowed) { new import_obsidian2.Notice("Modifiers are only allowed on dice rolls."); return; } [...this.results].sort((a2, b2) => a2[1].value - b2[1].value).slice(drop - this.results.size).forEach(([index]) => { const previous = this.results.get(index); previous.usable = false; previous.modifiers.add("d"); this.results.set(index, __spreadValues({}, previous)); }); } keepHigh(drop = 1) { if (!this.modifiersAllowed) { new import_obsidian2.Notice("Modifiers are only allowed on dice rolls."); return; } [...this.results].sort((a2, b2) => b2[1].value - a2[1].value).slice(drop).forEach(([index]) => { const previous = this.results.get(index); previous.usable = false; previous.modifiers.add("d"); this.results.set(index, __spreadValues({}, previous)); }); } reroll(times, conditionals) { if (!this.modifiersAllowed) { new import_obsidian2.Notice("Modifiers are only allowed on dice rolls."); return; } if (!conditionals.length) { conditionals.push({ operator: "=", comparer: this.faces.min }); } let i = 0, toReroll = [...this.results].filter(([, { value }]) => this.checkCondition(value, conditionals)); while (i < times && toReroll.filter(([, { value }]) => this.checkCondition(value, conditionals)).length > 0) { i++; toReroll.map(([, roll]) => { roll.modifiers.add("r"); roll.value = this.getRandomBetween(this.faces.min, this.faces.max); }); } toReroll.forEach(([index, value]) => { this.results.set(index, value); }); } explodeAndCombine(times, conditionals) { if (!this.modifiersAllowed) { new import_obsidian2.Notice("Modifiers are only allowed on dice rolls."); return; } if (!conditionals.length) { conditionals.push({ operator: "=", comparer: this.faces.max }); } let i = 0, toExplode = [...this.results].filter(([, { value }]) => this.checkCondition(value, conditionals)); toExplode.forEach(([index, value]) => { let newRoll = this.getRandomBetween(this.faces.min, this.faces.max); i++; value.modifiers.add("!"); value.value += newRoll; value.display = `${value.value}`; this.results.set(index, value); while (i < times && this.checkCondition(newRoll, conditionals)) { i++; newRoll = this.getRandomBetween(this.faces.min, this.faces.max); value.value += newRoll; value.display = `${value.value}`; this.results.set(index, value); } }); } explode(times, conditionals) { if (!this.modifiersAllowed) { new import_obsidian2.Notice("Modifiers are only allowed on dice rolls."); return; } if (!conditionals.length) { conditionals.push({ operator: "=", comparer: this.faces.max }); } let toExplode = [...this.results].filter(([, { value }]) => this.checkCondition(value, conditionals)); let inserted = 0; toExplode.forEach(([key, value]) => { let newRoll = value.value; let i = 0; while (i < times && this.checkCondition(newRoll, conditionals)) { let previous = this.results.get(key + inserted + i); previous.modifiers.add("!"); newRoll = this.getRandomBetween(this.faces.min, this.faces.max); _insertIntoMap(this.results, key + inserted + i + 1, { usable: true, value: newRoll, display: `${newRoll}`, modifiers: /* @__PURE__ */ new Set() }); i++; } inserted += i; }); } _roll() { if (this.static) { return [Number(this.dice)]; } return [...Array(this.rolls)].map(() => this.multiplier * this.getRandomBetween(this.faces.min, this.faces.max)); } setResults(results) { this.results = new Map([...results].map((n, i) => { return [ i, { usable: true, value: n, display: `${n}`, modifiers: /* @__PURE__ */ new Set() } ]; })); } roll() { var _a; const roll = this._roll(); this.results = new Map([...roll].map((n, i) => { return [ i, { usable: true, value: n, display: `${n}`, modifiers: /* @__PURE__ */ new Set() } ]; })); for (let [type, modifier] of this.modifiers) { this.applyModifier(type, modifier); } if ((_a = this.conditions) == null ? void 0 : _a.length) this.applyConditions(); return roll; } applyConditions() { for (let [index, result] of this.results) { const negate = this.conditions.find(({ operator }) => operator === "-=" || operator === "=-"); if (negate) { if (result.value === negate.comparer) { result.value = -1; result.modifiers.add("-"); continue; } } const check = this.checkCondition(result.value, this.conditions); if (!check) { result.usable = false; } else { result.modifiers.add("*"); result.value = 1; } } } applyModifier(type, modifier) { switch (type) { case "kh": { this.keepHigh(modifier.data); break; } case "kl": { this.keepLow(modifier.data); break; } case "!": { this.explode(modifier.data, modifier.conditionals); break; } case "!!": { this.explodeAndCombine(modifier.data, modifier.conditionals); break; } case "r": { this.reroll(modifier.data, modifier.conditionals); break; } case "condition": { } } } checkCondition(value, conditions) { if (!conditions || !conditions.length) return value; return conditions.some(({ operator, comparer }) => { if (Number.isNaN(value) || Number.isNaN(comparer)) { return false; } let result = false; switch (operator) { case "=": result = value === comparer; break; case "!=": case "=!": result = value !== comparer; break; case "<": result = value < comparer; break; case "<=": result = value <= comparer; break; case ">": result = value > comparer; break; case ">=": result = value >= comparer; break; } return result; }); } getRandomBetween(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } }; var StuntRoller = class extends DiceRoller { constructor(dice, lexeme) { super(`3d6`, lexeme); this.lexeme = lexeme; this.dice = dice; } get doubles() { return new Set([...this.results].map(([, { usable, value }]) => usable ? value : 0)).size < 3; } get result() { if (this.static) { return Number(this.dice); } const results = [...this.results].map(([, { usable, value }]) => usable ? value : 0); return results.reduce((a2, b2) => a2 + b2, 0); } get display() { let str = []; for (let result of this.results) { if (result[0] == 0 && this.doubles) { str.push(`${result[1].value}S`); continue; } str.push(`${result[1].value}`); } return `[${str.join(", ")}]`; } }; var StackRoller = class extends GenericRoller { constructor(plugin, original, lexemes, showDice = plugin.data.showDice) { super(plugin, original, lexemes, showDice); this.plugin = plugin; this.original = original; this.lexemes = lexemes; this.stunted = ""; this.shouldRender = false; this.operators = { "+": (a2, b2) => a2 + b2, "-": (a2, b2) => a2 - b2, "*": (a2, b2) => a2 * b2, "/": (a2, b2) => a2 / b2, "^": (a2, b2) => { return Math.pow(a2, b2); } }; this.stack = []; this.stackCopy = []; this.dice = []; this.loaded = true; this.trigger("loaded"); } get resultText() { let text = []; let index = 0; this.dice.forEach((dice) => { const slice = this.original.slice(index); text.push(slice.slice(0, slice.indexOf(dice.lexeme.original)), dice.display); index += slice.indexOf(dice.lexeme.original) + dice.lexeme.original.length; }); return text.join(""); } get tooltip() { if (this._tooltip) return this._tooltip; return `${this.original} ${this.resultText}`; } build() { return __async(this, null, function* () { const result = [ this.result.toLocaleString(navigator.language, { maximumFractionDigits: 2 }) ]; if (this.plugin.data.displayResultsInline) { result.unshift(this.inlineText); } this.resultEl.setText(result.join("") + this.stunted); }); } onClick(evt) { return __async(this, null, function* () { var _a; evt.stopPropagation(); evt.stopImmediatePropagation(); if ((_a = window.getSelection()) == null ? void 0 : _a.isCollapsed) { yield this.roll(); } }); } get dynamic() { return this.dice.filter((d) => !d.static); } get static() { return this.dice.filter((d) => d.static); } get isStatic() { return this.dice.every((d) => d.static); } roll() { return __async(this, null, function* () { let index = 0; this.stunted = ""; if (this.shouldRender) { yield this.plugin.renderRoll(this); } else { for (const dice of this.lexemes) { switch (dice.type) { case "+": case "-": case "*": case "/": case "^": case "math": let b2 = this.stack.pop(), a2 = this.stack.pop(); if (!a2) { if (dice.data === "-") { b2 = new DiceRoller(`-${b2.dice}`, b2.lexeme); } this.stackCopy.push(dice.data); this.stack.push(b2); continue; } b2.roll(); if (b2 instanceof StuntRoller) { if (b2.doubles) { this.stunted = ` - ${b2.results.get(0).value} Stunt Points`; } } a2.roll(); if (a2 instanceof StuntRoller) { if (a2.doubles) { this.stunted = ` - ${a2.results.get(0).value} Stunt Points`; } } const result = this.operators[dice.data](a2.result, b2.result); this.stackCopy.push(dice.data); this.stack.push(new DiceRoller(`${result}`, dice)); break; case "kh": { let diceInstance = this.dice[index - 1]; let data = dice.data ? Number(dice.data) : 1; diceInstance.modifiers.set("kh", { data, conditionals: [] }); break; } case "dl": { let diceInstance = this.dice[index - 1]; let data = dice.data ? Number(dice.data) : 1; data = diceInstance.results.size - data; diceInstance.modifiers.set("kh", { data, conditionals: [] }); break; } case "kl": { let diceInstance = this.dice[index - 1]; let data = dice.data ? Number(dice.data) : 1; diceInstance.modifiers.set("kl", { data, conditionals: [] }); break; } case "dh": { let diceInstance = this.dice[index - 1]; let data = dice.data ? Number(dice.data) : 1; data = diceInstance.results.size - data; diceInstance.modifiers.set("kl", { data, conditionals: [] }); break; } case "!": { let diceInstance = this.dice[index - 1]; let data = Number(dice.data) || 1; diceInstance.modifiers.set("!", { data, conditionals: dice.conditionals }); break; } case "!!": { let diceInstance = this.dice[index - 1]; let data = Number(dice.data) || 1; diceInstance.modifiers.set("!!", { data, conditionals: dice.conditionals }); break; } case "r": { let diceInstance = this.dice[index - 1]; let data = Number(dice.data) || 1; diceInstance.modifiers.set("r", { data, conditionals: dice.conditionals }); break; } case "dice": if (dice.parenedDice && /^d/.test(dice.original) && this.stack.length) { const previous = this.stack.pop(); dice.data = `${previous.result}${dice.original}`; this.dice[index] = new DiceRoller(dice.data, dice); } if (!this.dice[index]) { this.dice[index] = new DiceRoller(dice.data, dice); } this.stack.push(this.dice[index]); this.stackCopy.push(this.dice[index]); index++; break; case "stunt": if (!this.dice[index]) { this.dice[index] = new StuntRoller(dice.original, dice); } this.stack.push(this.dice[index]); this.stackCopy.push(this.dice[index]); index++; } } const final = this.stack.pop(); final.roll(); if (final instanceof StuntRoller) { if (final.doubles) { this.stunted = ` - ${final.results.get(0).value} Stunt Points`; } } this.result = final.result; this._tooltip = null; } this.render(); this.trigger("new-result"); return this.result; }); } recalculate() { let stack = []; let result = 0; for (let item of this.stackCopy) { if (typeof item === "string") { let b2 = stack.pop(), a2 = stack.pop(); if (!a2) { if (item === "-") { b2 = new DiceRoller(`-${b2.result}`, b2.lexeme); } stack.push(b2); continue; } const r = this.operators[item](a2.result, b2.result); stack.push(new DiceRoller(`${r}`)); } else { stack.push(item); } } if (stack.length && stack[0] instanceof DiceRoller) { result += stack[0].result; } this.result = result; } toResult() { return { type: "dice", result: this.result, tooltip: this.tooltip }; } applyResult(result) { return __async(this, null, function* () { if (result.type !== "dice") return; if (result.result) { this.result = result.result; } if (result.tooltip) { this._tooltip = result.tooltip; } yield this.render(); }); } setResult(result) { } }; // src/roller/section.ts var import_obsidian3 = __toModule(require("obsidian")); var SectionRoller = class extends GenericFileRoller { constructor(plugin, original, lexeme, source, inline = true, showDice = plugin.data.showDice) { super(plugin, original, lexeme, source, showDice); this.plugin = plugin; this.original = original; this.lexeme = lexeme; this.inline = inline; this.containerEl.addClasses(["has-embed", "markdown-embed"]); this.resultEl.addClass("internal-embed"); this.resultEl.setAttrs({ src: source }); this.copy = this.containerEl.createDiv({ cls: "dice-content-copy dice-roller-button no-show", attr: { "aria-label": "Copy Contents" } }); this.copy.addEventListener("click", (evt) => { evt.stopPropagation(); navigator.clipboard.writeText(this.displayFromCache(...this.results).trim()).then(() => __async(this, null, function* () { new import_obsidian3.Notice("Result copied to clipboard."); })); }); (0, import_obsidian3.setIcon)(this.copy, COPY_DEFINITION); } get tooltip() { return `${this.original} ${this.path}`; } build() { return __async(this, null, function* () { this.resultEl.empty(); if (this.plugin.data.displayResultsInline && this.inline) { this.resultEl.createSpan({ text: this.inlineText }); } if (!this.results || !this.results.length) { this.resultEl.createDiv({ cls: "dice-no-results", text: "No results." }); return; } if (this.plugin.data.copyContentButton) { this.copy.removeClass("no-show"); } for (const result of this.results) { this.resultEl.onclick = (evt) => __async(this, null, function* () { if (evt && evt.getModifierState("Control") || evt.getModifierState("Meta")) { evt.stopPropagation(); return; } }); const ret = this.resultEl.createDiv({ cls: "markdown-embed" }); if (!this.plugin.data.displayResultsInline) { const type = "type" in result ? result.type : "List Item"; ret.setAttrs({ "aria-label": `${this.file.basename}: ${type}` }); } if (!result) { ret.createDiv({ cls: "dice-no-results", text: "No results." }); continue; } import_obsidian3.MarkdownRenderer.renderMarkdown(this.displayFromCache(result), ret.createDiv(), this.source, null); if (this.plugin.data.copyContentButton && this.results.length > 1) { let copy = ret.createDiv({ cls: "dice-content-copy dice-roller-button", attr: { "aria-label": "Copy Contents" } }); copy.addEventListener("click", (evt) => { evt.stopPropagation(); navigator.clipboard.writeText(this.displayFromCache(result).trim()).then(() => __async(this, null, function* () { new import_obsidian3.Notice("Result copied to clipboard."); })); }); (0, import_obsidian3.setIcon)(copy, COPY_DEFINITION); } } }); } load() { return __async(this, null, function* () { yield this.getOptions(); }); } displayFromCache(...caches) { let res = []; for (let cache of caches) { res.push(this.content.slice(cache.position.start.offset, cache.position.end.offset)); } return res.join("\n\n"); } getPath() { var _a; const { groups } = this.lexeme.data.match(SECTION_REGEX); const { roll = 1, link, types } = groups; if (!link) throw new Error("Could not parse link."); this.rolls = (_a = roll && !isNaN(Number(roll)) && Number(roll)) != null ? _a : 1; this.path = link.replace(/(\[|\])/g, ""); this.types = types == null ? void 0 : types.split(","); this.levels = types == null ? void 0 : types.split(",").map((type) => /heading\-\d+/.test(type) ? type.split("-").pop() : null).filter((t) => t); this.types = types == null ? void 0 : types.split(",").map((type) => /heading\-\d+/.test(type) ? type.split("-").shift() : type); } getOptions() { return __async(this, null, function* () { this.cache = this.plugin.app.metadataCache.getFileCache(this.file); if (!this.cache || !this.cache.sections) { throw new Error("Could not read file cache."); } this.content = yield this.plugin.app.vault.cachedRead(this.file); this.options = this.cache.sections.filter(({ type, position }) => { var _a; if (!this.types) return !["yaml", "thematicBreak"].includes(type); if (type == "heading" && this.types.includes(type) && this.levels.length) { const headings = ((_a = this.cache.headings) != null ? _a : []).filter(({ level }) => this.levels.includes(`${level}`)); return headings.some(({ position: pos }) => samePosition(pos, position)); } return this.types.includes(type); }); if (this.types && this.types.includes("listItem")) { this.options.push(...this.cache.listItems); } this.loaded = true; this.trigger("loaded"); }); } roll() { return __async(this, null, function* () { return new Promise((resolve2, reject2) => { if (!this.loaded) { this.on("loaded", () => { const options = [...this.options]; this.results = [...Array(this.rolls)].map(() => { let option = options[this.getRandomBetween(0, options.length - 1)]; options.splice(options.indexOf(option), 1); return option; }).filter((r) => r); this.render(); this.trigger("new-result"); resolve2(this.results[0]); }); } else { const options = [...this.options]; this.results = [...Array(this.rolls)].map(() => { let option = options[this.getRandomBetween(0, options.length - 1)]; options.splice(options.indexOf(option), 1); return option; }).filter((r) => r); this.render(); this.trigger("new-result"); resolve2(this.results[0]); } }); }); } toResult() { return { type: "section", result: this.results }; } applyResult(result) { return __async(this, null, function* () { if (result.type !== "section") return; if (result.result) { this.results = result.result; } yield this.render(); }); } }; var TagRoller = class extends GenericRoller { constructor(plugin, original, lexeme, source, showDice = plugin.data.showDice) { super(plugin, original, [lexeme], showDice); this.plugin = plugin; this.original = original; this.lexeme = lexeme; this.source = source; this.loaded = false; if (!this.plugin.canUseDataview) { new import_obsidian3.Notice("A tag can only be rolled with the Dataview plugin enabled."); throw new Error("A tag can only be rolled with the Dataview plugin enabled."); } this.containerEl.addClasses(["has-embed", "markdown-embed"]); const { roll = 1, tag, collapse, types } = lexeme.data.match(TAG_REGEX).groups; this.collapse = collapse === "-" ? true : collapse === "+" ? false : !this.plugin.data.returnAllTags; this.tag = `#${tag}`; this.rolls = Number(roll); this.types = types; this.getFiles(); } get typeText() { var _a; if (!((_a = this.types) == null ? void 0 : _a.length)) { return ""; } return `|${this.types}`; } getFiles() { return __async(this, null, function* () { yield this.plugin.dataviewReady(); const files = this.plugin.dataview.index.tags.invMap.get(this.tag); if (files) files.delete(this.source); if (!files || !files.size) { throw new Error("No files found with that tag. Is the tag correct?\n\n" + this.tag); } const links = Array.from(files).map((file) => `${this.rolls}d[[${file}]]${this.typeText}`); this.results = links.map((link) => { return new SectionRoller(this.plugin, link, { data: link, original: link, conditionals: null, type: "section" }, this.source, false); }); this.loaded = true; this.trigger("loaded"); }); } build() { return __async(this, null, function* () { var _a; this.resultEl.empty(); if (this.plugin.data.displayResultsInline) { this.resultEl.createSpan({ text: this.inlineText }); } if (this.collapse) { this.chosen = (_a = this.random) != null ? _a : this.getRandomBetween(0, this.results.length - 1); let section = this.results[this.chosen]; this.random = null; const container = this.resultEl.createDiv(); container.createEl("h5", { cls: "dice-file-name", text: section.file.basename }); container.appendChild(section.containerEl); } else { for (let section of this.results) { const container = this.resultEl.createDiv(); container.createEl("h5", { cls: "dice-file-name", text: section.file.basename }); container.appendChild(section.containerEl); } } }); } roll() { return __async(this, null, function* () { return new Promise((resolve2, reject2) => { if (this.loaded) { this.results.forEach((section) => __async(this, null, function* () { return yield section.roll(); })); this.render(); this.trigger("new-result"); resolve2(this.result); } else { this.on("loaded", () => { this.results.forEach((section) => __async(this, null, function* () { return yield section.roll(); })); this.render(); this.trigger("new-result"); resolve2(this.result); }); } }); }); } get tooltip() { return this.original; } toResult() { return { type: "tag", random: this.chosen, result: Object.fromEntries(this.results.map((section) => [ section.path, section.toResult() ])) }; } applyResult(result) { return __async(this, null, function* () { if (result.type !== "tag") return; if (result.result) { for (let path in result.result) { const section = this.results.find((section2) => section2.path === path); if (!section) continue; section.applyResult(result.result[path]); } } if (result.random) { this.random = result.random; } yield this.render(); }); } }; var LinkRoller = class extends GenericRoller { constructor(plugin, original, lexeme, source, showDice = plugin.data.showDice) { super(plugin, original, [lexeme], showDice); this.plugin = plugin; this.original = original; this.lexeme = lexeme; this.source = source; var _a; const { roll = 1, tag } = lexeme.data.match(TAG_REGEX).groups; this.tag = `#${tag}`; this.rolls = (_a = roll && !isNaN(Number(roll)) && Number(roll)) != null ? _a : 1; this.getFiles(); } get tooltip() { return `${this.original} ${this.result.basename}`; } roll() { return __async(this, null, function* () { return new Promise((resolve2, reject2) => { if (this.loaded) { this.result = this.links[this.getRandomBetween(0, this.links.length - 1)]; this.render(); this.trigger("new-result"); resolve2(this.result); } else { this.on("loaded", () => { this.result = this.links[this.getRandomBetween(0, this.links.length - 1)]; this.render(); this.trigger("new-result"); resolve2(this.result); }); } }); }); } build() { return __async(this, null, function* () { this.resultEl.empty(); if (this.plugin.data.displayResultsInline) { this.resultEl.createSpan({ text: this.inlineText }); } const link = this.resultEl.createEl("a", { cls: "internal-link", text: this.result.basename }); link.onclick = (evt) => __async(this, null, function* () { var _a; evt.stopPropagation(); this.plugin.app.workspace.openLinkText(this.result.path, (_a = this.plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path, true); }); link.onmouseenter = (evt) => __async(this, null, function* () { var _a; this.plugin.app.workspace.trigger("link-hover", this, link, this.result.path, (_a = this.plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path); }); }); } getFiles() { return __async(this, null, function* () { yield this.plugin.dataviewReady(); const files = this.plugin.dataview.index.tags.invMap.get(this.tag); if (files) files.delete(this.source); if (!files || !files.size) { throw new Error("No files found with that tag. Is the tag correct?\n\n" + this.tag); } this.links = Array.from(files).map((link) => this.plugin.app.metadataCache.getFirstLinkpathDest(link, this.source)); this.loaded = true; this.trigger("loaded"); }); } toResult() { return { type: "link", result: this.result.path }; } applyResult(result) { return __async(this, null, function* () { if (result.type !== "link") return; if (result.result) { const file = this.plugin.app.vault.getAbstractFileByPath(result.result); if (file && file instanceof import_obsidian3.TFile) { this.result = file; } } yield this.render(); }); } }; var LineRoller = class extends GenericFileRoller { constructor(plugin, original, lexeme, source, inline = true, showDice = plugin.data.showDice) { super(plugin, original, lexeme, source, showDice); this.plugin = plugin; this.original = original; this.lexeme = lexeme; this.inline = inline; this.containerEl.addClasses(["has-embed", "markdown-embed"]); this.resultEl.addClass("internal-embed"); this.resultEl.setAttrs({ src: source }); this.copy = this.containerEl.createDiv({ cls: "dice-content-copy dice-roller-button no-show", attr: { "aria-label": "Copy Contents" } }); this.copy.addEventListener("click", (evt) => { evt.stopPropagation(); navigator.clipboard.writeText(this.results.join("\n")).then(() => __async(this, null, function* () { new import_obsidian3.Notice("Result copied to clipboard."); })); }); (0, import_obsidian3.setIcon)(this.copy, COPY_DEFINITION); } get tooltip() { return `${this.original} ${this.path}`; } build() { return __async(this, null, function* () { this.resultEl.empty(); if (this.plugin.data.displayResultsInline && this.inline) { this.resultEl.createSpan({ text: this.inlineText }); } if (!this.results || !this.results.length) { this.resultEl.createDiv({ cls: "dice-no-results", text: "No results." }); return; } if (this.plugin.data.copyContentButton) { this.copy.removeClass("no-show"); } for (const result of this.results) { this.resultEl.onclick = (evt) => __async(this, null, function* () { if (evt && evt.getModifierState("Control") || evt.getModifierState("Meta")) { evt.stopPropagation(); return; } }); const ret = this.resultEl.createDiv({ cls: "markdown-embed" }); if (!result) { ret.createDiv({ cls: "dice-no-results", text: "No results." }); continue; } import_obsidian3.MarkdownRenderer.renderMarkdown(result, ret.createDiv(), this.source, null); if (this.plugin.data.copyContentButton && this.results.length > 1) { let copy = ret.createDiv({ cls: "dice-content-copy dice-roller-button", attr: { "aria-label": "Copy Contents" } }); copy.addEventListener("click", (evt) => { evt.stopPropagation(); navigator.clipboard.writeText(result).then(() => __async(this, null, function* () { new import_obsidian3.Notice("Result copied to clipboard."); })); }); (0, import_obsidian3.setIcon)(copy, COPY_DEFINITION); } } }); } load() { return __async(this, null, function* () { yield this.getOptions(); }); } getPath() { var _a; const { groups } = this.lexeme.data.match(SECTION_REGEX); const { roll = 1, link, types } = groups; if (!link) throw new Error("Could not parse link."); this.rolls = (_a = roll && !isNaN(Number(roll)) && Number(roll)) != null ? _a : 1; this.path = link.replace(/(\[|\])/g, ""); this.types = types == null ? void 0 : types.split(","); } getOptions() { return __async(this, null, function* () { this.content = yield this.plugin.app.vault.cachedRead(this.file); if (!this.content) { throw new Error("Could not read file cache."); } this.options = this.content.trim().split("\n").map((c2) => c2.trim()).filter((c2) => c2 && c2.length); this.loaded = true; this.trigger("loaded"); }); } roll() { return __async(this, null, function* () { return new Promise((resolve2, reject2) => { if (!this.loaded) { this.on("loaded", () => { const options = [...this.options]; this.results = [...Array(this.rolls)].map(() => { let option = options[this.getRandomBetween(0, options.length - 1)]; options.splice(options.indexOf(option), 1); return option; }).filter((r) => r); this.render(); this.trigger("new-result"); resolve2(this.results[0]); }); } else { const options = [...this.options]; this.results = [...Array(this.rolls)].map(() => { let option = options[this.getRandomBetween(0, options.length - 1)]; options.splice(options.indexOf(option), 1); return option; }).filter((r) => r); this.render(); this.trigger("new-result"); resolve2(this.results[0]); } }); }); } toResult() { return { type: "section", result: this.results }; } applyResult(result) { return __async(this, null, function* () { if (result.type !== "section") return; if (result.result) { this.results = result.result; } yield this.render(); }); } }; var samePosition = (pos, pos2) => { return pos.start.col == pos2.start.col && pos.start.line == pos2.start.line && pos.start.offset == pos2.start.offset; }; // src/roller/table.ts var import_obsidian4 = __toModule(require("obsidian")); var TableRoller = class extends GenericFileRoller { getPath() { var _a; const { groups } = this.lexeme.data.match(TABLE_REGEX); const { roll = 1, link, block, header } = groups; if (!link || !block) throw new Error("Could not parse link."); this.rolls = (_a = roll && !isNaN(Number(roll)) && Number(roll)) != null ? _a : 1; this.path = link.replace(/(\[|\])/g, ""); this.block = block.replace(/(\^|#)/g, "").trim().toLowerCase(); this.header = header; } get tooltip() { return `${this.original} ${this.path} > ${this.block}${this.header ? " | " + this.header : ""}`; } build() { return __async(this, null, function* () { this.resultEl.empty(); const result = [this.result]; if (this.plugin.data.displayResultsInline) { result.unshift(this.inlineText); } yield import_obsidian4.MarkdownRenderer.renderMarkdown(result.join(""), this.resultEl.createSpan("embedded-table-result"), this.source, null); }); } getResult() { return __async(this, null, function* () { if (this.isLookup) { const result = yield this.lookupRoller.roll(); const option = this.lookupRanges.find(([range]) => range[1] === void 0 && result === range[0] || result >= range[0] && range[1] >= result); if (option) { return option[1]; } } const options = [...this.options]; return [...Array(this.rolls)].map(() => { let option = options[this.getRandomBetween(0, options.length - 1)]; options.splice(options.indexOf(option), 1); return option; }).join("||"); }); } roll() { return __async(this, null, function* () { return new Promise((resolve2) => __async(this, null, function* () { if (this.loaded) { this.result = yield this.getResult(); this.render(); this.trigger("new-result"); resolve2(this.result); } else { this.on("loaded", () => __async(this, null, function* () { this.result = yield this.getResult(); this.render(); this.trigger("new-result"); resolve2(this.result); })); } })); }); } load() { return __async(this, null, function* () { yield this.getOptions(); }); } getOptions() { return __async(this, null, function* () { var _a, _b; this.cache = this.plugin.app.metadataCache.getFileCache(this.file); if (!this.cache || !this.cache.blocks || !(this.block in this.cache.blocks)) { throw new Error(`Could not read file cache. Does the block reference exist? ${this.path} > ${this.block}`); } const section = (_a = this.cache.sections) == null ? void 0 : _a.find((s) => s.position == this.cache.blocks[this.block].position); this.position = this.cache.blocks[this.block].position; this.content = (_b = yield this.plugin.app.vault.cachedRead(this.file)) == null ? void 0 : _b.slice(this.position.start.offset, this.position.end.offset); if (section && section.type === "list") { this.options = this.content.split("\n"); } else { let table = extract(this.content); if (Object.keys(table.columns).length === 2 && /dice:\s*([\s\S]+)\s*?/.test(Object.keys(table.columns)[0])) { const roller = this.plugin.getRoller(Object.keys(table.columns)[0].split(":").pop(), this.source); if (roller instanceof StackRoller) { this.lookupRoller = roller; yield this.lookupRoller.roll(); this.lookupRanges = table.rows.map((row) => { var _a2; const [range, option] = row.split("|").map((str) => str.replace("{ESCAPED_PIPE}", "|")).map((s) => s.trim()); let [, min, max] = (_a2 = range.match(/(\d+)(?:[^\d]+?(\d+))?/)) != null ? _a2 : []; if (!min && !max) return; return [ [Number(min), max ? Number(max) : void 0], option ]; }); this.isLookup = true; } } if (this.header && table.columns[this.header]) { this.options = table.columns[this.header]; } else { if (this.header) { throw new Error(`Header ${this.header} was not found in table ${this.path} > ${this.block}.`); } this.options = table.rows; } } this.loaded = true; this.trigger("loaded"); }); } toResult() { return { type: "table", result: this.result }; } applyResult(result) { return __async(this, null, function* () { if (result.type !== "table") return; if (result.result) { this.result = result.result; } yield this.render(); }); } }; var MATCH = /^\|?([\s\S]+?)\|?$/; var SPLIT = /\|/; function extract(content) { const lines = content.split("\n"); const inner = lines.map((l) => { var _a; return ((_a = l.trim().match(MATCH)) != null ? _a : [, l.trim()])[1]; }); const headers = inner[0].replace("\\|", "{ESCAPED_PIPE}").split(SPLIT); const rows = []; const ret = []; for (let index in headers) { let header = headers[index]; if (!header.trim().length) header = index; ret.push([header.trim(), []]); } for (let line of lines.slice(2)) { const entries = line.trim().replace("\\|", "{ESCAPED_PIPE}").split(SPLIT).map((e) => e.trim()).filter((e) => e.length); rows.push(entries.join(" | ")); for (let index in entries) { const entry = entries[index].trim(); if (!entry.length || !ret[index]) continue; ret[index][1].push(entry); } } return { columns: Object.fromEntries(ret), rows }; } // src/settings/settings.ts var import_obsidian5 = __toModule(require("obsidian")); var SettingTab = class extends import_obsidian5.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.plugin = plugin; this.plugin = plugin; } display() { return __async(this, null, function* () { let { containerEl } = this; containerEl.empty(); containerEl.addClass("dice-roller-settings"); containerEl.createEl("h2", { text: "Dice Roller Settings" }); new import_obsidian5.Setting(containerEl).setName("Roll All Files for Tags").setDesc("Return a result for each file when rolling tags.").addToggle((t) => { t.setValue(this.plugin.data.returnAllTags); t.onChange((v) => __async(this, null, function* () { this.plugin.data.returnAllTags = v; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Always Return Links for Tags").setDesc("Enables random link rolling with the link parameter. Override by specifying a section type.").addToggle((t) => { t.setValue(this.plugin.data.rollLinksForTags); t.onChange((v) => __async(this, null, function* () { this.plugin.data.rollLinksForTags = v; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Add Copy Button to Section Results").setDesc("Randomly rolled sections will have a copy-content button to easy add result to clipboard.").addToggle((t) => { t.setValue(this.plugin.data.copyContentButton); t.onChange((v) => __async(this, null, function* () { this.plugin.data.copyContentButton = v; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Display Formula With Results").setDesc("Both the formula and the results will both be displayed in preview mode.").addToggle((t) => { t.setValue(this.plugin.data.displayResultsInline); t.onChange((v) => __async(this, null, function* () { this.plugin.data.displayResultsInline = v; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Add Formula When Modifying").setDesc(createFragment((e) => { e.createSpan({ text: "Both the formula and the results will both be added to the node when using " }); e.createEl("code", { text: "dice-mod" }); e.createSpan({ text: "." }); })).addToggle((t) => { t.setValue(this.plugin.data.displayFormulaForMod); t.onChange((v) => __async(this, null, function* () { this.plugin.data.displayFormulaForMod = v; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Display Lookup Table Roll").setDesc("Lookup table rolls will display the rolled number along with the result.").addToggle((t) => { t.setValue(this.plugin.data.displayLookupRoll); t.onChange((v) => __async(this, null, function* () { this.plugin.data.displayLookupRoll = v; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Show Dice Button").setDesc("A dice button will appear next to results.").addToggle((t) => { t.setValue(this.plugin.data.showDice); t.onChange((v) => __async(this, null, function* () { this.plugin.data.showDice = v; yield this.plugin.saveSettings(); })); }); const save = new import_obsidian5.Setting(containerEl).setName("Globally Save Results").setDesc("Dice results will be saved by default. This can be overridden using ").addToggle((t) => { t.setValue(this.plugin.data.persistResults); t.onChange((v) => __async(this, null, function* () { this.plugin.data.persistResults = v; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Open Dice View on Startup").setDesc("The dice view can always be opened using the command from the command palette.").addToggle((t) => { t.setValue(this.plugin.data.showLeafOnStartup); t.onChange((v) => __async(this, null, function* () { this.plugin.data.showLeafOnStartup = v; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Display graphics for Dice View Rolls").setDesc("Dice rolls from dice view will be displayed on screen.").addToggle((t) => { t.setValue(this.plugin.data.renderer); t.onChange((v) => __async(this, null, function* () { this.plugin.data.renderer = v; yield this.plugin.saveSettings(); })); }); const diceColor = new import_obsidian5.Setting(containerEl).setName("Dice Base Color").setDesc("Rendered dice will be this color."); diceColor.controlEl.createEl("input", { type: "color", value: this.plugin.data.diceColor }, (el) => { el.value = this.plugin.data.diceColor; el.onchange = (_0) => __async(this, [_0], function* ({ target }) { let color = target.value; this.plugin.data.diceColor = color; yield this.plugin.saveSettings(); this.plugin.app.workspace.trigger("dice-roller:update-colors"); }); }); const textColor = new import_obsidian5.Setting(containerEl).setName("Dice Text Color").setDesc("Rendered dice will use this color for their numbers."); textColor.controlEl.createEl("input", { type: "color", value: this.plugin.data.textColor }, (el) => { el.value = this.plugin.data.textColor; el.onchange = (_0) => __async(this, [_0], function* ({ target }) { let color = target.value; if (!color) return; this.plugin.data.textColor = color; yield this.plugin.saveSettings(); this.plugin.app.workspace.trigger("dice-roller:update-colors"); }); }); new import_obsidian5.Setting(containerEl).setName("Default Face").setDesc("Use this as the number of faces when it is omitted.").addText((t) => { t.setValue(`${this.plugin.data.defaultFace}`); t.inputEl.onblur = () => __async(this, null, function* () { if (isNaN(Number(t.inputEl.value))) { new import_obsidian5.Notice("The default face must be a number."); } this.plugin.data.defaultFace = Number(t.inputEl.value); yield this.plugin.saveSettings(); }); }); save.descEl.createEl("code", { text: `dice-: formula` }); save.descEl.createEl("p", { text: "Please note that the plugin will attempt to save the result but may not be able to." }); this.additionalContainer = containerEl.createDiv("dice-roller-setting-additional-container"); this.buildFormulaSettings(); const div = containerEl.createDiv("coffee"); div.createEl("a", { href: "https://www.buymeacoffee.com/valentine195" }).createEl("img", { attr: { src: "https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=\u2615&slug=valentine195&button_colour=e3e7ef&font_colour=262626&font_family=Inter&outline_colour=262626&coffee_colour=ff0000" } }); }); } buildFormulaSettings() { this.additionalContainer.empty(); const addNew = this.additionalContainer.createDiv(); new import_obsidian5.Setting(addNew).setName("Add Formula").setDesc("Add a new formula shortcut.").addButton((button) => { let b2 = button.setTooltip("Add Formula").setButtonText("+").onClick(() => __async(this, null, function* () { const formula = yield this.buildFormulaForm(addNew); if (formula) { this.plugin.data.formulas[formula.alias] = formula.formula; this.buildFormulaSettings(); yield this.plugin.saveSettings(); } })); return b2; }); const additional = this.additionalContainer.createDiv("additional"); const formulas = this.plugin.data.formulas; for (const [alias, formula] of Object.entries(formulas)) { const setting = new import_obsidian5.Setting(additional).setName(alias); setting.controlEl.createSpan({ text: formula }); setting.addExtraButton((b2) => b2.setIcon("pencil").setTooltip("Edit").onClick(() => __async(this, null, function* () { const edited = yield this.buildFormulaForm(addNew, { alias, formula }); if (edited) { delete this.plugin.data.formulas[alias]; this.plugin.data.formulas[edited.alias] = edited.formula; this.buildFormulaSettings(); yield this.plugin.saveSettings(); } }))).addExtraButton((b2) => b2.setIcon("trash").setTooltip("Delete").onClick(() => __async(this, null, function* () { delete this.plugin.data.formulas[alias]; yield this.plugin.saveSettings(); this.buildFormulaSettings(); }))); } if (!Object.values(formulas).length) { additional.createSpan({ text: "Create a formula to see it here!", cls: "no-formulas" }); } } buildFormulaForm(_0) { return __async(this, arguments, function* (el, temp = { alias: null, formula: null }) { return new Promise((resolve2) => { const formulaEl = el.createDiv("add-new-formula"); const dataEl = formulaEl.createDiv("formula-data"); new import_obsidian5.Setting(dataEl).setName("Alias").addText((t) => { t.setValue(temp.alias).onChange((v) => temp.alias = v); }); new import_obsidian5.Setting(dataEl).setName("Formula").addText((t) => { t.setValue(temp.formula).onChange((v) => temp.formula = v); }); const buttonEl = formulaEl.createDiv("formula-buttons"); new import_obsidian5.Setting(buttonEl).addButton((b2) => b2.setCta().setButtonText("Save").onClick(() => __async(this, null, function* () { formulaEl.detach(); resolve2(temp); }))).addExtraButton((b2) => b2.setIcon("cross").setTooltip("Cancel").onClick(() => { formulaEl.detach(); resolve2(null); })); }); }); } }; // src/view/view.ts var import_obsidian6 = __toModule(require("obsidian")); var VIEW_TYPE = "DICE_ROLLER_VIEW"; var D4 = ``; var D6 = ``; var D8 = ``; var D10 = ``; var D12 = ``; var D20 = ``; var D100 = ``; (0, import_obsidian6.addIcon)("d4", D4); (0, import_obsidian6.addIcon)("d6", D6); (0, import_obsidian6.addIcon)("d8", D8); (0, import_obsidian6.addIcon)("d10", D10); (0, import_obsidian6.addIcon)("d12", D12); (0, import_obsidian6.addIcon)("d20", D20); (0, import_obsidian6.addIcon)("d100", D100); (0, import_obsidian6.addIcon)("dice-roller-save", ``); (0, import_obsidian6.addIcon)("dice-roller-plus", ``); (0, import_obsidian6.addIcon)("dice-roller-minus", ``); var DiceView = class extends import_obsidian6.ItemView { constructor(plugin, leaf) { super(leaf); this.plugin = plugin; this.leaf = leaf; this.dice = DiceView.DICE(); this.custom = ""; this.adv = false; this.dis = false; this.add = 0; this.contentEl.addClass("dice-roller-view"); this.registerEvent(this.plugin.app.workspace.on("dice-roller:update-colors", () => { this.renderer.factory.updateColors(); })); } static DICE() { return { d4: 0, d6: 0, d8: 0, d10: 0, d12: 0, d20: 0, d100: 0 }; } get customFormulas() { return this.plugin.data.customFormulas; } get renderer() { return this.plugin.renderer; } onOpen() { return __async(this, null, function* () { this.display(); }); } display() { return __async(this, null, function* () { this.contentEl.empty(); this.gridEl = this.contentEl.createDiv("dice-roller-grid"); this.formulaEl = this.contentEl.createDiv("dice-roller-formula"); const resultsEl = this.contentEl.createDiv("dice-roller-results-container"); const headerEl = resultsEl.createDiv("dice-roller-results-header"); headerEl.createEl("h4", { text: "Results" }); new import_obsidian6.ExtraButtonComponent(headerEl.createDiv("clear-all")).setIcon("trash").setTooltip("Clear All").onClick(() => { this.resultEl.empty(); this.resultEl.append(this.noResultsEl); }); this.resultEl = resultsEl.createDiv("dice-roller-results"); this.noResultsEl = this.resultEl.createSpan({ text: "No results yet! Roll some dice to get started :)" }); this.buildButtons(); this.buildFormula(); }); } buildButtons() { this.gridEl.empty(); const buttons = this.gridEl.createDiv("dice-buttons"); for (let type in this.dice) { const button = new import_obsidian6.ExtraButtonComponent(buttons.createDiv("dice-button")).setIcon(type); button.extraSettingsEl.onclick = (evt) => __async(this, null, function* () { let add2 = evt.getModifierState("Shift") ? -1 : 1; this.dice[type] += add2; this.setFormula(); const roller = yield this.plugin.getRoller(this.formulaComponent.inputEl.value, "view"); if (roller instanceof StackRoller) { this.stack = roller; } }); } const advDis = this.gridEl.createDiv("advantage-disadvantage"); const adv = new import_obsidian6.ButtonComponent(advDis).setButtonText("ADV").onClick(() => { this.adv = !this.adv; this.dis = false; if (this.adv) { adv.setCta(); dis.removeCta(); } else { adv.removeCta(); } this.setFormula(); }); const dis = new import_obsidian6.ButtonComponent(advDis).setButtonText("DIS").onClick(() => { this.dis = !this.dis; if (this.dis) { dis.setCta(); adv.removeCta(); } else { dis.removeCta(); } this.adv = false; this.setFormula(); }); const add = this.gridEl.createDiv("dice-context").createDiv("add-subtract"); new import_obsidian6.ExtraButtonComponent(add).setIcon("dice-roller-minus").onClick(() => { this.add -= 1; addComponent.setValue(`${this.add}`); this.setFormula(); }); const addComponent = new import_obsidian6.TextComponent(add).setValue(`${this.add ? this.add : ""}`).onChange((v) => { if (!isNaN(Number(v))) this.add = Number(v); this.setFormula(); }); new import_obsidian6.ExtraButtonComponent(add).setIcon("dice-roller-plus").onClick(() => { this.add += 1; addComponent.setValue(`${this.add}`); this.setFormula(); }); if (this.customFormulas.length) { const customs = this.gridEl.createDiv("dice-roller-results-container"); const headerEl = customs.createDiv("dice-roller-results-header"); headerEl.createEl("h4", { text: "Saved Formulas" }); for (let formula of this.customFormulas) { const containerEl = customs.createDiv("dice-custom-formula-container"); const formulaEl = containerEl.createDiv("dice-custom-formula"); new import_obsidian6.ExtraButtonComponent(formulaEl).setIcon(ICON_DEFINITION).setTooltip("Roll").onClick(() => this.roll(formula)); formulaEl.createSpan({ text: formula }); new import_obsidian6.ExtraButtonComponent(containerEl).setIcon("trash").setTooltip("Remove").onClick(() => { this.plugin.data.customFormulas = this.plugin.data.customFormulas.filter((f) => f != formula); this.plugin.saveSettings(); this.buildButtons(); }); } } } roll() { return __async(this, arguments, function* (formula = this.formulaComponent.inputEl.value) { if (!formula) { return; } this.rollButton.setDisabled(true); const roller = yield this.plugin.getRoller(formula, "view"); if (!(roller instanceof StackRoller)) { new import_obsidian6.Notice("The Dice View only supports dice rolls."); return; } yield roller.roll(); if (!roller.dice.length) { new import_obsidian6.Notice("Invalid formula."); return; } try { if (this.plugin.data.renderer) { this.addChild(this.renderer); this.renderer.setDice(roller); yield this.renderer.start(); roller.recalculate(); } } catch (e) { new import_obsidian6.Notice("There was an error rendering the roll."); console.error(e); } this.rollButton.setDisabled(false); this.addResult({ result: roller.result, original: roller.original, resultText: roller.resultText }); this.dice = DiceView.DICE(); this.add = null; this.adv = false; this.dis = false; this.buildButtons(); this.setFormula(); }); } buildFormula() { this.formulaEl.empty(); this.formulaComponent = new import_obsidian6.TextAreaComponent(this.formulaEl).setPlaceholder("Dice Formula"); this.formulaComponent.onChange((0, import_obsidian6.debounce)((v) => __async(this, null, function* () { }), 500, true)); const buttons = this.formulaEl.createDiv("action-buttons"); this.saveButton = new import_obsidian6.ButtonComponent(buttons).setIcon("plus-with-circle").setCta().setTooltip("Save Formula").onClick(() => this.save()); this.saveButton.buttonEl.addClass("dice-roller-roll"); this.rollButton = new import_obsidian6.ButtonComponent(buttons).setIcon(ICON_DEFINITION).setCta().setTooltip("Roll").onClick(() => this.roll()); this.rollButton.buttonEl.addClass("dice-roller-roll"); } save() { if (!this.formulaComponent.inputEl.value) return; this.plugin.data.customFormulas.push(this.formulaComponent.inputEl.value); this.buildButtons(); this.plugin.saveSettings(); } addResult(roller) { if (this.noResultsEl) { this.noResultsEl.detach(); } const result = createDiv("view-result"); result.createSpan({ text: roller.original }); result.createEl("strong", { text: `${roller.result}`, attr: { "aria-label": roller.resultText } }); const context = result.createDiv("result-context"); context.createEl("em", { text: new Date().toLocaleString() }); new import_obsidian6.ExtraButtonComponent(context).setIcon("trash").onClick(() => { result.detach(); if (this.resultEl.children.length === 0) { this.resultEl.prepend(this.noResultsEl); } }); const copy = new import_obsidian6.ExtraButtonComponent(context).setIcon(COPY_DEFINITION).setTooltip("Copy Result").onClick(() => __async(this, null, function* () { yield navigator.clipboard.writeText(`${roller.result}`); })); copy.extraSettingsEl.addClass("dice-content-copy"); const reroll = new import_obsidian6.ExtraButtonComponent(context).setIcon(ICON_DEFINITION).setTooltip("Roll Again").onClick(() => this.roll(roller.original)); reroll.extraSettingsEl.addClass("dice-result-reroll"); this.resultEl.prepend(result); } get formulaString() { const result = []; const dice = Object.entries(this.dice).filter(([type, num]) => num != 0); if (!dice.length) return ""; dice.sort((a2, b2) => Number(b2[0].slice(1)) - Number(a2[0].slice(1))); const first = dice.shift(); result.push(`${first[1]}${first[0]}`); if (this.adv) { result.push("kh"); } else if (this.dis) { result.push("dh"); } if (dice.length) { result.push(...dice.map(([type, num]) => `${num > 0 ? "+" : "-"}${Math.abs(num)}${type}`)); } if (this.add && this.add != 0) { result.push(this.add > 0 ? "+" : "-"); result.push(Math.abs(this.add)); } return result.join(""); } setFormula() { this.formulaComponent.setValue(this.formulaString); } getDisplayText() { return "Dice Roller"; } getViewType() { return VIEW_TYPE; } getIcon() { return ICON_DEFINITION; } onClose() { var __superGet = (key) => super[key]; return __async(this, null, function* () { yield __superGet("onClose").call(this); this.renderer.unload(); }); } }; // src/view/renderer.ts var import_obsidian7 = __toModule(require("obsidian")); // node_modules/three/build/three.module.js var REVISION = "132"; var CullFaceNone = 0; var CullFaceBack = 1; var CullFaceFront = 2; var PCFShadowMap = 1; var PCFSoftShadowMap = 2; var VSMShadowMap = 3; var FrontSide = 0; var BackSide = 1; var DoubleSide = 2; var FlatShading = 1; 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 CineonToneMapping = 3; var ACESFilmicToneMapping = 4; var CustomToneMapping = 5; var UVMapping = 300; var CubeReflectionMapping = 301; var CubeRefractionMapping = 302; var EquirectangularReflectionMapping = 303; var EquirectangularRefractionMapping = 304; var CubeUVReflectionMapping = 306; var CubeUVRefractionMapping = 307; var RepeatWrapping = 1e3; var ClampToEdgeWrapping = 1001; var MirroredRepeatWrapping = 1002; var NearestFilter = 1003; var NearestMipmapNearestFilter = 1004; var NearestMipmapLinearFilter = 1005; var LinearFilter = 1006; var LinearMipmapNearestFilter = 1007; 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 NormalAnimationBlendMode = 2500; var AdditiveAnimationBlendMode = 2501; var TrianglesDrawMode = 0; var LinearEncoding = 3e3; 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 KeepStencilOp = 7680; var AlwaysStencilFunc = 519; var StaticDrawUsage = 35044; var DynamicDrawUsage = 35048; var GLSL3 = "300 es"; var EventDispatcher = class { addEventListener(type, listener3) { if (this._listeners === void 0) this._listeners = {}; const listeners = this._listeners; if (listeners[type] === void 0) { listeners[type] = []; } if (listeners[type].indexOf(listener3) === -1) { listeners[type].push(listener3); } } hasEventListener(type, listener3) { if (this._listeners === void 0) return false; const listeners = this._listeners; return listeners[type] !== void 0 && listeners[type].indexOf(listener3) !== -1; } removeEventListener(type, listener3) { if (this._listeners === void 0) return; const listeners = this._listeners; const listenerArray = listeners[type]; if (listenerArray !== void 0) { const index = listenerArray.indexOf(listener3); if (index !== -1) { listenerArray.splice(index, 1); } } } dispatchEvent(event) { if (this._listeners === void 0) return; const listeners = this._listeners; const listenerArray = listeners[event.type]; if (listenerArray !== void 0) { event.target = this; const array = listenerArray.slice(0); for (let i = 0, l = array.length; i < l; i++) { array[i].call(this, event); } event.target = null; } } }; var _lut = []; for (let i = 0; i < 256; i++) { _lut[i] = (i < 16 ? "0" : "") + i.toString(16); } var DEG2RAD = Math.PI / 180; var RAD2DEG = 180 / Math.PI; function generateUUID() { const d0 = Math.random() * 4294967295 | 0; const d1 = Math.random() * 4294967295 | 0; const d2 = Math.random() * 4294967295 | 0; const d3 = Math.random() * 4294967295 | 0; const uuid = _lut[d0 & 255] + _lut[d0 >> 8 & 255] + _lut[d0 >> 16 & 255] + _lut[d0 >> 24 & 255] + "-" + _lut[d1 & 255] + _lut[d1 >> 8 & 255] + "-" + _lut[d1 >> 16 & 15 | 64] + _lut[d1 >> 24 & 255] + "-" + _lut[d2 & 63 | 128] + _lut[d2 >> 8 & 255] + "-" + _lut[d2 >> 16 & 255] + _lut[d2 >> 24 & 255] + _lut[d3 & 255] + _lut[d3 >> 8 & 255] + _lut[d3 >> 16 & 255] + _lut[d3 >> 24 & 255]; return uuid.toUpperCase(); } function clamp(value, min, max) { return Math.max(min, Math.min(max, value)); } function euclideanModulo(n, m) { return (n % m + m) % m; } function lerp(x, y, t) { return (1 - t) * x + t * y; } function isPowerOfTwo(value) { return (value & value - 1) === 0 && value !== 0; } function floorPowerOfTwo(value) { return Math.pow(2, Math.floor(Math.log(value) / Math.LN2)); } var Vector2 = class { constructor(x = 0, y = 0) { this.x = x; this.y = y; } get width() { return this.x; } set width(value) { this.x = value; } get height() { return this.y; } set height(value) { this.y = value; } set(x, y) { this.x = x; this.y = y; return this; } setScalar(scalar) { this.x = scalar; this.y = scalar; return this; } setX(x) { this.x = x; return this; } setY(y) { this.y = y; return this; } setComponent(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(index) { switch (index) { case 0: return this.x; case 1: return this.y; default: throw new Error("index is out of range: " + index); } } clone() { return new this.constructor(this.x, this.y); } copy(v) { this.x = v.x; this.y = v.y; return this; } add(v, w2) { if (w2 !== void 0) { console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."); return this.addVectors(v, w2); } this.x += v.x; this.y += v.y; return this; } addScalar(s) { this.x += s; this.y += s; return this; } addVectors(a2, b2) { this.x = a2.x + b2.x; this.y = a2.y + b2.y; return this; } addScaledVector(v, s) { this.x += v.x * s; this.y += v.y * s; return this; } sub(v, w2) { if (w2 !== void 0) { console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."); return this.subVectors(v, w2); } this.x -= v.x; this.y -= v.y; return this; } subScalar(s) { this.x -= s; this.y -= s; return this; } subVectors(a2, b2) { this.x = a2.x - b2.x; this.y = a2.y - b2.y; return this; } multiply(v) { this.x *= v.x; this.y *= v.y; return this; } multiplyScalar(scalar) { this.x *= scalar; this.y *= scalar; return this; } divide(v) { this.x /= v.x; this.y /= v.y; return this; } divideScalar(scalar) { return this.multiplyScalar(1 / scalar); } applyMatrix3(m) { const x = this.x, y = this.y; const 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(v) { this.x = Math.min(this.x, v.x); this.y = Math.min(this.y, v.y); return this; } max(v) { this.x = Math.max(this.x, v.x); this.y = Math.max(this.y, v.y); return this; } clamp(min, max) { 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(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(min, max) { const length = this.length(); return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); } floor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); return this; } ceil() { this.x = Math.ceil(this.x); this.y = Math.ceil(this.y); return this; } round() { this.x = Math.round(this.x); this.y = Math.round(this.y); return this; } roundToZero() { 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() { this.x = -this.x; this.y = -this.y; return this; } dot(v) { return this.x * v.x + this.y * v.y; } cross(v) { return this.x * v.y - this.y * v.x; } lengthSq() { return this.x * this.x + this.y * this.y; } length() { return Math.sqrt(this.x * this.x + this.y * this.y); } manhattanLength() { return Math.abs(this.x) + Math.abs(this.y); } normalize() { return this.divideScalar(this.length() || 1); } angle() { const angle = Math.atan2(-this.y, -this.x) + Math.PI; return angle; } distanceTo(v) { return Math.sqrt(this.distanceToSquared(v)); } distanceToSquared(v) { const dx = this.x - v.x, dy = this.y - v.y; return dx * dx + dy * dy; } manhattanDistanceTo(v) { return Math.abs(this.x - v.x) + Math.abs(this.y - v.y); } setLength(length) { return this.normalize().multiplyScalar(length); } lerp(v, alpha) { this.x += (v.x - this.x) * alpha; this.y += (v.y - this.y) * alpha; return this; } lerpVectors(v12, v22, alpha) { this.x = v12.x + (v22.x - v12.x) * alpha; this.y = v12.y + (v22.y - v12.y) * alpha; return this; } equals(v) { return v.x === this.x && v.y === this.y; } fromArray(array, offset = 0) { this.x = array[offset]; this.y = array[offset + 1]; return this; } toArray(array = [], offset = 0) { array[offset] = this.x; array[offset + 1] = this.y; return array; } fromBufferAttribute(attribute, index, offset) { if (offset !== void 0) { console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute()."); } this.x = attribute.getX(index); this.y = attribute.getY(index); return this; } rotateAround(center, angle) { const c2 = Math.cos(angle), s = Math.sin(angle); const x = this.x - center.x; const y = this.y - center.y; this.x = x * c2 - y * s + center.x; this.y = x * s + y * c2 + center.y; return this; } random() { this.x = Math.random(); this.y = Math.random(); return this; } }; Vector2.prototype.isVector2 = true; var Matrix3 = class { constructor() { 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."); } } set(n11, n12, n13, n21, n22, n23, n31, n32, n33) { const 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() { this.set(1, 0, 0, 0, 1, 0, 0, 0, 1); return this; } copy(m) { const te = this.elements; const 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(xAxis, yAxis, zAxis) { xAxis.setFromMatrix3Column(this, 0); yAxis.setFromMatrix3Column(this, 1); zAxis.setFromMatrix3Column(this, 2); return this; } setFromMatrix4(m) { const 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(m) { return this.multiplyMatrices(this, m); } premultiply(m) { return this.multiplyMatrices(m, this); } multiplyMatrices(a2, b2) { const ae = a2.elements; const be = b2.elements; const te = this.elements; const a11 = ae[0], a12 = ae[3], a13 = ae[6]; const a21 = ae[1], a22 = ae[4], a23 = ae[7]; const a31 = ae[2], a32 = ae[5], a33 = ae[8]; const b11 = be[0], b12 = be[3], b13 = be[6]; const b21 = be[1], b22 = be[4], b23 = be[7]; const 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(s) { const 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() { const te = this.elements; const a2 = te[0], b2 = te[1], c2 = te[2], d = te[3], e = te[4], f = te[5], g = te[6], h = te[7], i = te[8]; return a2 * e * i - a2 * f * h - b2 * d * i + b2 * f * g + c2 * d * h - c2 * e * g; } invert() { const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n12 = te[3], n22 = te[4], n32 = te[5], n13 = te[6], n23 = te[7], n33 = te[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); const 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() { let tmp3; const m = this.elements; tmp3 = m[1]; m[1] = m[3]; m[3] = tmp3; tmp3 = m[2]; m[2] = m[6]; m[6] = tmp3; tmp3 = m[5]; m[5] = m[7]; m[7] = tmp3; return this; } getNormalMatrix(matrix4) { return this.setFromMatrix4(matrix4).invert().transpose(); } transposeIntoArray(r) { const 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(tx, ty, sx, sy, rotation, cx, cy) { const c2 = Math.cos(rotation); const s = Math.sin(rotation); this.set(sx * c2, sx * s, -sx * (c2 * cx + s * cy) + cx + tx, -sy * s, sy * c2, -sy * (-s * cx + c2 * cy) + cy + ty, 0, 0, 1); return this; } scale(sx, sy) { const te = this.elements; te[0] *= sx; te[3] *= sx; te[6] *= sx; te[1] *= sy; te[4] *= sy; te[7] *= sy; return this; } rotate(theta) { const c2 = Math.cos(theta); const s = Math.sin(theta); const te = this.elements; const a11 = te[0], a12 = te[3], a13 = te[6]; const a21 = te[1], a22 = te[4], a23 = te[7]; te[0] = c2 * a11 + s * a21; te[3] = c2 * a12 + s * a22; te[6] = c2 * a13 + s * a23; te[1] = -s * a11 + c2 * a21; te[4] = -s * a12 + c2 * a22; te[7] = -s * a13 + c2 * a23; return this; } translate(tx, ty) { const 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(matrix) { const te = this.elements; const me = matrix.elements; for (let i = 0; i < 9; i++) { if (te[i] !== me[i]) return false; } return true; } fromArray(array, offset = 0) { for (let i = 0; i < 9; i++) { this.elements[i] = array[i + offset]; } return this; } toArray(array = [], offset = 0) { const 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; } clone() { return new this.constructor().fromArray(this.elements); } }; Matrix3.prototype.isMatrix3 = true; var _canvas; var ImageUtils = class { static getDataURL(image) { if (/^data:/i.test(image.src)) { return image.src; } if (typeof HTMLCanvasElement == "undefined") { return image.src; } let canvas; if (image instanceof HTMLCanvasElement) { canvas = image; } else { if (_canvas === void 0) _canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); _canvas.width = image.width; _canvas.height = image.height; const 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) { console.warn("THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons", image); return canvas.toDataURL("image/jpeg", 0.6); } else { return canvas.toDataURL("image/png"); } } }; var textureId = 0; var Texture = class extends EventDispatcher { constructor(image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = 1, encoding = LinearEncoding) { super(); Object.defineProperty(this, "id", { value: textureId++ }); this.uuid = generateUUID(); this.name = ""; this.image = image; this.mipmaps = []; this.mapping = mapping; this.wrapS = wrapS; this.wrapT = wrapT; this.magFilter = magFilter; this.minFilter = minFilter; this.anisotropy = anisotropy; this.format = format; this.internalFormat = null; this.type = type; 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; this.encoding = encoding; this.version = 0; this.onUpdate = null; this.isRenderTargetTexture = false; } updateMatrix() { this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y); } clone() { return new this.constructor().copy(this); } copy(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(meta) { const isRootObject = meta === void 0 || typeof meta === "string"; if (!isRootObject && meta.textures[this.uuid] !== void 0) { return meta.textures[this.uuid]; } const 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 !== void 0) { const image = this.image; if (image.uuid === void 0) { image.uuid = generateUUID(); } if (!isRootObject && meta.images[image.uuid] === void 0) { let url; if (Array.isArray(image)) { url = []; for (let i = 0, l = image.length; i < l; i++) { if (image[i].isDataTexture) { url.push(serializeImage(image[i].image)); } else { url.push(serializeImage(image[i])); } } } else { url = serializeImage(image); } meta.images[image.uuid] = { uuid: image.uuid, url }; } output.image = image.uuid; } if (!isRootObject) { meta.textures[this.uuid] = output; } return output; } dispose() { this.dispatchEvent({ type: "dispose" }); } transformUv(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; } set needsUpdate(value) { if (value === true) this.version++; } }; Texture.DEFAULT_IMAGE = void 0; Texture.DEFAULT_MAPPING = UVMapping; Texture.prototype.isTexture = true; function serializeImage(image) { if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) { return ImageUtils.getDataURL(image); } else { if (image.data) { return { data: Array.prototype.slice.call(image.data), width: image.width, height: image.height, type: image.data.constructor.name }; } else { console.warn("THREE.Texture: Unable to serialize Texture."); return {}; } } } var Vector4 = class { constructor(x = 0, y = 0, z = 0, w2 = 1) { this.x = x; this.y = y; this.z = z; this.w = w2; } get width() { return this.z; } set width(value) { this.z = value; } get height() { return this.w; } set height(value) { this.w = value; } set(x, y, z, w2) { this.x = x; this.y = y; this.z = z; this.w = w2; return this; } setScalar(scalar) { this.x = scalar; this.y = scalar; this.z = scalar; this.w = scalar; return this; } setX(x) { this.x = x; return this; } setY(y) { this.y = y; return this; } setZ(z) { this.z = z; return this; } setW(w2) { this.w = w2; return this; } setComponent(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(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() { return new this.constructor(this.x, this.y, this.z, this.w); } copy(v) { this.x = v.x; this.y = v.y; this.z = v.z; this.w = v.w !== void 0 ? v.w : 1; return this; } add(v, w2) { if (w2 !== void 0) { console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."); return this.addVectors(v, w2); } this.x += v.x; this.y += v.y; this.z += v.z; this.w += v.w; return this; } addScalar(s) { this.x += s; this.y += s; this.z += s; this.w += s; return this; } addVectors(a2, b2) { this.x = a2.x + b2.x; this.y = a2.y + b2.y; this.z = a2.z + b2.z; this.w = a2.w + b2.w; return this; } addScaledVector(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(v, w2) { if (w2 !== void 0) { console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."); return this.subVectors(v, w2); } this.x -= v.x; this.y -= v.y; this.z -= v.z; this.w -= v.w; return this; } subScalar(s) { this.x -= s; this.y -= s; this.z -= s; this.w -= s; return this; } subVectors(a2, b2) { this.x = a2.x - b2.x; this.y = a2.y - b2.y; this.z = a2.z - b2.z; this.w = a2.w - b2.w; return this; } multiply(v) { this.x *= v.x; this.y *= v.y; this.z *= v.z; this.w *= v.w; return this; } multiplyScalar(scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; this.w *= scalar; return this; } applyMatrix4(m) { const x = this.x, y = this.y, z = this.z, w2 = this.w; const e = m.elements; this.x = e[0] * x + e[4] * y + e[8] * z + e[12] * w2; this.y = e[1] * x + e[5] * y + e[9] * z + e[13] * w2; this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w2; this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w2; return this; } divideScalar(scalar) { return this.multiplyScalar(1 / scalar); } setAxisAngleFromQuaternion(q) { this.w = 2 * Math.acos(q.w); const s = Math.sqrt(1 - q.w * q.w); if (s < 1e-4) { 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(m) { let angle, x, y, z; const epsilon = 0.01, epsilon2 = 0.1, 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) { if (Math.abs(m12 + m21) < epsilon2 && Math.abs(m13 + m31) < epsilon2 && Math.abs(m23 + m32) < epsilon2 && Math.abs(m11 + m22 + m33 - 3) < epsilon2) { this.set(1, 0, 0, 0); return this; } angle = Math.PI; const xx = (m11 + 1) / 2; const yy = (m22 + 1) / 2; const zz = (m33 + 1) / 2; const xy = (m12 + m21) / 4; const xz = (m13 + m31) / 4; const yz = (m23 + m32) / 4; if (xx > yy && xx > zz) { 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) { if (yy < epsilon) { x = 0.707106781; y = 0; z = 0.707106781; } else { y = Math.sqrt(yy); x = xy / y; z = yz / y; } } else { 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; } let s = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12)); if (Math.abs(s) < 1e-3) s = 1; 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(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(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(min, max) { 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(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(min, max) { const length = this.length(); return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); } floor() { 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() { 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() { 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() { 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() { this.x = -this.x; this.y = -this.y; this.z = -this.z; this.w = -this.w; return this; } dot(v) { return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; } lengthSq() { return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; } length() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); } manhattanLength() { return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w); } normalize() { return this.divideScalar(this.length() || 1); } setLength(length) { return this.normalize().multiplyScalar(length); } lerp(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(v12, v22, alpha) { this.x = v12.x + (v22.x - v12.x) * alpha; this.y = v12.y + (v22.y - v12.y) * alpha; this.z = v12.z + (v22.z - v12.z) * alpha; this.w = v12.w + (v22.w - v12.w) * alpha; return this; } equals(v) { return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w; } fromArray(array, offset = 0) { this.x = array[offset]; this.y = array[offset + 1]; this.z = array[offset + 2]; this.w = array[offset + 3]; return this; } toArray(array = [], offset = 0) { array[offset] = this.x; array[offset + 1] = this.y; array[offset + 2] = this.z; array[offset + 3] = this.w; return array; } fromBufferAttribute(attribute, index, offset) { if (offset !== void 0) { 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; } random() { this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); this.w = Math.random(); return this; } }; Vector4.prototype.isVector4 = true; var WebGLRenderTarget = class extends EventDispatcher { constructor(width, height, options = {}) { super(); this.width = width; this.height = height; this.depth = 1; this.scissor = new Vector4(0, 0, width, height); this.scissorTest = false; this.viewport = new Vector4(0, 0, width, height); this.texture = new Texture(void 0, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); this.texture.isRenderTargetTexture = true; this.texture.image = { width, height, depth: 1 }; this.texture.generateMipmaps = options.generateMipmaps !== void 0 ? options.generateMipmaps : false; this.texture.internalFormat = options.internalFormat !== void 0 ? options.internalFormat : null; this.texture.minFilter = options.minFilter !== void 0 ? options.minFilter : LinearFilter; this.depthBuffer = options.depthBuffer !== void 0 ? options.depthBuffer : true; this.stencilBuffer = options.stencilBuffer !== void 0 ? options.stencilBuffer : false; this.depthTexture = options.depthTexture !== void 0 ? options.depthTexture : null; } setTexture(texture) { texture.image = { width: this.width, height: this.height, depth: this.depth }; this.texture = texture; } setSize(width, height, depth = 1) { if (this.width !== width || this.height !== height || this.depth !== depth) { this.width = width; this.height = height; this.depth = depth; this.texture.image.width = width; this.texture.image.height = height; this.texture.image.depth = depth; this.dispose(); } this.viewport.set(0, 0, width, height); this.scissor.set(0, 0, width, height); } clone() { return new this.constructor().copy(this); } copy(source) { this.width = source.width; this.height = source.height; this.depth = source.depth; this.viewport.copy(source.viewport); this.texture = source.texture.clone(); this.texture.image = __spreadValues({}, this.texture.image); this.depthBuffer = source.depthBuffer; this.stencilBuffer = source.stencilBuffer; this.depthTexture = source.depthTexture; return this; } dispose() { this.dispatchEvent({ type: "dispose" }); } }; WebGLRenderTarget.prototype.isWebGLRenderTarget = true; var WebGLMultipleRenderTargets = class extends WebGLRenderTarget { constructor(width, height, count) { super(width, height); const texture = this.texture; this.texture = []; for (let i = 0; i < count; i++) { this.texture[i] = texture.clone(); } } setSize(width, height, depth = 1) { if (this.width !== width || this.height !== height || this.depth !== depth) { this.width = width; this.height = height; this.depth = depth; for (let i = 0, il = this.texture.length; i < il; i++) { this.texture[i].image.width = width; this.texture[i].image.height = height; this.texture[i].image.depth = depth; } this.dispose(); } this.viewport.set(0, 0, width, height); this.scissor.set(0, 0, width, height); return this; } copy(source) { this.dispose(); this.width = source.width; this.height = source.height; this.depth = source.depth; this.viewport.set(0, 0, this.width, this.height); this.scissor.set(0, 0, this.width, this.height); this.depthBuffer = source.depthBuffer; this.stencilBuffer = source.stencilBuffer; this.depthTexture = source.depthTexture; this.texture.length = 0; for (let i = 0, il = source.texture.length; i < il; i++) { this.texture[i] = source.texture[i].clone(); } return this; } }; WebGLMultipleRenderTargets.prototype.isWebGLMultipleRenderTargets = true; var WebGLMultisampleRenderTarget = class extends WebGLRenderTarget { constructor(width, height, options) { super(width, height, options); this.samples = 4; } copy(source) { super.copy.call(this, source); this.samples = source.samples; return this; } }; WebGLMultisampleRenderTarget.prototype.isWebGLMultisampleRenderTarget = true; var Quaternion = class { constructor(x = 0, y = 0, z = 0, w2 = 1) { this._x = x; this._y = y; this._z = z; this._w = w2; } static slerp(qa, qb, qm, t) { console.warn("THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead."); return qm.slerpQuaternions(qa, qb, t); } static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) { let x0 = src0[srcOffset0 + 0], y0 = src0[srcOffset0 + 1], z0 = src0[srcOffset0 + 2], w0 = src0[srcOffset0 + 3]; const x1 = src1[srcOffset1 + 0], y1 = src1[srcOffset1 + 1], z1 = src1[srcOffset1 + 2], w1 = src1[srcOffset1 + 3]; if (t === 0) { dst[dstOffset + 0] = x0; dst[dstOffset + 1] = y0; dst[dstOffset + 2] = z0; dst[dstOffset + 3] = w0; return; } if (t === 1) { dst[dstOffset + 0] = x1; dst[dstOffset + 1] = y1; dst[dstOffset + 2] = z1; dst[dstOffset + 3] = w1; return; } if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) { let s = 1 - t; const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, dir = cos >= 0 ? 1 : -1, sqrSin = 1 - cos * cos; if (sqrSin > Number.EPSILON) { const sin = Math.sqrt(sqrSin), len = Math.atan2(sin, cos * dir); s = Math.sin(s * len) / sin; t = Math.sin(t * len) / sin; } const tDir = t * dir; x0 = x0 * s + x1 * tDir; y0 = y0 * s + y1 * tDir; z0 = z0 * s + z1 * tDir; w0 = w0 * s + w1 * tDir; if (s === 1 - t) { const 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; } static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) { const x0 = src0[srcOffset0]; const y0 = src0[srcOffset0 + 1]; const z0 = src0[srcOffset0 + 2]; const w0 = src0[srcOffset0 + 3]; const x1 = src1[srcOffset1]; const y1 = src1[srcOffset1 + 1]; const z1 = src1[srcOffset1 + 2]; const w1 = src1[srcOffset1 + 3]; dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1; dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1; dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1; dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; return dst; } get x() { return this._x; } set x(value) { this._x = value; this._onChangeCallback(); } get y() { return this._y; } set y(value) { this._y = value; this._onChangeCallback(); } get z() { return this._z; } set z(value) { this._z = value; this._onChangeCallback(); } get w() { return this._w; } set w(value) { this._w = value; this._onChangeCallback(); } set(x, y, z, w2) { this._x = x; this._y = y; this._z = z; this._w = w2; this._onChangeCallback(); return this; } clone() { return new this.constructor(this._x, this._y, this._z, this._w); } copy(quaternion) { this._x = quaternion.x; this._y = quaternion.y; this._z = quaternion.z; this._w = quaternion.w; this._onChangeCallback(); return this; } setFromEuler(euler, update) { if (!(euler && euler.isEuler)) { throw new Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order."); } const x = euler._x, y = euler._y, z = euler._z, order = euler._order; const cos = Math.cos; const sin = Math.sin; const c1 = cos(x / 2); const c2 = cos(y / 2); const c3 = cos(z / 2); const s1 = sin(x / 2); const s2 = sin(y / 2); const s3 = sin(z / 2); switch (order) { case "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; break; case "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; break; case "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; break; case "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; break; case "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; break; case "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; break; default: console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: " + order); } if (update !== false) this._onChangeCallback(); return this; } setFromAxisAngle(axis, angle) { const 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(m) { const 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; if (trace > 0) { const s = 0.5 / Math.sqrt(trace + 1); 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) { const s = 2 * Math.sqrt(1 + 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) { const s = 2 * Math.sqrt(1 + m22 - m11 - m33); this._w = (m13 - m31) / s; this._x = (m12 + m21) / s; this._y = 0.25 * s; this._z = (m23 + m32) / s; } else { const s = 2 * Math.sqrt(1 + 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(vFrom, vTo) { let r = vFrom.dot(vTo) + 1; if (r < Number.EPSILON) { 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 { 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(q) { return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1))); } rotateTowards(q, step) { const angle = this.angleTo(q); if (angle === 0) return this; const t = Math.min(1, step / angle); this.slerp(q, t); return this; } identity() { return this.set(0, 0, 0, 1); } invert() { return this.conjugate(); } conjugate() { this._x *= -1; this._y *= -1; this._z *= -1; this._onChangeCallback(); return this; } dot(v) { return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; } lengthSq() { return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; } length() { return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w); } normalize() { let 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(q, p2) { if (p2 !== void 0) { console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."); return this.multiplyQuaternions(q, p2); } return this.multiplyQuaternions(this, q); } premultiply(q) { return this.multiplyQuaternions(q, this); } multiplyQuaternions(a2, b2) { const qax = a2._x, qay = a2._y, qaz = a2._z, qaw = a2._w; const qbx = b2._x, qby = b2._y, qbz = b2._z, qbw = b2._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(qb, t) { if (t === 0) return this; if (t === 1) return this.copy(qb); const x = this._x, y = this._y, z = this._z, w2 = this._w; let cosHalfTheta = w2 * 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) { this._w = w2; this._x = x; this._y = y; this._z = z; return this; } const sqrSinHalfTheta = 1 - cosHalfTheta * cosHalfTheta; if (sqrSinHalfTheta <= Number.EPSILON) { const s = 1 - t; this._w = s * w2 + 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; } const sinHalfTheta = Math.sqrt(sqrSinHalfTheta); const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta); const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, ratioB = Math.sin(t * halfTheta) / sinHalfTheta; this._w = w2 * 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; } slerpQuaternions(qa, qb, t) { this.copy(qa).slerp(qb, t); } equals(quaternion) { return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w; } fromArray(array, 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(array = [], offset = 0) { array[offset] = this._x; array[offset + 1] = this._y; array[offset + 2] = this._z; array[offset + 3] = this._w; return array; } fromBufferAttribute(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(callback) { this._onChangeCallback = callback; return this; } _onChangeCallback() { } }; Quaternion.prototype.isQuaternion = true; var Vector3 = class { constructor(x = 0, y = 0, z = 0) { this.x = x; this.y = y; this.z = z; } set(x, y, z) { if (z === void 0) z = this.z; this.x = x; this.y = y; this.z = z; return this; } setScalar(scalar) { this.x = scalar; this.y = scalar; this.z = scalar; return this; } setX(x) { this.x = x; return this; } setY(y) { this.y = y; return this; } setZ(z) { this.z = z; return this; } setComponent(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(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() { return new this.constructor(this.x, this.y, this.z); } copy(v) { this.x = v.x; this.y = v.y; this.z = v.z; return this; } add(v, w2) { if (w2 !== void 0) { console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."); return this.addVectors(v, w2); } this.x += v.x; this.y += v.y; this.z += v.z; return this; } addScalar(s) { this.x += s; this.y += s; this.z += s; return this; } addVectors(a2, b2) { this.x = a2.x + b2.x; this.y = a2.y + b2.y; this.z = a2.z + b2.z; return this; } addScaledVector(v, s) { this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; return this; } sub(v, w2) { if (w2 !== void 0) { console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."); return this.subVectors(v, w2); } this.x -= v.x; this.y -= v.y; this.z -= v.z; return this; } subScalar(s) { this.x -= s; this.y -= s; this.z -= s; return this; } subVectors(a2, b2) { this.x = a2.x - b2.x; this.y = a2.y - b2.y; this.z = a2.z - b2.z; return this; } multiply(v, w2) { if (w2 !== void 0) { console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."); return this.multiplyVectors(v, w2); } this.x *= v.x; this.y *= v.y; this.z *= v.z; return this; } multiplyScalar(scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; return this; } multiplyVectors(a2, b2) { this.x = a2.x * b2.x; this.y = a2.y * b2.y; this.z = a2.z * b2.z; return this; } applyEuler(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$4.setFromEuler(euler)); } applyAxisAngle(axis, angle) { return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle)); } applyMatrix3(m) { const x = this.x, y = this.y, z = this.z; const 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(m) { return this.applyMatrix3(m).normalize(); } applyMatrix4(m) { const x = this.x, y = this.y, z = this.z; const e = m.elements; const w2 = 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]) * w2; this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w2; this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w2; return this; } applyQuaternion(q) { const x = this.x, y = this.y, z = this.z; const qx = q.x, qy = q.y, qz = q.z, qw = q.w; const ix = qw * x + qy * z - qz * y; const iy = qw * y + qz * x - qx * z; const iz = qw * z + qx * y - qy * x; const iw = -qx * x - qy * y - qz * z; 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(camera) { return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix); } unproject(camera) { return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld); } transformDirection(m) { const x = this.x, y = this.y, z = this.z; const 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(v) { this.x /= v.x; this.y /= v.y; this.z /= v.z; return this; } divideScalar(scalar) { return this.multiplyScalar(1 / scalar); } min(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(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(min, max) { 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(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(min, max) { const length = this.length(); return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length))); } floor() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); this.z = Math.floor(this.z); return this; } ceil() { this.x = Math.ceil(this.x); this.y = Math.ceil(this.y); this.z = Math.ceil(this.z); return this; } round() { this.x = Math.round(this.x); this.y = Math.round(this.y); this.z = Math.round(this.z); return this; } roundToZero() { 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() { this.x = -this.x; this.y = -this.y; this.z = -this.z; return this; } dot(v) { return this.x * v.x + this.y * v.y + this.z * v.z; } lengthSq() { return this.x * this.x + this.y * this.y + this.z * this.z; } length() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); } manhattanLength() { return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z); } normalize() { return this.divideScalar(this.length() || 1); } setLength(length) { return this.normalize().multiplyScalar(length); } lerp(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(v12, v22, alpha) { this.x = v12.x + (v22.x - v12.x) * alpha; this.y = v12.y + (v22.y - v12.y) * alpha; this.z = v12.z + (v22.z - v12.z) * alpha; return this; } cross(v, w2) { if (w2 !== void 0) { console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."); return this.crossVectors(v, w2); } return this.crossVectors(this, v); } crossVectors(a2, b2) { const ax = a2.x, ay = a2.y, az = a2.z; const bx = b2.x, by = b2.y, bz = b2.z; this.x = ay * bz - az * by; this.y = az * bx - ax * bz; this.z = ax * by - ay * bx; return this; } projectOnVector(v) { const denominator = v.lengthSq(); if (denominator === 0) return this.set(0, 0, 0); const scalar = v.dot(this) / denominator; return this.copy(v).multiplyScalar(scalar); } projectOnPlane(planeNormal) { _vector$c.copy(this).projectOnVector(planeNormal); return this.sub(_vector$c); } reflect(normal) { return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal))); } angleTo(v) { const denominator = Math.sqrt(this.lengthSq() * v.lengthSq()); if (denominator === 0) return Math.PI / 2; const theta = this.dot(v) / denominator; return Math.acos(clamp(theta, -1, 1)); } distanceTo(v) { return Math.sqrt(this.distanceToSquared(v)); } distanceToSquared(v) { const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; return dx * dx + dy * dy + dz * dz; } manhattanDistanceTo(v) { return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z); } setFromSpherical(s) { return this.setFromSphericalCoords(s.radius, s.phi, s.theta); } setFromSphericalCoords(radius, phi, theta) { const 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(c2) { return this.setFromCylindricalCoords(c2.radius, c2.theta, c2.y); } setFromCylindricalCoords(radius, theta, y) { this.x = radius * Math.sin(theta); this.y = y; this.z = radius * Math.cos(theta); return this; } setFromMatrixPosition(m) { const e = m.elements; this.x = e[12]; this.y = e[13]; this.z = e[14]; return this; } setFromMatrixScale(m) { const sx = this.setFromMatrixColumn(m, 0).length(); const sy = this.setFromMatrixColumn(m, 1).length(); const sz = this.setFromMatrixColumn(m, 2).length(); this.x = sx; this.y = sy; this.z = sz; return this; } setFromMatrixColumn(m, index) { return this.fromArray(m.elements, index * 4); } setFromMatrix3Column(m, index) { return this.fromArray(m.elements, index * 3); } equals(v) { return v.x === this.x && v.y === this.y && v.z === this.z; } fromArray(array, offset = 0) { this.x = array[offset]; this.y = array[offset + 1]; this.z = array[offset + 2]; return this; } toArray(array = [], offset = 0) { array[offset] = this.x; array[offset + 1] = this.y; array[offset + 2] = this.z; return array; } fromBufferAttribute(attribute, index, offset) { if (offset !== void 0) { 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; } random() { this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); return this; } }; Vector3.prototype.isVector3 = true; var _vector$c = /* @__PURE__ */ new Vector3(); var _quaternion$4 = /* @__PURE__ */ new Quaternion(); var Box3 = class { constructor(min = new Vector3(Infinity, Infinity, Infinity), max = new Vector3(-Infinity, -Infinity, -Infinity)) { this.min = min; this.max = max; } set(min, max) { this.min.copy(min); this.max.copy(max); return this; } setFromArray(array) { let minX = Infinity; let minY = Infinity; let minZ = Infinity; let maxX = -Infinity; let maxY = -Infinity; let maxZ = -Infinity; for (let i = 0, l = array.length; i < l; i += 3) { const x = array[i]; const y = array[i + 1]; const 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(attribute) { let minX = Infinity; let minY = Infinity; let minZ = Infinity; let maxX = -Infinity; let maxY = -Infinity; let maxZ = -Infinity; for (let i = 0, l = attribute.count; i < l; i++) { const x = attribute.getX(i); const y = attribute.getY(i); const 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(points) { this.makeEmpty(); for (let i = 0, il = points.length; i < il; i++) { this.expandByPoint(points[i]); } return this; } setFromCenterAndSize(center, size) { const halfSize = _vector$b.copy(size).multiplyScalar(0.5); this.min.copy(center).sub(halfSize); this.max.copy(center).add(halfSize); return this; } setFromObject(object) { this.makeEmpty(); return this.expandByObject(object); } clone() { return new this.constructor().copy(this); } copy(box) { this.min.copy(box.min); this.max.copy(box.max); return this; } makeEmpty() { this.min.x = this.min.y = this.min.z = Infinity; this.max.x = this.max.y = this.max.z = -Infinity; return this; } isEmpty() { return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z; } getCenter(target) { return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); } getSize(target) { return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min); } expandByPoint(point) { this.min.min(point); this.max.max(point); return this; } expandByVector(vector) { this.min.sub(vector); this.max.add(vector); return this; } expandByScalar(scalar) { this.min.addScalar(-scalar); this.max.addScalar(scalar); return this; } expandByObject(object) { object.updateWorldMatrix(false, false); const geometry = object.geometry; if (geometry !== void 0) { if (geometry.boundingBox === null) { geometry.computeBoundingBox(); } _box$3.copy(geometry.boundingBox); _box$3.applyMatrix4(object.matrixWorld); this.union(_box$3); } const children = object.children; for (let i = 0, l = children.length; i < l; i++) { this.expandByObject(children[i]); } return this; } containsPoint(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(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(point, target) { 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(box) { 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(sphere) { this.clampPoint(sphere.center, _vector$b); return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius; } intersectsPlane(plane) { let 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(triangle) { if (this.isEmpty()) { return false; } this.getCenter(_center); _extents.subVectors(this.max, _center); _v0$2.subVectors(triangle.a, _center); _v1$7.subVectors(triangle.b, _center); _v2$3.subVectors(triangle.c, _center); _f0.subVectors(_v1$7, _v0$2); _f1.subVectors(_v2$3, _v1$7); _f2.subVectors(_v0$2, _v2$3); let 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$2, _v1$7, _v2$3, _extents)) { return false; } axes = [1, 0, 0, 0, 1, 0, 0, 0, 1]; if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) { return false; } _triangleNormal.crossVectors(_f0, _f1); axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z]; return satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents); } clampPoint(point, target) { return target.copy(point).clamp(this.min, this.max); } distanceToPoint(point) { const clampedPoint = _vector$b.copy(point).clamp(this.min, this.max); return clampedPoint.sub(point).length(); } getBoundingSphere(target) { this.getCenter(target.center); target.radius = this.getSize(_vector$b).length() * 0.5; return target; } intersect(box) { this.min.max(box.min); this.max.min(box.max); if (this.isEmpty()) this.makeEmpty(); return this; } union(box) { this.min.min(box.min); this.max.max(box.max); return this; } applyMatrix4(matrix) { if (this.isEmpty()) return this; _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); this.setFromPoints(_points); return this; } translate(offset) { this.min.add(offset); this.max.add(offset); return this; } equals(box) { return box.min.equals(this.min) && box.max.equals(this.max); } }; Box3.prototype.isBox3 = true; var _points = [ /* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3(), /* @__PURE__ */ new Vector3() ]; var _vector$b = /* @__PURE__ */ new Vector3(); var _box$3 = /* @__PURE__ */ new Box3(); var _v0$2 = /* @__PURE__ */ new Vector3(); var _v1$7 = /* @__PURE__ */ new Vector3(); var _v2$3 = /* @__PURE__ */ new Vector3(); var _f0 = /* @__PURE__ */ new Vector3(); var _f1 = /* @__PURE__ */ new Vector3(); var _f2 = /* @__PURE__ */ new Vector3(); var _center = /* @__PURE__ */ new Vector3(); var _extents = /* @__PURE__ */ new Vector3(); var _triangleNormal = /* @__PURE__ */ new Vector3(); var _testAxis = /* @__PURE__ */ new Vector3(); function satForAxes(axes, v02, v12, v22, extents) { for (let i = 0, j = axes.length - 3; i <= j; i += 3) { _testAxis.fromArray(axes, i); const r = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z); const p0 = v02.dot(_testAxis); const p1 = v12.dot(_testAxis); const p2 = v22.dot(_testAxis); if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) { return false; } } return true; } var _box$2 = /* @__PURE__ */ new Box3(); var _v1$6 = /* @__PURE__ */ new Vector3(); var _toFarthestPoint = /* @__PURE__ */ new Vector3(); var _toPoint = /* @__PURE__ */ new Vector3(); var Sphere = class { constructor(center = new Vector3(), radius = -1) { this.center = center; this.radius = radius; } set(center, radius) { this.center.copy(center); this.radius = radius; return this; } setFromPoints(points, optionalCenter) { const center = this.center; if (optionalCenter !== void 0) { center.copy(optionalCenter); } else { _box$2.setFromPoints(points).getCenter(center); } let maxRadiusSq = 0; for (let i = 0, il = points.length; i < il; i++) { maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i])); } this.radius = Math.sqrt(maxRadiusSq); return this; } copy(sphere) { this.center.copy(sphere.center); this.radius = sphere.radius; return this; } isEmpty() { return this.radius < 0; } makeEmpty() { this.center.set(0, 0, 0); this.radius = -1; return this; } containsPoint(point) { return point.distanceToSquared(this.center) <= this.radius * this.radius; } distanceToPoint(point) { return point.distanceTo(this.center) - this.radius; } intersectsSphere(sphere) { const radiusSum = this.radius + sphere.radius; return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum; } intersectsBox(box) { return box.intersectsSphere(this); } intersectsPlane(plane) { return Math.abs(plane.distanceToPoint(this.center)) <= this.radius; } clampPoint(point, target) { const deltaLengthSq = this.center.distanceToSquared(point); target.copy(point); if (deltaLengthSq > this.radius * this.radius) { target.sub(this.center).normalize(); target.multiplyScalar(this.radius).add(this.center); } return target; } getBoundingBox(target) { if (this.isEmpty()) { target.makeEmpty(); return target; } target.set(this.center, this.center); target.expandByScalar(this.radius); return target; } applyMatrix4(matrix) { this.center.applyMatrix4(matrix); this.radius = this.radius * matrix.getMaxScaleOnAxis(); return this; } translate(offset) { this.center.add(offset); return this; } expandByPoint(point) { _toPoint.subVectors(point, this.center); const lengthSq = _toPoint.lengthSq(); if (lengthSq > this.radius * this.radius) { const length = Math.sqrt(lengthSq); const missingRadiusHalf = (length - this.radius) * 0.5; this.center.add(_toPoint.multiplyScalar(missingRadiusHalf / length)); this.radius += missingRadiusHalf; } return this; } union(sphere) { _toFarthestPoint.subVectors(sphere.center, this.center).normalize().multiplyScalar(sphere.radius); this.expandByPoint(_v1$6.copy(sphere.center).add(_toFarthestPoint)); this.expandByPoint(_v1$6.copy(sphere.center).sub(_toFarthestPoint)); return this; } equals(sphere) { return sphere.center.equals(this.center) && sphere.radius === this.radius; } clone() { return new this.constructor().copy(this); } }; var _vector$a = /* @__PURE__ */ new Vector3(); var _segCenter = /* @__PURE__ */ new Vector3(); var _segDir = /* @__PURE__ */ new Vector3(); var _diff = /* @__PURE__ */ new Vector3(); var _edge1 = /* @__PURE__ */ new Vector3(); var _edge2 = /* @__PURE__ */ new Vector3(); var _normal$1 = /* @__PURE__ */ new Vector3(); var Ray = class { constructor(origin = new Vector3(), direction = new Vector3(0, 0, -1)) { this.origin = origin; this.direction = direction; } set(origin, direction) { this.origin.copy(origin); this.direction.copy(direction); return this; } copy(ray) { this.origin.copy(ray.origin); this.direction.copy(ray.direction); return this; } at(t, target) { return target.copy(this.direction).multiplyScalar(t).add(this.origin); } lookAt(v) { this.direction.copy(v).sub(this.origin).normalize(); return this; } recast(t) { this.origin.copy(this.at(t, _vector$a)); return this; } closestPointToPoint(point, target) { target.subVectors(point, this.origin); const directionDistance = target.dot(this.direction); if (directionDistance < 0) { return target.copy(this.origin); } return target.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); } distanceToPoint(point) { return Math.sqrt(this.distanceSqToPoint(point)); } distanceSqToPoint(point) { const directionDistance = _vector$a.subVectors(point, this.origin).dot(this.direction); if (directionDistance < 0) { return this.origin.distanceToSquared(point); } _vector$a.copy(this.direction).multiplyScalar(directionDistance).add(this.origin); return _vector$a.distanceToSquared(point); } distanceSqToSegment(v02, v12, optionalPointOnRay, optionalPointOnSegment) { _segCenter.copy(v02).add(v12).multiplyScalar(0.5); _segDir.copy(v12).sub(v02).normalize(); _diff.copy(this.origin).sub(_segCenter); const segExtent = v02.distanceTo(v12) * 0.5; const a01 = -this.direction.dot(_segDir); const b0 = _diff.dot(this.direction); const b1 = -_diff.dot(_segDir); const c2 = _diff.lengthSq(); const det = Math.abs(1 - a01 * a01); let s0, s1, sqrDist, extDet; if (det > 0) { s0 = a01 * b1 - b0; s1 = a01 * b0 - b1; extDet = segExtent * det; if (s0 >= 0) { if (s1 >= -extDet) { if (s1 <= extDet) { const invDet = 1 / det; s0 *= invDet; s1 *= invDet; sqrDist = s0 * (s0 + a01 * s1 + 2 * b0) + s1 * (a01 * s0 + s1 + 2 * b1) + c2; } else { s1 = segExtent; s0 = Math.max(0, -(a01 * s1 + b0)); sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c2; } } else { s1 = -segExtent; s0 = Math.max(0, -(a01 * s1 + b0)); sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c2; } } else { if (s1 <= -extDet) { 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) + c2; } else if (s1 <= extDet) { s0 = 0; s1 = Math.min(Math.max(-segExtent, -b1), segExtent); sqrDist = s1 * (s1 + 2 * b1) + c2; } else { 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) + c2; } } } else { s1 = a01 > 0 ? -segExtent : segExtent; s0 = Math.max(0, -(a01 * s1 + b0)); sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c2; } if (optionalPointOnRay) { optionalPointOnRay.copy(this.direction).multiplyScalar(s0).add(this.origin); } if (optionalPointOnSegment) { optionalPointOnSegment.copy(_segDir).multiplyScalar(s1).add(_segCenter); } return sqrDist; } intersectSphere(sphere, target) { _vector$a.subVectors(sphere.center, this.origin); const tca = _vector$a.dot(this.direction); const d2 = _vector$a.dot(_vector$a) - tca * tca; const radius2 = sphere.radius * sphere.radius; if (d2 > radius2) return null; const thc = Math.sqrt(radius2 - d2); const t0 = tca - thc; const t1 = tca + thc; if (t0 < 0 && t1 < 0) return null; if (t0 < 0) return this.at(t1, target); return this.at(t0, target); } intersectsSphere(sphere) { return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius; } distanceToPlane(plane) { const denominator = plane.normal.dot(this.direction); if (denominator === 0) { if (plane.distanceToPoint(this.origin) === 0) { return 0; } return null; } const t = -(this.origin.dot(plane.normal) + plane.constant) / denominator; return t >= 0 ? t : null; } intersectPlane(plane, target) { const t = this.distanceToPlane(plane); if (t === null) { return null; } return this.at(t, target); } intersectsPlane(plane) { const distToPoint = plane.distanceToPoint(this.origin); if (distToPoint === 0) { return true; } const denominator = plane.normal.dot(this.direction); if (denominator * distToPoint < 0) { return true; } return false; } intersectBox(box, target) { let tmin, tmax, tymin, tymax, tzmin, tzmax; const invdirx = 1 / this.direction.x, invdiry = 1 / this.direction.y, invdirz = 1 / this.direction.z; const 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; 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; if (tmax < 0) return null; return this.at(tmin >= 0 ? tmin : tmax, target); } intersectsBox(box) { return this.intersectBox(box, _vector$a) !== null; } intersectTriangle(a2, b2, c2, backfaceCulling, target) { _edge1.subVectors(b2, a2); _edge2.subVectors(c2, a2); _normal$1.crossVectors(_edge1, _edge2); let DdN = this.direction.dot(_normal$1); let sign2; if (DdN > 0) { if (backfaceCulling) return null; sign2 = 1; } else if (DdN < 0) { sign2 = -1; DdN = -DdN; } else { return null; } _diff.subVectors(this.origin, a2); const DdQxE2 = sign2 * this.direction.dot(_edge2.crossVectors(_diff, _edge2)); if (DdQxE2 < 0) { return null; } const DdE1xQ = sign2 * this.direction.dot(_edge1.cross(_diff)); if (DdE1xQ < 0) { return null; } if (DdQxE2 + DdE1xQ > DdN) { return null; } const QdN = -sign2 * _diff.dot(_normal$1); if (QdN < 0) { return null; } return this.at(QdN / DdN, target); } applyMatrix4(matrix4) { this.origin.applyMatrix4(matrix4); this.direction.transformDirection(matrix4); return this; } equals(ray) { return ray.origin.equals(this.origin) && ray.direction.equals(this.direction); } clone() { return new this.constructor().copy(this); } }; var Matrix4 = class { constructor() { 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."); } } set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { const 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() { this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); return this; } clone() { return new Matrix4().fromArray(this.elements); } copy(m) { const te = this.elements; const 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(m) { const te = this.elements, me = m.elements; te[12] = me[12]; te[13] = me[13]; te[14] = me[14]; return this; } setFromMatrix3(m) { const me = m.elements; this.set(me[0], me[3], me[6], 0, me[1], me[4], me[7], 0, me[2], me[5], me[8], 0, 0, 0, 0, 1); return this; } extractBasis(xAxis, yAxis, zAxis) { xAxis.setFromMatrixColumn(this, 0); yAxis.setFromMatrixColumn(this, 1); zAxis.setFromMatrixColumn(this, 2); return this; } makeBasis(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(m) { const te = this.elements; const me = m.elements; const scaleX = 1 / _v1$5.setFromMatrixColumn(m, 0).length(); const scaleY = 1 / _v1$5.setFromMatrixColumn(m, 1).length(); const scaleZ = 1 / _v1$5.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(euler) { if (!(euler && euler.isEuler)) { console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order."); } const te = this.elements; const x = euler.x, y = euler.y, z = euler.z; const a2 = Math.cos(x), b2 = Math.sin(x); const c2 = Math.cos(y), d = Math.sin(y); const e = Math.cos(z), f = Math.sin(z); if (euler.order === "XYZ") { const ae = a2 * e, af = a2 * f, be = b2 * e, bf = b2 * f; te[0] = c2 * e; te[4] = -c2 * f; te[8] = d; te[1] = af + be * d; te[5] = ae - bf * d; te[9] = -b2 * c2; te[2] = bf - ae * d; te[6] = be + af * d; te[10] = a2 * c2; } else if (euler.order === "YXZ") { const ce = c2 * e, cf = c2 * f, de = d * e, df = d * f; te[0] = ce + df * b2; te[4] = de * b2 - cf; te[8] = a2 * d; te[1] = a2 * f; te[5] = a2 * e; te[9] = -b2; te[2] = cf * b2 - de; te[6] = df + ce * b2; te[10] = a2 * c2; } else if (euler.order === "ZXY") { const ce = c2 * e, cf = c2 * f, de = d * e, df = d * f; te[0] = ce - df * b2; te[4] = -a2 * f; te[8] = de + cf * b2; te[1] = cf + de * b2; te[5] = a2 * e; te[9] = df - ce * b2; te[2] = -a2 * d; te[6] = b2; te[10] = a2 * c2; } else if (euler.order === "ZYX") { const ae = a2 * e, af = a2 * f, be = b2 * e, bf = b2 * f; te[0] = c2 * e; te[4] = be * d - af; te[8] = ae * d + bf; te[1] = c2 * f; te[5] = bf * d + ae; te[9] = af * d - be; te[2] = -d; te[6] = b2 * c2; te[10] = a2 * c2; } else if (euler.order === "YZX") { const ac = a2 * c2, ad = a2 * d, bc = b2 * c2, bd = b2 * d; te[0] = c2 * e; te[4] = bd - ac * f; te[8] = bc * f + ad; te[1] = f; te[5] = a2 * e; te[9] = -b2 * e; te[2] = -d * e; te[6] = ad * f + bc; te[10] = ac - bd * f; } else if (euler.order === "XZY") { const ac = a2 * c2, ad = a2 * d, bc = b2 * c2, bd = b2 * d; te[0] = c2 * e; te[4] = -f; te[8] = d * e; te[1] = ac * f + bd; te[5] = a2 * e; te[9] = ad * f - bc; te[2] = bc * f - ad; te[6] = b2 * e; te[10] = bd * f + ac; } te[3] = 0; te[7] = 0; te[11] = 0; te[12] = 0; te[13] = 0; te[14] = 0; te[15] = 1; return this; } makeRotationFromQuaternion(q) { return this.compose(_zero, q, _one); } lookAt(eye, target, up) { const te = this.elements; _z.subVectors(eye, target); if (_z.lengthSq() === 0) { _z.z = 1; } _z.normalize(); _x.crossVectors(up, _z); if (_x.lengthSq() === 0) { if (Math.abs(up.z) === 1) { _z.x += 1e-4; } else { _z.z += 1e-4; } _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(m, n) { if (n !== void 0) { 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(m) { return this.multiplyMatrices(m, this); } multiplyMatrices(a2, b2) { const ae = a2.elements; const be = b2.elements; const te = this.elements; const a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12]; const a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13]; const a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14]; const a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15]; const b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12]; const b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13]; const b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14]; const 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(s) { const 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() { const te = this.elements; const n11 = te[0], n12 = te[4], n13 = te[8], n14 = te[12]; const n21 = te[1], n22 = te[5], n23 = te[9], n24 = te[13]; const n31 = te[2], n32 = te[6], n33 = te[10], n34 = te[14]; const n41 = te[3], n42 = te[7], n43 = te[11], n44 = te[15]; 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() { const te = this.elements; let tmp3; tmp3 = te[1]; te[1] = te[4]; te[4] = tmp3; tmp3 = te[2]; te[2] = te[8]; te[8] = tmp3; tmp3 = te[6]; te[6] = te[9]; te[9] = tmp3; tmp3 = te[3]; te[3] = te[12]; te[12] = tmp3; tmp3 = te[7]; te[7] = te[13]; te[13] = tmp3; tmp3 = te[11]; te[11] = te[14]; te[14] = tmp3; return this; } setPosition(x, y, z) { const 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; } invert() { const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n41 = te[3], n12 = te[4], n22 = te[5], n32 = te[6], n42 = te[7], n13 = te[8], n23 = te[9], n33 = te[10], n43 = te[11], n14 = te[12], n24 = te[13], n34 = te[14], n44 = te[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; const 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); const 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(v) { const te = this.elements; const 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() { const te = this.elements; const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2]; const scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6]; const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10]; return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq)); } makeTranslation(x, y, z) { this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1); return this; } makeRotationX(theta) { const c2 = Math.cos(theta), s = Math.sin(theta); this.set(1, 0, 0, 0, 0, c2, -s, 0, 0, s, c2, 0, 0, 0, 0, 1); return this; } makeRotationY(theta) { const c2 = Math.cos(theta), s = Math.sin(theta); this.set(c2, 0, s, 0, 0, 1, 0, 0, -s, 0, c2, 0, 0, 0, 0, 1); return this; } makeRotationZ(theta) { const c2 = Math.cos(theta), s = Math.sin(theta); this.set(c2, -s, 0, 0, s, c2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); return this; } makeRotationAxis(axis, angle) { const c2 = Math.cos(angle); const s = Math.sin(angle); const t = 1 - c2; const x = axis.x, y = axis.y, z = axis.z; const tx = t * x, ty = t * y; this.set(tx * x + c2, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c2, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c2, 0, 0, 0, 0, 1); return this; } makeScale(x, y, z) { this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1); return this; } makeShear(xy, xz, yx, yz, zx, zy) { this.set(1, yx, zx, 0, xy, 1, zy, 0, xz, yz, 1, 0, 0, 0, 0, 1); return this; } compose(position, quaternion, scale) { const te = this.elements; const x = quaternion._x, y = quaternion._y, z = quaternion._z, w2 = quaternion._w; const x2 = x + x, y2 = y + y, z2 = z + z; const xx = x * x2, xy = x * y2, xz = x * z2; const yy = y * y2, yz = y * z2, zz = z * z2; const wx = w2 * x2, wy = w2 * y2, wz = w2 * z2; const 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(position, quaternion, scale) { const te = this.elements; let sx = _v1$5.set(te[0], te[1], te[2]).length(); const sy = _v1$5.set(te[4], te[5], te[6]).length(); const sz = _v1$5.set(te[8], te[9], te[10]).length(); const det = this.determinant(); if (det < 0) sx = -sx; position.x = te[12]; position.y = te[13]; position.z = te[14]; _m1$2.copy(this); const invSX = 1 / sx; const invSY = 1 / sy; const invSZ = 1 / sz; _m1$2.elements[0] *= invSX; _m1$2.elements[1] *= invSX; _m1$2.elements[2] *= invSX; _m1$2.elements[4] *= invSY; _m1$2.elements[5] *= invSY; _m1$2.elements[6] *= invSY; _m1$2.elements[8] *= invSZ; _m1$2.elements[9] *= invSZ; _m1$2.elements[10] *= invSZ; quaternion.setFromRotationMatrix(_m1$2); scale.x = sx; scale.y = sy; scale.z = sz; return this; } makePerspective(left, right, top, bottom, near, far) { if (far === void 0) { console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs."); } const te = this.elements; const x = 2 * near / (right - left); const y = 2 * near / (top - bottom); const a2 = (right + left) / (right - left); const b2 = (top + bottom) / (top - bottom); const c2 = -(far + near) / (far - near); const d = -2 * far * near / (far - near); te[0] = x; te[4] = 0; te[8] = a2; te[12] = 0; te[1] = 0; te[5] = y; te[9] = b2; te[13] = 0; te[2] = 0; te[6] = 0; te[10] = c2; te[14] = d; te[3] = 0; te[7] = 0; te[11] = -1; te[15] = 0; return this; } makeOrthographic(left, right, top, bottom, near, far) { const te = this.elements; const w2 = 1 / (right - left); const h = 1 / (top - bottom); const p2 = 1 / (far - near); const x = (right + left) * w2; const y = (top + bottom) * h; const z = (far + near) * p2; te[0] = 2 * w2; 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 * p2; te[14] = -z; te[3] = 0; te[7] = 0; te[11] = 0; te[15] = 1; return this; } equals(matrix) { const te = this.elements; const me = matrix.elements; for (let i = 0; i < 16; i++) { if (te[i] !== me[i]) return false; } return true; } fromArray(array, offset = 0) { for (let i = 0; i < 16; i++) { this.elements[i] = array[i + offset]; } return this; } toArray(array = [], offset = 0) { const 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; } }; Matrix4.prototype.isMatrix4 = true; var _v1$5 = /* @__PURE__ */ new Vector3(); var _m1$2 = /* @__PURE__ */ new Matrix4(); var _zero = /* @__PURE__ */ new Vector3(0, 0, 0); var _one = /* @__PURE__ */ new Vector3(1, 1, 1); var _x = /* @__PURE__ */ new Vector3(); var _y = /* @__PURE__ */ new Vector3(); var _z = /* @__PURE__ */ new Vector3(); var _matrix$1 = /* @__PURE__ */ new Matrix4(); var _quaternion$3 = /* @__PURE__ */ new Quaternion(); var Euler = class { constructor(x = 0, y = 0, z = 0, order = Euler.DefaultOrder) { this._x = x; this._y = y; this._z = z; this._order = order; } get x() { return this._x; } set x(value) { this._x = value; this._onChangeCallback(); } get y() { return this._y; } set y(value) { this._y = value; this._onChangeCallback(); } get z() { return this._z; } set z(value) { this._z = value; this._onChangeCallback(); } get order() { return this._order; } set order(value) { this._order = value; this._onChangeCallback(); } set(x, y, z, order = this._order) { this._x = x; this._y = y; this._z = z; this._order = order; this._onChangeCallback(); return this; } clone() { return new this.constructor(this._x, this._y, this._z, this._order); } copy(euler) { this._x = euler._x; this._y = euler._y; this._z = euler._z; this._order = euler._order; this._onChangeCallback(); return this; } setFromRotationMatrix(m, order = this._order, update = true) { const te = m.elements; const m11 = te[0], m12 = te[4], m13 = te[8]; const m21 = te[1], m22 = te[5], m23 = te[9]; const m31 = te[2], m32 = te[6], m33 = te[10]; switch (order) { case "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; } break; case "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; } break; case "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); } break; case "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); } break; case "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); } break; case "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; } break; default: console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: " + order); } this._order = order; if (update === true) this._onChangeCallback(); return this; } setFromQuaternion(q, order, update) { _matrix$1.makeRotationFromQuaternion(q); return this.setFromRotationMatrix(_matrix$1, order, update); } setFromVector3(v, order = this._order) { return this.set(v.x, v.y, v.z, order); } reorder(newOrder) { _quaternion$3.setFromEuler(this); return this.setFromQuaternion(_quaternion$3, newOrder); } equals(euler) { return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order; } fromArray(array) { this._x = array[0]; this._y = array[1]; this._z = array[2]; if (array[3] !== void 0) this._order = array[3]; this._onChangeCallback(); return this; } toArray(array = [], offset = 0) { array[offset] = this._x; array[offset + 1] = this._y; array[offset + 2] = this._z; array[offset + 3] = this._order; return array; } toVector3(optionalResult) { if (optionalResult) { return optionalResult.set(this._x, this._y, this._z); } else { return new Vector3(this._x, this._y, this._z); } } _onChange(callback) { this._onChangeCallback = callback; return this; } _onChangeCallback() { } }; Euler.prototype.isEuler = true; Euler.DefaultOrder = "XYZ"; Euler.RotationOrders = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"]; var Layers = class { constructor() { this.mask = 1 | 0; } set(channel) { this.mask = 1 << channel | 0; } enable(channel) { this.mask |= 1 << channel | 0; } enableAll() { this.mask = 4294967295 | 0; } toggle(channel) { this.mask ^= 1 << channel | 0; } disable(channel) { this.mask &= ~(1 << channel | 0); } disableAll() { this.mask = 0; } test(layers) { return (this.mask & layers.mask) !== 0; } }; var _object3DId = 0; var _v1$4 = /* @__PURE__ */ new Vector3(); var _q1 = /* @__PURE__ */ new Quaternion(); var _m1$1 = /* @__PURE__ */ new Matrix4(); var _target = /* @__PURE__ */ new Vector3(); var _position$3 = /* @__PURE__ */ new Vector3(); var _scale$2 = /* @__PURE__ */ new Vector3(); var _quaternion$2 = /* @__PURE__ */ new Quaternion(); var _xAxis = /* @__PURE__ */ new Vector3(1, 0, 0); var _yAxis = /* @__PURE__ */ new Vector3(0, 1, 0); var _zAxis = /* @__PURE__ */ new Vector3(0, 0, 1); var _addedEvent = { type: "added" }; var _removedEvent = { type: "removed" }; var Object3D = class extends EventDispatcher { constructor() { super(); Object.defineProperty(this, "id", { value: _object3DId++ }); this.uuid = generateUUID(); this.name = ""; this.type = "Object3D"; this.parent = null; this.children = []; this.up = Object3D.DefaultUp.clone(); const position = new Vector3(); const rotation = new Euler(); const quaternion = new Quaternion(); const scale = new Vector3(1, 1, 1); function onRotationChange() { quaternion.setFromEuler(rotation, false); } function onQuaternionChange() { rotation.setFromQuaternion(quaternion, void 0, 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.animations = []; this.userData = {}; } onBeforeRender() { } onAfterRender() { } applyMatrix4(matrix) { if (this.matrixAutoUpdate) this.updateMatrix(); this.matrix.premultiply(matrix); this.matrix.decompose(this.position, this.quaternion, this.scale); } applyQuaternion(q) { this.quaternion.premultiply(q); return this; } setRotationFromAxisAngle(axis, angle) { this.quaternion.setFromAxisAngle(axis, angle); } setRotationFromEuler(euler) { this.quaternion.setFromEuler(euler, true); } setRotationFromMatrix(m) { this.quaternion.setFromRotationMatrix(m); } setRotationFromQuaternion(q) { this.quaternion.copy(q); } rotateOnAxis(axis, angle) { _q1.setFromAxisAngle(axis, angle); this.quaternion.multiply(_q1); return this; } rotateOnWorldAxis(axis, angle) { _q1.setFromAxisAngle(axis, angle); this.quaternion.premultiply(_q1); return this; } rotateX(angle) { return this.rotateOnAxis(_xAxis, angle); } rotateY(angle) { return this.rotateOnAxis(_yAxis, angle); } rotateZ(angle) { return this.rotateOnAxis(_zAxis, angle); } translateOnAxis(axis, distance) { _v1$4.copy(axis).applyQuaternion(this.quaternion); this.position.add(_v1$4.multiplyScalar(distance)); return this; } translateX(distance) { return this.translateOnAxis(_xAxis, distance); } translateY(distance) { return this.translateOnAxis(_yAxis, distance); } translateZ(distance) { return this.translateOnAxis(_zAxis, distance); } localToWorld(vector) { return vector.applyMatrix4(this.matrixWorld); } worldToLocal(vector) { return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert()); } lookAt(x, y, z) { if (x.isVector3) { _target.copy(x); } else { _target.set(x, y, z); } const parent = this.parent; this.updateWorldMatrix(true, false); _position$3.setFromMatrixPosition(this.matrixWorld); if (this.isCamera || this.isLight) { _m1$1.lookAt(_position$3, _target, this.up); } else { _m1$1.lookAt(_target, _position$3, this.up); } this.quaternion.setFromRotationMatrix(_m1$1); if (parent) { _m1$1.extractRotation(parent.matrixWorld); _q1.setFromRotationMatrix(_m1$1); this.quaternion.premultiply(_q1.invert()); } } add(object) { if (arguments.length > 1) { for (let 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(object) { if (arguments.length > 1) { for (let i = 0; i < arguments.length; i++) { this.remove(arguments[i]); } return this; } const index = this.children.indexOf(object); if (index !== -1) { object.parent = null; this.children.splice(index, 1); object.dispatchEvent(_removedEvent); } return this; } removeFromParent() { const parent = this.parent; if (parent !== null) { parent.remove(this); } return this; } clear() { for (let i = 0; i < this.children.length; i++) { const object = this.children[i]; object.parent = null; object.dispatchEvent(_removedEvent); } this.children.length = 0; return this; } attach(object) { this.updateWorldMatrix(true, false); _m1$1.copy(this.matrixWorld).invert(); if (object.parent !== null) { object.parent.updateWorldMatrix(true, false); _m1$1.multiply(object.parent.matrixWorld); } object.applyMatrix4(_m1$1); this.add(object); object.updateWorldMatrix(false, true); return this; } getObjectById(id) { return this.getObjectByProperty("id", id); } getObjectByName(name) { return this.getObjectByProperty("name", name); } getObjectByProperty(name, value) { if (this[name] === value) return this; for (let i = 0, l = this.children.length; i < l; i++) { const child = this.children[i]; const object = child.getObjectByProperty(name, value); if (object !== void 0) { return object; } } return void 0; } getWorldPosition(target) { this.updateWorldMatrix(true, false); return target.setFromMatrixPosition(this.matrixWorld); } getWorldQuaternion(target) { this.updateWorldMatrix(true, false); this.matrixWorld.decompose(_position$3, target, _scale$2); return target; } getWorldScale(target) { this.updateWorldMatrix(true, false); this.matrixWorld.decompose(_position$3, _quaternion$2, target); return target; } getWorldDirection(target) { this.updateWorldMatrix(true, false); const e = this.matrixWorld.elements; return target.set(e[8], e[9], e[10]).normalize(); } raycast() { } traverse(callback) { callback(this); const children = this.children; for (let i = 0, l = children.length; i < l; i++) { children[i].traverse(callback); } } traverseVisible(callback) { if (this.visible === false) return; callback(this); const children = this.children; for (let i = 0, l = children.length; i < l; i++) { children[i].traverseVisible(callback); } } traverseAncestors(callback) { const parent = this.parent; if (parent !== null) { callback(parent); parent.traverseAncestors(callback); } } updateMatrix() { this.matrix.compose(this.position, this.quaternion, this.scale); this.matrixWorldNeedsUpdate = true; } updateMatrixWorld(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; } const children = this.children; for (let i = 0, l = children.length; i < l; i++) { children[i].updateMatrixWorld(force); } } updateWorldMatrix(updateParents, updateChildren) { const 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); } if (updateChildren === true) { const children = this.children; for (let i = 0, l = children.length; i < l; i++) { children[i].updateWorldMatrix(false, true); } } } toJSON(meta) { const isRootObject = meta === void 0 || typeof meta === "string"; const output = {}; if (isRootObject) { meta = { geometries: {}, materials: {}, textures: {}, images: {}, shapes: {}, skeletons: {}, animations: {} }; output.metadata = { version: 4.5, type: "Object", generator: "Object3D.toJSON" }; } const 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; if (this.isInstancedMesh) { object.type = "InstancedMesh"; object.count = this.count; object.instanceMatrix = this.instanceMatrix.toJSON(); if (this.instanceColor !== null) object.instanceColor = this.instanceColor.toJSON(); } function serialize(library2, element) { if (library2[element.uuid] === void 0) { library2[element.uuid] = element.toJSON(meta); } return element.uuid; } if (this.isScene) { if (this.background) { if (this.background.isColor) { object.background = this.background.toJSON(); } else if (this.background.isTexture) { object.background = this.background.toJSON(meta).uuid; } } if (this.environment && this.environment.isTexture) { object.environment = this.environment.toJSON(meta).uuid; } } else if (this.isMesh || this.isLine || this.isPoints) { object.geometry = serialize(meta.geometries, this.geometry); const parameters = this.geometry.parameters; if (parameters !== void 0 && parameters.shapes !== void 0) { const shapes = parameters.shapes; if (Array.isArray(shapes)) { for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; serialize(meta.shapes, shape); } } else { serialize(meta.shapes, shapes); } } } if (this.isSkinnedMesh) { object.bindMode = this.bindMode; object.bindMatrix = this.bindMatrix.toArray(); if (this.skeleton !== void 0) { serialize(meta.skeletons, this.skeleton); object.skeleton = this.skeleton.uuid; } } if (this.material !== void 0) { if (Array.isArray(this.material)) { const uuids = []; for (let 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 (let i = 0; i < this.children.length; i++) { object.children.push(this.children[i].toJSON(meta).object); } } if (this.animations.length > 0) { object.animations = []; for (let i = 0; i < this.animations.length; i++) { const animation = this.animations[i]; object.animations.push(serialize(meta.animations, animation)); } } if (isRootObject) { const geometries = extractFromCache(meta.geometries); const materials = extractFromCache(meta.materials); const textures = extractFromCache(meta.textures); const images = extractFromCache(meta.images); const shapes = extractFromCache(meta.shapes); const skeletons = extractFromCache(meta.skeletons); const animations = extractFromCache(meta.animations); 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; if (skeletons.length > 0) output.skeletons = skeletons; if (animations.length > 0) output.animations = animations; } output.object = object; return output; function extractFromCache(cache) { const values = []; for (const key in cache) { const data = cache[key]; delete data.metadata; values.push(data); } return values; } } clone(recursive) { return new this.constructor().copy(this, recursive); } copy(source, recursive = true) { this.name = source.name; this.up.copy(source.up); this.position.copy(source.position); this.rotation.order = source.rotation.order; 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 (let i = 0; i < source.children.length; i++) { const child = source.children[i]; this.add(child.clone()); } } return this; } }; Object3D.DefaultUp = new Vector3(0, 1, 0); Object3D.DefaultMatrixAutoUpdate = true; Object3D.prototype.isObject3D = true; var _v0$1 = /* @__PURE__ */ new Vector3(); var _v1$3 = /* @__PURE__ */ new Vector3(); var _v2$2 = /* @__PURE__ */ new Vector3(); var _v3$1 = /* @__PURE__ */ new Vector3(); var _vab = /* @__PURE__ */ new Vector3(); var _vac = /* @__PURE__ */ new Vector3(); var _vbc = /* @__PURE__ */ new Vector3(); var _vap = /* @__PURE__ */ new Vector3(); var _vbp = /* @__PURE__ */ new Vector3(); var _vcp = /* @__PURE__ */ new Vector3(); var Triangle = class { constructor(a2 = new Vector3(), b2 = new Vector3(), c2 = new Vector3()) { this.a = a2; this.b = b2; this.c = c2; } static getNormal(a2, b2, c2, target) { target.subVectors(c2, b2); _v0$1.subVectors(a2, b2); target.cross(_v0$1); const targetLengthSq = target.lengthSq(); if (targetLengthSq > 0) { return target.multiplyScalar(1 / Math.sqrt(targetLengthSq)); } return target.set(0, 0, 0); } static getBarycoord(point, a2, b2, c2, target) { _v0$1.subVectors(c2, a2); _v1$3.subVectors(b2, a2); _v2$2.subVectors(point, a2); const dot00 = _v0$1.dot(_v0$1); const dot01 = _v0$1.dot(_v1$3); const dot02 = _v0$1.dot(_v2$2); const dot11 = _v1$3.dot(_v1$3); const dot12 = _v1$3.dot(_v2$2); const denom = dot00 * dot11 - dot01 * dot01; if (denom === 0) { return target.set(-2, -1, -1); } const invDenom = 1 / denom; const u = (dot11 * dot02 - dot01 * dot12) * invDenom; const v = (dot00 * dot12 - dot01 * dot02) * invDenom; return target.set(1 - u - v, v, u); } static containsPoint(point, a2, b2, c2) { this.getBarycoord(point, a2, b2, c2, _v3$1); return _v3$1.x >= 0 && _v3$1.y >= 0 && _v3$1.x + _v3$1.y <= 1; } static getUV(point, p1, p2, p3, uv1, uv2, uv3, target) { this.getBarycoord(point, p1, p2, p3, _v3$1); target.set(0, 0); target.addScaledVector(uv1, _v3$1.x); target.addScaledVector(uv2, _v3$1.y); target.addScaledVector(uv3, _v3$1.z); return target; } static isFrontFacing(a2, b2, c2, direction) { _v0$1.subVectors(c2, b2); _v1$3.subVectors(a2, b2); return _v0$1.cross(_v1$3).dot(direction) < 0 ? true : false; } set(a2, b2, c2) { this.a.copy(a2); this.b.copy(b2); this.c.copy(c2); return this; } setFromPointsAndIndices(points, i0, i1, i2) { this.a.copy(points[i0]); this.b.copy(points[i1]); this.c.copy(points[i2]); return this; } clone() { return new this.constructor().copy(this); } copy(triangle) { this.a.copy(triangle.a); this.b.copy(triangle.b); this.c.copy(triangle.c); return this; } getArea() { _v0$1.subVectors(this.c, this.b); _v1$3.subVectors(this.a, this.b); return _v0$1.cross(_v1$3).length() * 0.5; } getMidpoint(target) { return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3); } getNormal(target) { return Triangle.getNormal(this.a, this.b, this.c, target); } getPlane(target) { return target.setFromCoplanarPoints(this.a, this.b, this.c); } getBarycoord(point, target) { return Triangle.getBarycoord(point, this.a, this.b, this.c, target); } getUV(point, uv1, uv2, uv3, target) { return Triangle.getUV(point, this.a, this.b, this.c, uv1, uv2, uv3, target); } containsPoint(point) { return Triangle.containsPoint(point, this.a, this.b, this.c); } isFrontFacing(direction) { return Triangle.isFrontFacing(this.a, this.b, this.c, direction); } intersectsBox(box) { return box.intersectsTriangle(this); } closestPointToPoint(p2, target) { const a2 = this.a, b2 = this.b, c2 = this.c; let v, w2; _vab.subVectors(b2, a2); _vac.subVectors(c2, a2); _vap.subVectors(p2, a2); const d1 = _vab.dot(_vap); const d2 = _vac.dot(_vap); if (d1 <= 0 && d2 <= 0) { return target.copy(a2); } _vbp.subVectors(p2, b2); const d3 = _vab.dot(_vbp); const d4 = _vac.dot(_vbp); if (d3 >= 0 && d4 <= d3) { return target.copy(b2); } const vc2 = d1 * d4 - d3 * d2; if (vc2 <= 0 && d1 >= 0 && d3 <= 0) { v = d1 / (d1 - d3); return target.copy(a2).addScaledVector(_vab, v); } _vcp.subVectors(p2, c2); const d5 = _vab.dot(_vcp); const d6 = _vac.dot(_vcp); if (d6 >= 0 && d5 <= d6) { return target.copy(c2); } const vb2 = d5 * d2 - d1 * d6; if (vb2 <= 0 && d2 >= 0 && d6 <= 0) { w2 = d2 / (d2 - d6); return target.copy(a2).addScaledVector(_vac, w2); } const va2 = d3 * d6 - d5 * d4; if (va2 <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) { _vbc.subVectors(c2, b2); w2 = (d4 - d3) / (d4 - d3 + (d5 - d6)); return target.copy(b2).addScaledVector(_vbc, w2); } const denom = 1 / (va2 + vb2 + vc2); v = vb2 * denom; w2 = vc2 * denom; return target.copy(a2).addScaledVector(_vab, v).addScaledVector(_vac, w2); } equals(triangle) { return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c); } }; var materialId = 0; var Material = class extends EventDispatcher { constructor() { super(); Object.defineProperty(this, "id", { value: materialId++ }); this.uuid = generateUUID(); this.name = ""; this.type = "Material"; this.fog = true; this.blending = NormalBlending; this.side = FrontSide; this.vertexColors = false; this.opacity = 1; this.format = RGBAFormat; 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 = 255; this.stencilFunc = AlwaysStencilFunc; this.stencilRef = 0; this.stencilFuncMask = 255; 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; this.polygonOffset = false; this.polygonOffsetFactor = 0; this.polygonOffsetUnits = 0; this.dithering = false; this.alphaToCoverage = false; this.premultipliedAlpha = false; this.visible = true; this.toneMapped = true; this.userData = {}; this.version = 0; this._alphaTest = 0; } get alphaTest() { return this._alphaTest; } set alphaTest(value) { if (this._alphaTest > 0 !== value > 0) { this.version++; } this._alphaTest = value; } onBuild() { } onBeforeCompile() { } customProgramCacheKey() { return this.onBeforeCompile.toString(); } setValues(values) { if (values === void 0) return; for (const key in values) { const newValue = values[key]; if (newValue === void 0) { console.warn("THREE.Material: '" + key + "' parameter is undefined."); continue; } if (key === "shading") { console.warn("THREE." + this.type + ": .shading has been removed. Use the boolean .flatShading instead."); this.flatShading = newValue === FlatShading ? true : false; continue; } const currentValue = this[key]; if (currentValue === void 0) { 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(meta) { const isRoot = meta === void 0 || typeof meta === "string"; if (isRoot) { meta = { textures: {}, images: {} }; } const data = { metadata: { version: 4.5, type: "Material", generator: "Material.toJSON" } }; 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 !== void 0) data.roughness = this.roughness; if (this.metalness !== void 0) data.metalness = this.metalness; if (this.sheenTint && this.sheenTint.isColor) data.sheenTint = this.sheenTint.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.specularIntensity !== void 0) data.specularIntensity = this.specularIntensity; if (this.specularTint && this.specularTint.isColor) data.specularTint = this.specularTint.getHex(); if (this.shininess !== void 0) data.shininess = this.shininess; if (this.clearcoat !== void 0) data.clearcoat = this.clearcoat; if (this.clearcoatRoughness !== void 0) 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; data.lightMapIntensity = this.lightMapIntensity; } 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.specularIntensityMap && this.specularIntensityMap.isTexture) data.specularIntensityMap = this.specularIntensityMap.toJSON(meta).uuid; if (this.specularTintMap && this.specularTintMap.isTexture) data.specularTintMap = this.specularTintMap.toJSON(meta).uuid; if (this.envMap && this.envMap.isTexture) { data.envMap = this.envMap.toJSON(meta).uuid; if (this.combine !== void 0) data.combine = this.combine; } if (this.envMapIntensity !== void 0) data.envMapIntensity = this.envMapIntensity; if (this.reflectivity !== void 0) data.reflectivity = this.reflectivity; if (this.refractionRatio !== void 0) data.refractionRatio = this.refractionRatio; if (this.gradientMap && this.gradientMap.isTexture) { data.gradientMap = this.gradientMap.toJSON(meta).uuid; } if (this.transmission !== void 0) data.transmission = this.transmission; if (this.transmissionMap && this.transmissionMap.isTexture) data.transmissionMap = this.transmissionMap.toJSON(meta).uuid; if (this.thickness !== void 0) data.thickness = this.thickness; if (this.thicknessMap && this.thicknessMap.isTexture) data.thicknessMap = this.thicknessMap.toJSON(meta).uuid; if (this.attenuationDistance !== void 0) data.attenuationDistance = this.attenuationDistance; if (this.attenuationTint !== void 0) data.attenuationTint = this.attenuationTint.getHex(); if (this.size !== void 0) data.size = this.size; if (this.shadowSide !== null) data.shadowSide = this.shadowSide; if (this.sizeAttenuation !== void 0) data.sizeAttenuation = this.sizeAttenuation; if (this.blending !== NormalBlending) data.blending = this.blending; if (this.side !== FrontSide) data.side = this.side; if (this.vertexColors) data.vertexColors = true; if (this.opacity < 1) data.opacity = this.opacity; if (this.format !== RGBAFormat) data.format = this.format; if (this.transparent === true) data.transparent = this.transparent; data.depthFunc = this.depthFunc; data.depthTest = this.depthTest; data.depthWrite = this.depthWrite; data.colorWrite = this.colorWrite; 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; 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 !== void 0) data.dashSize = this.dashSize; if (this.gapSize !== void 0) data.gapSize = this.gapSize; if (this.scale !== void 0) data.scale = this.scale; if (this.dithering === true) data.dithering = true; if (this.alphaTest > 0) data.alphaTest = this.alphaTest; if (this.alphaToCoverage === true) data.alphaToCoverage = this.alphaToCoverage; 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.flatShading === true) data.flatShading = this.flatShading; if (this.visible === false) data.visible = false; if (this.toneMapped === false) data.toneMapped = false; if (JSON.stringify(this.userData) !== "{}") data.userData = this.userData; function extractFromCache(cache) { const values = []; for (const key in cache) { const data2 = cache[key]; delete data2.metadata; values.push(data2); } return values; } if (isRoot) { const textures = extractFromCache(meta.textures); const images = extractFromCache(meta.images); if (textures.length > 0) data.textures = textures; if (images.length > 0) data.images = images; } return data; } clone() { return new this.constructor().copy(this); } copy(source) { this.name = source.name; this.fog = source.fog; this.blending = source.blending; this.side = source.side; this.vertexColors = source.vertexColors; this.opacity = source.opacity; this.format = source.format; 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; const srcPlanes = source.clippingPlanes; let dstPlanes = null; if (srcPlanes !== null) { const n = srcPlanes.length; dstPlanes = new Array(n); for (let 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.alphaToCoverage = source.alphaToCoverage; this.premultipliedAlpha = source.premultipliedAlpha; this.visible = source.visible; this.toneMapped = source.toneMapped; this.userData = JSON.parse(JSON.stringify(source.userData)); return this; } dispose() { this.dispatchEvent({ type: "dispose" }); } set needsUpdate(value) { if (value === true) this.version++; } }; Material.prototype.isMaterial = true; var _colorKeywords = { "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 }; var _hslA = { h: 0, s: 0, l: 0 }; var _hslB = { h: 0, s: 0, l: 0 }; function hue2rgb(p2, q, t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p2 + (q - p2) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p2 + (q - p2) * 6 * (2 / 3 - t); return p2; } function SRGBToLinear(c2) { return c2 < 0.04045 ? c2 * 0.0773993808 : Math.pow(c2 * 0.9478672986 + 0.0521327014, 2.4); } function LinearToSRGB(c2) { return c2 < 31308e-7 ? c2 * 12.92 : 1.055 * Math.pow(c2, 0.41666) - 0.055; } var Color = class { constructor(r, g, b2) { if (g === void 0 && b2 === void 0) { return this.set(r); } return this.setRGB(r, g, b2); } set(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(scalar) { this.r = scalar; this.g = scalar; this.b = scalar; return this; } setHex(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(r, g, b2) { this.r = r; this.g = g; this.b = b2; return this; } setHSL(h, s, l) { h = euclideanModulo(h, 1); s = clamp(s, 0, 1); l = clamp(l, 0, 1); if (s === 0) { this.r = this.g = this.b = l; } else { const p2 = l <= 0.5 ? l * (1 + s) : l + s - l * s; const q = 2 * l - p2; this.r = hue2rgb(q, p2, h + 1 / 3); this.g = hue2rgb(q, p2, h); this.b = hue2rgb(q, p2, h - 1 / 3); } return this; } setStyle(style) { function handleAlpha(string) { if (string === void 0) return; if (parseFloat(string) < 1) { console.warn("THREE.Color: Alpha component of " + style + " will be ignored."); } } let m; if (m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(style)) { let color; const name = m[1]; const components = m[2]; switch (name) { case "rgb": case "rgba": if (color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { 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[4]); return this; } if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { 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[4]); return this; } break; case "hsl": case "hsla": if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { const h = parseFloat(color[1]) / 360; const s = parseInt(color[2], 10) / 100; const l = parseInt(color[3], 10) / 100; handleAlpha(color[4]); return this.setHSL(h, s, l); } break; } } else if (m = /^\#([A-Fa-f\d]+)$/.exec(style)) { const hex = m[1]; const size = hex.length; if (size === 3) { 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) { 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(style) { const hex = _colorKeywords[style.toLowerCase()]; if (hex !== void 0) { this.setHex(hex); } else { console.warn("THREE.Color: Unknown color " + style); } return this; } clone() { return new this.constructor(this.r, this.g, this.b); } copy(color) { this.r = color.r; this.g = color.g; this.b = color.b; return this; } copyGammaToLinear(color, gammaFactor = 2) { this.r = Math.pow(color.r, gammaFactor); this.g = Math.pow(color.g, gammaFactor); this.b = Math.pow(color.b, gammaFactor); return this; } copyLinearToGamma(color, gammaFactor = 2) { const safeInverse = gammaFactor > 0 ? 1 / gammaFactor : 1; this.r = Math.pow(color.r, safeInverse); this.g = Math.pow(color.g, safeInverse); this.b = Math.pow(color.b, safeInverse); return this; } convertGammaToLinear(gammaFactor) { this.copyGammaToLinear(this, gammaFactor); return this; } convertLinearToGamma(gammaFactor) { this.copyLinearToGamma(this, gammaFactor); return this; } copySRGBToLinear(color) { this.r = SRGBToLinear(color.r); this.g = SRGBToLinear(color.g); this.b = SRGBToLinear(color.b); return this; } copyLinearToSRGB(color) { this.r = LinearToSRGB(color.r); this.g = LinearToSRGB(color.g); this.b = LinearToSRGB(color.b); return this; } convertSRGBToLinear() { this.copySRGBToLinear(this); return this; } convertLinearToSRGB() { this.copyLinearToSRGB(this); return this; } getHex() { return this.r * 255 << 16 ^ this.g * 255 << 8 ^ this.b * 255 << 0; } getHexString() { return ("000000" + this.getHex().toString(16)).slice(-6); } getHSL(target) { const r = this.r, g = this.g, b2 = this.b; const max = Math.max(r, g, b2); const min = Math.min(r, g, b2); let hue, saturation; const lightness = (min + max) / 2; if (min === max) { hue = 0; saturation = 0; } else { const delta = max - min; saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min); switch (max) { case r: hue = (g - b2) / delta + (g < b2 ? 6 : 0); break; case g: hue = (b2 - r) / delta + 2; break; case b2: hue = (r - g) / delta + 4; break; } hue /= 6; } target.h = hue; target.s = saturation; target.l = lightness; return target; } getStyle() { return "rgb(" + (this.r * 255 | 0) + "," + (this.g * 255 | 0) + "," + (this.b * 255 | 0) + ")"; } offsetHSL(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(color) { this.r += color.r; this.g += color.g; this.b += color.b; return this; } addColors(color1, color2) { this.r = color1.r + color2.r; this.g = color1.g + color2.g; this.b = color1.b + color2.b; return this; } addScalar(s) { this.r += s; this.g += s; this.b += s; return this; } sub(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(color) { this.r *= color.r; this.g *= color.g; this.b *= color.b; return this; } multiplyScalar(s) { this.r *= s; this.g *= s; this.b *= s; return this; } lerp(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; } lerpColors(color1, color2, alpha) { this.r = color1.r + (color2.r - color1.r) * alpha; this.g = color1.g + (color2.g - color1.g) * alpha; this.b = color1.b + (color2.b - color1.b) * alpha; return this; } lerpHSL(color, alpha) { this.getHSL(_hslA); color.getHSL(_hslB); const h = lerp(_hslA.h, _hslB.h, alpha); const s = lerp(_hslA.s, _hslB.s, alpha); const l = lerp(_hslA.l, _hslB.l, alpha); this.setHSL(h, s, l); return this; } equals(c2) { return c2.r === this.r && c2.g === this.g && c2.b === this.b; } fromArray(array, offset = 0) { this.r = array[offset]; this.g = array[offset + 1]; this.b = array[offset + 2]; return this; } toArray(array = [], offset = 0) { array[offset] = this.r; array[offset + 1] = this.g; array[offset + 2] = this.b; return array; } fromBufferAttribute(attribute, index) { this.r = attribute.getX(index); this.g = attribute.getY(index); this.b = attribute.getZ(index); if (attribute.normalized === true) { this.r /= 255; this.g /= 255; this.b /= 255; } return this; } toJSON() { return this.getHex(); } }; Color.NAMES = _colorKeywords; Color.prototype.isColor = true; Color.prototype.r = 1; Color.prototype.g = 1; Color.prototype.b = 1; var MeshBasicMaterial = class extends Material { constructor(parameters) { super(); this.type = "MeshBasicMaterial"; this.color = new Color(16777215); this.map = null; this.lightMap = null; this.lightMapIntensity = 1; this.aoMap = null; this.aoMapIntensity = 1; 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.setValues(parameters); } copy(source) { super.copy(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; return this; } }; MeshBasicMaterial.prototype.isMeshBasicMaterial = true; var _vector$9 = /* @__PURE__ */ new Vector3(); var _vector2$1 = /* @__PURE__ */ new Vector2(); var BufferAttribute = class { constructor(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 !== void 0 ? array.length / itemSize : 0; this.normalized = normalized === true; this.usage = StaticDrawUsage; this.updateRange = { offset: 0, count: -1 }; this.version = 0; } onUploadCallback() { } set needsUpdate(value) { if (value === true) this.version++; } setUsage(value) { this.usage = value; return this; } copy(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(index1, attribute, index2) { index1 *= this.itemSize; index2 *= attribute.itemSize; for (let i = 0, l = this.itemSize; i < l; i++) { this.array[index1 + i] = attribute.array[index2 + i]; } return this; } copyArray(array) { this.array.set(array); return this; } copyColorsArray(colors) { const array = this.array; let offset = 0; for (let i = 0, l = colors.length; i < l; i++) { let color = colors[i]; if (color === void 0) { 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(vectors) { const array = this.array; let offset = 0; for (let i = 0, l = vectors.length; i < l; i++) { let vector = vectors[i]; if (vector === void 0) { console.warn("THREE.BufferAttribute.copyVector2sArray(): vector is undefined", i); vector = new Vector2(); } array[offset++] = vector.x; array[offset++] = vector.y; } return this; } copyVector3sArray(vectors) { const array = this.array; let offset = 0; for (let i = 0, l = vectors.length; i < l; i++) { let vector = vectors[i]; if (vector === void 0) { 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(vectors) { const array = this.array; let offset = 0; for (let i = 0, l = vectors.length; i < l; i++) { let vector = vectors[i]; if (vector === void 0) { 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(m) { if (this.itemSize === 2) { for (let i = 0, l = this.count; i < l; i++) { _vector2$1.fromBufferAttribute(this, i); _vector2$1.applyMatrix3(m); this.setXY(i, _vector2$1.x, _vector2$1.y); } } else if (this.itemSize === 3) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); _vector$9.applyMatrix3(m); this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } } return this; } applyMatrix4(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.x = this.getX(i); _vector$9.y = this.getY(i); _vector$9.z = this.getZ(i); _vector$9.applyMatrix4(m); this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } return this; } applyNormalMatrix(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.x = this.getX(i); _vector$9.y = this.getY(i); _vector$9.z = this.getZ(i); _vector$9.applyNormalMatrix(m); this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } return this; } transformDirection(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.x = this.getX(i); _vector$9.y = this.getY(i); _vector$9.z = this.getZ(i); _vector$9.transformDirection(m); this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } return this; } set(value, offset = 0) { this.array.set(value, offset); return this; } getX(index) { return this.array[index * this.itemSize]; } setX(index, x) { this.array[index * this.itemSize] = x; return this; } getY(index) { return this.array[index * this.itemSize + 1]; } setY(index, y) { this.array[index * this.itemSize + 1] = y; return this; } getZ(index) { return this.array[index * this.itemSize + 2]; } setZ(index, z) { this.array[index * this.itemSize + 2] = z; return this; } getW(index) { return this.array[index * this.itemSize + 3]; } setW(index, w2) { this.array[index * this.itemSize + 3] = w2; return this; } setXY(index, x, y) { index *= this.itemSize; this.array[index + 0] = x; this.array[index + 1] = y; return this; } setXYZ(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(index, x, y, z, w2) { index *= this.itemSize; this.array[index + 0] = x; this.array[index + 1] = y; this.array[index + 2] = z; this.array[index + 3] = w2; return this; } onUpload(callback) { this.onUploadCallback = callback; return this; } clone() { return new this.constructor(this.array, this.itemSize).copy(this); } toJSON() { const data = { itemSize: this.itemSize, type: this.array.constructor.name, array: Array.prototype.slice.call(this.array), normalized: this.normalized }; if (this.name !== "") data.name = this.name; if (this.usage !== StaticDrawUsage) data.usage = this.usage; if (this.updateRange.offset !== 0 || this.updateRange.count !== -1) data.updateRange = this.updateRange; return data; } }; BufferAttribute.prototype.isBufferAttribute = true; var Uint16BufferAttribute = class extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint16Array(array), itemSize, normalized); } }; var Uint32BufferAttribute = class extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint32Array(array), itemSize, normalized); } }; var Float16BufferAttribute = class extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Uint16Array(array), itemSize, normalized); } }; Float16BufferAttribute.prototype.isFloat16BufferAttribute = true; var Float32BufferAttribute = class extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Float32Array(array), itemSize, normalized); } }; function arrayMax(array) { if (array.length === 0) return -Infinity; let max = array[0]; for (let i = 1, l = array.length; i < l; ++i) { if (array[i] > max) max = array[i]; } return max; } var _id = 0; var _m1 = /* @__PURE__ */ new Matrix4(); var _obj = /* @__PURE__ */ new Object3D(); var _offset = /* @__PURE__ */ new Vector3(); var _box$1 = /* @__PURE__ */ new Box3(); var _boxMorphTargets = /* @__PURE__ */ new Box3(); var _vector$8 = /* @__PURE__ */ new Vector3(); var BufferGeometry = class extends EventDispatcher { constructor() { super(); Object.defineProperty(this, "id", { value: _id++ }); this.uuid = 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 = {}; } getIndex() { return this.index; } setIndex(index) { if (Array.isArray(index)) { this.index = new (arrayMax(index) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1); } else { this.index = index; } return this; } getAttribute(name) { return this.attributes[name]; } setAttribute(name, attribute) { this.attributes[name] = attribute; return this; } deleteAttribute(name) { delete this.attributes[name]; return this; } hasAttribute(name) { return this.attributes[name] !== void 0; } addGroup(start, count, materialIndex = 0) { this.groups.push({ start, count, materialIndex }); } clearGroups() { this.groups = []; } setDrawRange(start, count) { this.drawRange.start = start; this.drawRange.count = count; } applyMatrix4(matrix) { const position = this.attributes.position; if (position !== void 0) { position.applyMatrix4(matrix); position.needsUpdate = true; } const normal = this.attributes.normal; if (normal !== void 0) { const normalMatrix = new Matrix3().getNormalMatrix(matrix); normal.applyNormalMatrix(normalMatrix); normal.needsUpdate = true; } const tangent = this.attributes.tangent; if (tangent !== void 0) { tangent.transformDirection(matrix); tangent.needsUpdate = true; } if (this.boundingBox !== null) { this.computeBoundingBox(); } if (this.boundingSphere !== null) { this.computeBoundingSphere(); } return this; } applyQuaternion(q) { _m1.makeRotationFromQuaternion(q); this.applyMatrix4(_m1); return this; } rotateX(angle) { _m1.makeRotationX(angle); this.applyMatrix4(_m1); return this; } rotateY(angle) { _m1.makeRotationY(angle); this.applyMatrix4(_m1); return this; } rotateZ(angle) { _m1.makeRotationZ(angle); this.applyMatrix4(_m1); return this; } translate(x, y, z) { _m1.makeTranslation(x, y, z); this.applyMatrix4(_m1); return this; } scale(x, y, z) { _m1.makeScale(x, y, z); this.applyMatrix4(_m1); return this; } lookAt(vector) { _obj.lookAt(vector); _obj.updateMatrix(); this.applyMatrix4(_obj.matrix); return this; } center() { this.computeBoundingBox(); this.boundingBox.getCenter(_offset).negate(); this.translate(_offset.x, _offset.y, _offset.z); return this; } setFromPoints(points) { const position = []; for (let i = 0, l = points.length; i < l; i++) { const point = points[i]; position.push(point.x, point.y, point.z || 0); } this.setAttribute("position", new Float32BufferAttribute(position, 3)); return this; } computeBoundingBox() { if (this.boundingBox === null) { this.boundingBox = new Box3(); } const position = this.attributes.position; const morphAttributesPosition = this.morphAttributes.position; if (position && position.isGLBufferAttribute) { console.error('THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set "mesh.frustumCulled" to "false".', this); this.boundingBox.set(new Vector3(-Infinity, -Infinity, -Infinity), new Vector3(Infinity, Infinity, Infinity)); return; } if (position !== void 0) { this.boundingBox.setFromBufferAttribute(position); if (morphAttributesPosition) { for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { const morphAttribute = morphAttributesPosition[i]; _box$1.setFromBufferAttribute(morphAttribute); if (this.morphTargetsRelative) { _vector$8.addVectors(this.boundingBox.min, _box$1.min); this.boundingBox.expandByPoint(_vector$8); _vector$8.addVectors(this.boundingBox.max, _box$1.max); this.boundingBox.expandByPoint(_vector$8); } else { this.boundingBox.expandByPoint(_box$1.min); this.boundingBox.expandByPoint(_box$1.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() { if (this.boundingSphere === null) { this.boundingSphere = new Sphere(); } const position = this.attributes.position; const morphAttributesPosition = this.morphAttributes.position; if (position && position.isGLBufferAttribute) { console.error('THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set "mesh.frustumCulled" to "false".', this); this.boundingSphere.set(new Vector3(), Infinity); return; } if (position) { const center = this.boundingSphere.center; _box$1.setFromBufferAttribute(position); if (morphAttributesPosition) { for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { const morphAttribute = morphAttributesPosition[i]; _boxMorphTargets.setFromBufferAttribute(morphAttribute); if (this.morphTargetsRelative) { _vector$8.addVectors(_box$1.min, _boxMorphTargets.min); _box$1.expandByPoint(_vector$8); _vector$8.addVectors(_box$1.max, _boxMorphTargets.max); _box$1.expandByPoint(_vector$8); } else { _box$1.expandByPoint(_boxMorphTargets.min); _box$1.expandByPoint(_boxMorphTargets.max); } } } _box$1.getCenter(center); let maxRadiusSq = 0; for (let i = 0, il = position.count; i < il; i++) { _vector$8.fromBufferAttribute(position, i); maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); } if (morphAttributesPosition) { for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { const morphAttribute = morphAttributesPosition[i]; const morphTargetsRelative = this.morphTargetsRelative; for (let j = 0, jl = morphAttribute.count; j < jl; j++) { _vector$8.fromBufferAttribute(morphAttribute, j); if (morphTargetsRelative) { _offset.fromBufferAttribute(position, j); _vector$8.add(_offset); } maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8)); } } } 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); } } } computeTangents() { const index = this.index; const attributes = this.attributes; if (index === null || attributes.position === void 0 || attributes.normal === void 0 || attributes.uv === void 0) { console.error("THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)"); return; } const indices = index.array; const positions = attributes.position.array; const normals = attributes.normal.array; const uvs = attributes.uv.array; const nVertices = positions.length / 3; if (attributes.tangent === void 0) { this.setAttribute("tangent", new BufferAttribute(new Float32Array(4 * nVertices), 4)); } const tangents = attributes.tangent.array; const tan1 = [], tan2 = []; for (let i = 0; i < nVertices; i++) { tan1[i] = new Vector3(); tan2[i] = new Vector3(); } const vA = new Vector3(), vB = new Vector3(), vC = new Vector3(), uvA = new Vector2(), uvB = new Vector2(), uvC = new Vector2(), sdir = new Vector3(), tdir = new Vector3(); function handleTriangle(a2, b2, c2) { vA.fromArray(positions, a2 * 3); vB.fromArray(positions, b2 * 3); vC.fromArray(positions, c2 * 3); uvA.fromArray(uvs, a2 * 2); uvB.fromArray(uvs, b2 * 2); uvC.fromArray(uvs, c2 * 2); vB.sub(vA); vC.sub(vA); uvB.sub(uvA); uvC.sub(uvA); const r = 1 / (uvB.x * uvC.y - uvC.x * uvB.y); if (!isFinite(r)) return; sdir.copy(vB).multiplyScalar(uvC.y).addScaledVector(vC, -uvB.y).multiplyScalar(r); tdir.copy(vC).multiplyScalar(uvB.x).addScaledVector(vB, -uvC.x).multiplyScalar(r); tan1[a2].add(sdir); tan1[b2].add(sdir); tan1[c2].add(sdir); tan2[a2].add(tdir); tan2[b2].add(tdir); tan2[c2].add(tdir); } let groups = this.groups; if (groups.length === 0) { groups = [{ start: 0, count: indices.length }]; } for (let i = 0, il = groups.length; i < il; ++i) { const group = groups[i]; const start = group.start; const count = group.count; for (let j = start, jl = start + count; j < jl; j += 3) { handleTriangle(indices[j + 0], indices[j + 1], indices[j + 2]); } } const tmp3 = new Vector3(), tmp22 = new Vector3(); const n = new Vector3(), n2 = new Vector3(); function handleVertex(v) { n.fromArray(normals, v * 3); n2.copy(n); const t = tan1[v]; tmp3.copy(t); tmp3.sub(n.multiplyScalar(n.dot(t))).normalize(); tmp22.crossVectors(n2, t); const test = tmp22.dot(tan2[v]); const w2 = test < 0 ? -1 : 1; tangents[v * 4] = tmp3.x; tangents[v * 4 + 1] = tmp3.y; tangents[v * 4 + 2] = tmp3.z; tangents[v * 4 + 3] = w2; } for (let i = 0, il = groups.length; i < il; ++i) { const group = groups[i]; const start = group.start; const count = group.count; for (let j = start, jl = start + count; j < jl; j += 3) { handleVertex(indices[j + 0]); handleVertex(indices[j + 1]); handleVertex(indices[j + 2]); } } } computeVertexNormals() { const index = this.index; const positionAttribute = this.getAttribute("position"); if (positionAttribute !== void 0) { let normalAttribute = this.getAttribute("normal"); if (normalAttribute === void 0) { normalAttribute = new BufferAttribute(new Float32Array(positionAttribute.count * 3), 3); this.setAttribute("normal", normalAttribute); } else { for (let i = 0, il = normalAttribute.count; i < il; i++) { normalAttribute.setXYZ(i, 0, 0, 0); } } const pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); const nA = new Vector3(), nB = new Vector3(), nC = new Vector3(); const cb2 = new Vector3(), ab2 = new Vector3(); if (index) { for (let i = 0, il = index.count; i < il; i += 3) { const vA = index.getX(i + 0); const vB = index.getX(i + 1); const vC = index.getX(i + 2); pA.fromBufferAttribute(positionAttribute, vA); pB.fromBufferAttribute(positionAttribute, vB); pC.fromBufferAttribute(positionAttribute, vC); cb2.subVectors(pC, pB); ab2.subVectors(pA, pB); cb2.cross(ab2); nA.fromBufferAttribute(normalAttribute, vA); nB.fromBufferAttribute(normalAttribute, vB); nC.fromBufferAttribute(normalAttribute, vC); nA.add(cb2); nB.add(cb2); nC.add(cb2); normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z); normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z); normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z); } } else { for (let i = 0, il = positionAttribute.count; i < il; i += 3) { pA.fromBufferAttribute(positionAttribute, i + 0); pB.fromBufferAttribute(positionAttribute, i + 1); pC.fromBufferAttribute(positionAttribute, i + 2); cb2.subVectors(pC, pB); ab2.subVectors(pA, pB); cb2.cross(ab2); normalAttribute.setXYZ(i + 0, cb2.x, cb2.y, cb2.z); normalAttribute.setXYZ(i + 1, cb2.x, cb2.y, cb2.z); normalAttribute.setXYZ(i + 2, cb2.x, cb2.y, cb2.z); } } this.normalizeNormals(); normalAttribute.needsUpdate = true; } } merge(geometry, offset) { if (!(geometry && geometry.isBufferGeometry)) { console.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.", geometry); return; } if (offset === void 0) { offset = 0; console.warn("THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge."); } const attributes = this.attributes; for (const key in attributes) { if (geometry.attributes[key] === void 0) continue; const attribute1 = attributes[key]; const attributeArray1 = attribute1.array; const attribute2 = geometry.attributes[key]; const attributeArray2 = attribute2.array; const attributeOffset = attribute2.itemSize * offset; const length = Math.min(attributeArray2.length, attributeArray1.length - attributeOffset); for (let i = 0, j = attributeOffset; i < length; i++, j++) { attributeArray1[j] = attributeArray2[i]; } } return this; } normalizeNormals() { const normals = this.attributes.normal; for (let i = 0, il = normals.count; i < il; i++) { _vector$8.fromBufferAttribute(normals, i); _vector$8.normalize(); normals.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z); } } toNonIndexed() { function convertBufferAttribute(attribute, indices2) { const array = attribute.array; const itemSize = attribute.itemSize; const normalized = attribute.normalized; const array2 = new array.constructor(indices2.length * itemSize); let index = 0, index2 = 0; for (let i = 0, l = indices2.length; i < l; i++) { if (attribute.isInterleavedBufferAttribute) { index = indices2[i] * attribute.data.stride + attribute.offset; } else { index = indices2[i] * itemSize; } for (let j = 0; j < itemSize; j++) { array2[index2++] = array[index++]; } } return new BufferAttribute(array2, itemSize, normalized); } if (this.index === null) { console.warn("THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed."); return this; } const geometry2 = new BufferGeometry(); const indices = this.index.array; const attributes = this.attributes; for (const name in attributes) { const attribute = attributes[name]; const newAttribute = convertBufferAttribute(attribute, indices); geometry2.setAttribute(name, newAttribute); } const morphAttributes = this.morphAttributes; for (const name in morphAttributes) { const morphArray = []; const morphAttribute = morphAttributes[name]; for (let i = 0, il = morphAttribute.length; i < il; i++) { const attribute = morphAttribute[i]; const newAttribute = convertBufferAttribute(attribute, indices); morphArray.push(newAttribute); } geometry2.morphAttributes[name] = morphArray; } geometry2.morphTargetsRelative = this.morphTargetsRelative; const groups = this.groups; for (let i = 0, l = groups.length; i < l; i++) { const group = groups[i]; geometry2.addGroup(group.start, group.count, group.materialIndex); } return geometry2; } toJSON() { const data = { metadata: { version: 4.5, type: "BufferGeometry", generator: "BufferGeometry.toJSON" } }; 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 !== void 0) { const parameters = this.parameters; for (const key in parameters) { if (parameters[key] !== void 0) data[key] = parameters[key]; } return data; } data.data = { attributes: {} }; const index = this.index; if (index !== null) { data.data.index = { type: index.array.constructor.name, array: Array.prototype.slice.call(index.array) }; } const attributes = this.attributes; for (const key in attributes) { const attribute = attributes[key]; data.data.attributes[key] = attribute.toJSON(data.data); } const morphAttributes = {}; let hasMorphAttributes = false; for (const key in this.morphAttributes) { const attributeArray = this.morphAttributes[key]; const array = []; for (let i = 0, il = attributeArray.length; i < il; i++) { const attribute = attributeArray[i]; array.push(attribute.toJSON(data.data)); } if (array.length > 0) { morphAttributes[key] = array; hasMorphAttributes = true; } } if (hasMorphAttributes) { data.data.morphAttributes = morphAttributes; data.data.morphTargetsRelative = this.morphTargetsRelative; } const groups = this.groups; if (groups.length > 0) { data.data.groups = JSON.parse(JSON.stringify(groups)); } const boundingSphere = this.boundingSphere; if (boundingSphere !== null) { data.data.boundingSphere = { center: boundingSphere.center.toArray(), radius: boundingSphere.radius }; } return data; } clone() { return new BufferGeometry().copy(this); } copy(source) { this.index = null; this.attributes = {}; this.morphAttributes = {}; this.groups = []; this.boundingBox = null; this.boundingSphere = null; const data = {}; this.name = source.name; const index = source.index; if (index !== null) { this.setIndex(index.clone(data)); } const attributes = source.attributes; for (const name in attributes) { const attribute = attributes[name]; this.setAttribute(name, attribute.clone(data)); } const morphAttributes = source.morphAttributes; for (const name in morphAttributes) { const array = []; const morphAttribute = morphAttributes[name]; for (let i = 0, l = morphAttribute.length; i < l; i++) { array.push(morphAttribute[i].clone(data)); } this.morphAttributes[name] = array; } this.morphTargetsRelative = source.morphTargetsRelative; const groups = source.groups; for (let i = 0, l = groups.length; i < l; i++) { const group = groups[i]; this.addGroup(group.start, group.count, group.materialIndex); } const boundingBox = source.boundingBox; if (boundingBox !== null) { this.boundingBox = boundingBox.clone(); } const boundingSphere = source.boundingSphere; if (boundingSphere !== null) { this.boundingSphere = boundingSphere.clone(); } this.drawRange.start = source.drawRange.start; this.drawRange.count = source.drawRange.count; this.userData = source.userData; return this; } dispose() { this.dispatchEvent({ type: "dispose" }); } }; BufferGeometry.prototype.isBufferGeometry = true; var _inverseMatrix$2 = /* @__PURE__ */ new Matrix4(); var _ray$2 = /* @__PURE__ */ new Ray(); var _sphere$3 = /* @__PURE__ */ new Sphere(); var _vA$1 = /* @__PURE__ */ new Vector3(); var _vB$1 = /* @__PURE__ */ new Vector3(); var _vC$1 = /* @__PURE__ */ new Vector3(); var _tempA = /* @__PURE__ */ new Vector3(); var _tempB = /* @__PURE__ */ new Vector3(); var _tempC = /* @__PURE__ */ new Vector3(); var _morphA = /* @__PURE__ */ new Vector3(); var _morphB = /* @__PURE__ */ new Vector3(); var _morphC = /* @__PURE__ */ new Vector3(); var _uvA$1 = /* @__PURE__ */ new Vector2(); var _uvB$1 = /* @__PURE__ */ new Vector2(); var _uvC$1 = /* @__PURE__ */ new Vector2(); var _intersectionPoint = /* @__PURE__ */ new Vector3(); var _intersectionPointWorld = /* @__PURE__ */ new Vector3(); var Mesh = class extends Object3D { constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) { super(); this.type = "Mesh"; this.geometry = geometry; this.material = material; this.updateMorphTargets(); } copy(source) { super.copy(source); if (source.morphTargetInfluences !== void 0) { this.morphTargetInfluences = source.morphTargetInfluences.slice(); } if (source.morphTargetDictionary !== void 0) { this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); } this.material = source.material; this.geometry = source.geometry; return this; } updateMorphTargets() { const geometry = this.geometry; if (geometry.isBufferGeometry) { const morphAttributes = geometry.morphAttributes; const keys = Object.keys(morphAttributes); if (keys.length > 0) { const morphAttribute = morphAttributes[keys[0]]; if (morphAttribute !== void 0) { this.morphTargetInfluences = []; this.morphTargetDictionary = {}; for (let m = 0, ml = morphAttribute.length; m < ml; m++) { const name = morphAttribute[m].name || String(m); this.morphTargetInfluences.push(0); this.morphTargetDictionary[name] = m; } } } } else { const morphTargets = geometry.morphTargets; if (morphTargets !== void 0 && morphTargets.length > 0) { console.error("THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead."); } } } raycast(raycaster, intersects2) { const geometry = this.geometry; const material = this.material; const matrixWorld = this.matrixWorld; if (material === void 0) return; if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$3.copy(geometry.boundingSphere); _sphere$3.applyMatrix4(matrixWorld); if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; _inverseMatrix$2.copy(matrixWorld).invert(); _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); if (geometry.boundingBox !== null) { if (_ray$2.intersectsBox(geometry.boundingBox) === false) return; } let intersection; if (geometry.isBufferGeometry) { const index = geometry.index; const position = geometry.attributes.position; const morphPosition = geometry.morphAttributes.position; const morphTargetsRelative = geometry.morphTargetsRelative; const uv = geometry.attributes.uv; const uv2 = geometry.attributes.uv2; const groups = geometry.groups; const drawRange = geometry.drawRange; if (index !== null) { if (Array.isArray(material)) { for (let i = 0, il = groups.length; i < il; i++) { const group = groups[i]; const groupMaterial = material[group.materialIndex]; const start = Math.max(group.start, drawRange.start); const end = Math.min(group.start + group.count, drawRange.start + drawRange.count); for (let j = start, jl = end; j < jl; j += 3) { const a2 = index.getX(j); const b2 = index.getX(j + 1); const c2 = index.getX(j + 2); intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a2, b2, c2); if (intersection) { intersection.faceIndex = Math.floor(j / 3); intersection.face.materialIndex = group.materialIndex; intersects2.push(intersection); } } } } else { const start = Math.max(0, drawRange.start); const end = Math.min(index.count, drawRange.start + drawRange.count); for (let i = start, il = end; i < il; i += 3) { const a2 = index.getX(i); const b2 = index.getX(i + 1); const c2 = index.getX(i + 2); intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a2, b2, c2); if (intersection) { intersection.faceIndex = Math.floor(i / 3); intersects2.push(intersection); } } } } else if (position !== void 0) { if (Array.isArray(material)) { for (let i = 0, il = groups.length; i < il; i++) { const group = groups[i]; const groupMaterial = material[group.materialIndex]; const start = Math.max(group.start, drawRange.start); const end = Math.min(group.start + group.count, drawRange.start + drawRange.count); for (let j = start, jl = end; j < jl; j += 3) { const a2 = j; const b2 = j + 1; const c2 = j + 2; intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a2, b2, c2); if (intersection) { intersection.faceIndex = Math.floor(j / 3); intersection.face.materialIndex = group.materialIndex; intersects2.push(intersection); } } } } else { const start = Math.max(0, drawRange.start); const end = Math.min(position.count, drawRange.start + drawRange.count); for (let i = start, il = end; i < il; i += 3) { const a2 = i; const b2 = i + 1; const c2 = i + 2; intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a2, b2, c2); if (intersection) { intersection.faceIndex = Math.floor(i / 3); intersects2.push(intersection); } } } } } else if (geometry.isGeometry) { console.error("THREE.Mesh.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead."); } } }; Mesh.prototype.isMesh = true; function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) { let intersect2; if (material.side === BackSide) { intersect2 = ray.intersectTriangle(pC, pB, pA, true, point); } else { intersect2 = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point); } if (intersect2 === null) return null; _intersectionPointWorld.copy(point); _intersectionPointWorld.applyMatrix4(object.matrixWorld); const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld); if (distance < raycaster.near || distance > raycaster.far) return null; return { distance, point: _intersectionPointWorld.clone(), object }; } function checkBufferGeometryIntersection(object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a2, b2, c2) { _vA$1.fromBufferAttribute(position, a2); _vB$1.fromBufferAttribute(position, b2); _vC$1.fromBufferAttribute(position, c2); const morphInfluences = object.morphTargetInfluences; if (morphPosition && morphInfluences) { _morphA.set(0, 0, 0); _morphB.set(0, 0, 0); _morphC.set(0, 0, 0); for (let i = 0, il = morphPosition.length; i < il; i++) { const influence = morphInfluences[i]; const morphAttribute = morphPosition[i]; if (influence === 0) continue; _tempA.fromBufferAttribute(morphAttribute, a2); _tempB.fromBufferAttribute(morphAttribute, b2); _tempC.fromBufferAttribute(morphAttribute, c2); if (morphTargetsRelative) { _morphA.addScaledVector(_tempA, influence); _morphB.addScaledVector(_tempB, influence); _morphC.addScaledVector(_tempC, influence); } else { _morphA.addScaledVector(_tempA.sub(_vA$1), influence); _morphB.addScaledVector(_tempB.sub(_vB$1), influence); _morphC.addScaledVector(_tempC.sub(_vC$1), influence); } } _vA$1.add(_morphA); _vB$1.add(_morphB); _vC$1.add(_morphC); } if (object.isSkinnedMesh) { object.boneTransform(a2, _vA$1); object.boneTransform(b2, _vB$1); object.boneTransform(c2, _vC$1); } const intersection = checkIntersection(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint); if (intersection) { if (uv) { _uvA$1.fromBufferAttribute(uv, a2); _uvB$1.fromBufferAttribute(uv, b2); _uvC$1.fromBufferAttribute(uv, c2); intersection.uv = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()); } if (uv2) { _uvA$1.fromBufferAttribute(uv2, a2); _uvB$1.fromBufferAttribute(uv2, b2); _uvC$1.fromBufferAttribute(uv2, c2); intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2()); } const face = { a: a2, b: b2, c: c2, normal: new Vector3(), materialIndex: 0 }; Triangle.getNormal(_vA$1, _vB$1, _vC$1, face.normal); intersection.face = face; } return intersection; } var BoxGeometry = class extends BufferGeometry { constructor(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) { super(); this.type = "BoxGeometry"; this.parameters = { width, height, depth, widthSegments, heightSegments, depthSegments }; const scope = this; widthSegments = Math.floor(widthSegments); heightSegments = Math.floor(heightSegments); depthSegments = Math.floor(depthSegments); const indices = []; const vertices = []; const normals = []; const uvs = []; let numberOfVertices = 0; let groupStart = 0; buildPlane("z", "y", "x", -1, -1, depth, height, width, depthSegments, heightSegments, 0); buildPlane("z", "y", "x", 1, -1, depth, height, -width, depthSegments, heightSegments, 1); buildPlane("x", "z", "y", 1, 1, width, depth, height, widthSegments, depthSegments, 2); buildPlane("x", "z", "y", 1, -1, width, depth, -height, widthSegments, depthSegments, 3); buildPlane("x", "y", "z", 1, -1, width, height, depth, widthSegments, heightSegments, 4); buildPlane("x", "y", "z", -1, -1, width, height, -depth, widthSegments, heightSegments, 5); 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, w2, udir, vdir, width2, height2, depth2, gridX, gridY, materialIndex) { const segmentWidth = width2 / gridX; const segmentHeight = height2 / gridY; const widthHalf = width2 / 2; const heightHalf = height2 / 2; const depthHalf = depth2 / 2; const gridX1 = gridX + 1; const gridY1 = gridY + 1; let vertexCounter = 0; let groupCount = 0; const vector = new Vector3(); for (let iy = 0; iy < gridY1; iy++) { const y = iy * segmentHeight - heightHalf; for (let ix = 0; ix < gridX1; ix++) { const x = ix * segmentWidth - widthHalf; vector[u] = x * udir; vector[v] = y * vdir; vector[w2] = depthHalf; vertices.push(vector.x, vector.y, vector.z); vector[u] = 0; vector[v] = 0; vector[w2] = depth2 > 0 ? 1 : -1; normals.push(vector.x, vector.y, vector.z); uvs.push(ix / gridX); uvs.push(1 - iy / gridY); vertexCounter += 1; } } for (let iy = 0; iy < gridY; iy++) { for (let ix = 0; ix < gridX; ix++) { const a2 = numberOfVertices + ix + gridX1 * iy; const b2 = numberOfVertices + ix + gridX1 * (iy + 1); const c2 = numberOfVertices + (ix + 1) + gridX1 * (iy + 1); const d = numberOfVertices + (ix + 1) + gridX1 * iy; indices.push(a2, b2, d); indices.push(b2, c2, d); groupCount += 6; } } scope.addGroup(groupStart, groupCount, materialIndex); groupStart += groupCount; numberOfVertices += vertexCounter; } } static fromJSON(data) { return new BoxGeometry(data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments); } }; function cloneUniforms(src) { const dst = {}; for (const u in src) { dst[u] = {}; for (const p2 in src[u]) { const property = src[u][p2]; if (property && (property.isColor || property.isMatrix3 || property.isMatrix4 || property.isVector2 || property.isVector3 || property.isVector4 || property.isTexture || property.isQuaternion)) { dst[u][p2] = property.clone(); } else if (Array.isArray(property)) { dst[u][p2] = property.slice(); } else { dst[u][p2] = property; } } } return dst; } function mergeUniforms(uniforms) { const merged = {}; for (let u = 0; u < uniforms.length; u++) { const tmp3 = cloneUniforms(uniforms[u]); for (const p2 in tmp3) { merged[p2] = tmp3[p2]; } } return merged; } var UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; var default_vertex = "void main() {\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; var default_fragment = "void main() {\n gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; var ShaderMaterial = class extends Material { constructor(parameters) { super(); 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; this.lights = false; this.clipping = false; this.extensions = { derivatives: false, fragDepth: false, drawBuffers: false, shaderTextureLOD: false }; this.defaultAttributeValues = { "color": [1, 1, 1], "uv": [0, 0], "uv2": [0, 0] }; this.index0AttributeName = void 0; this.uniformsNeedUpdate = false; this.glslVersion = null; if (parameters !== void 0) { if (parameters.attributes !== void 0) { console.error("THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead."); } this.setValues(parameters); } } copy(source) { super.copy(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.extensions = Object.assign({}, source.extensions); this.glslVersion = source.glslVersion; return this; } toJSON(meta) { const data = super.toJSON(meta); data.glslVersion = this.glslVersion; data.uniforms = {}; for (const name in this.uniforms) { const uniform = this.uniforms[name]; const 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 }; } } if (Object.keys(this.defines).length > 0) data.defines = this.defines; data.vertexShader = this.vertexShader; data.fragmentShader = this.fragmentShader; const extensions = {}; for (const key in this.extensions) { if (this.extensions[key] === true) extensions[key] = true; } if (Object.keys(extensions).length > 0) data.extensions = extensions; return data; } }; ShaderMaterial.prototype.isShaderMaterial = true; var Camera = class extends Object3D { constructor() { super(); this.type = "Camera"; this.matrixWorldInverse = new Matrix4(); this.projectionMatrix = new Matrix4(); this.projectionMatrixInverse = new Matrix4(); } copy(source, recursive) { super.copy(source, recursive); this.matrixWorldInverse.copy(source.matrixWorldInverse); this.projectionMatrix.copy(source.projectionMatrix); this.projectionMatrixInverse.copy(source.projectionMatrixInverse); return this; } getWorldDirection(target) { this.updateWorldMatrix(true, false); const e = this.matrixWorld.elements; return target.set(-e[8], -e[9], -e[10]).normalize(); } updateMatrixWorld(force) { super.updateMatrixWorld(force); this.matrixWorldInverse.copy(this.matrixWorld).invert(); } updateWorldMatrix(updateParents, updateChildren) { super.updateWorldMatrix(updateParents, updateChildren); this.matrixWorldInverse.copy(this.matrixWorld).invert(); } clone() { return new this.constructor().copy(this); } }; Camera.prototype.isCamera = true; var PerspectiveCamera = class extends Camera { constructor(fov2 = 50, aspect2 = 1, near = 0.1, far = 2e3) { super(); this.type = "PerspectiveCamera"; this.fov = fov2; this.zoom = 1; this.near = near; this.far = far; this.focus = 10; this.aspect = aspect2; this.view = null; this.filmGauge = 35; this.filmOffset = 0; this.updateProjectionMatrix(); } copy(source, recursive) { super.copy(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; } setFocalLength(focalLength) { const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; this.fov = RAD2DEG * 2 * Math.atan(vExtentSlope); this.updateProjectionMatrix(); } getFocalLength() { const vExtentSlope = Math.tan(DEG2RAD * 0.5 * this.fov); return 0.5 * this.getFilmHeight() / vExtentSlope; } getEffectiveFOV() { return RAD2DEG * 2 * Math.atan(Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom); } getFilmWidth() { return this.filmGauge * Math.min(this.aspect, 1); } getFilmHeight() { return this.filmGauge / Math.max(this.aspect, 1); } setViewOffset(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() { if (this.view !== null) { this.view.enabled = false; } this.updateProjectionMatrix(); } updateProjectionMatrix() { const near = this.near; let top = near * Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom; let height = 2 * top; let width = this.aspect * height; let left = -0.5 * width; const view = this.view; if (this.view !== null && this.view.enabled) { const fullWidth = view.fullWidth, fullHeight = view.fullHeight; left += view.offsetX * width / fullWidth; top -= view.offsetY * height / fullHeight; width *= view.width / fullWidth; height *= view.height / fullHeight; } const 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.copy(this.projectionMatrix).invert(); } toJSON(meta) { const data = super.toJSON(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; } }; PerspectiveCamera.prototype.isPerspectiveCamera = true; var fov = 90; var aspect = 1; var CubeCamera = class extends Object3D { constructor(near, far, renderTarget) { super(); this.type = "CubeCamera"; if (renderTarget.isWebGLCubeRenderTarget !== true) { console.error("THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter."); return; } this.renderTarget = renderTarget; const cameraPX = new PerspectiveCamera(fov, aspect, near, far); cameraPX.layers = this.layers; cameraPX.up.set(0, -1, 0); cameraPX.lookAt(new Vector3(1, 0, 0)); this.add(cameraPX); const cameraNX = new PerspectiveCamera(fov, aspect, near, far); cameraNX.layers = this.layers; cameraNX.up.set(0, -1, 0); cameraNX.lookAt(new Vector3(-1, 0, 0)); this.add(cameraNX); const cameraPY = new PerspectiveCamera(fov, aspect, near, far); cameraPY.layers = this.layers; cameraPY.up.set(0, 0, 1); cameraPY.lookAt(new Vector3(0, 1, 0)); this.add(cameraPY); const cameraNY = new PerspectiveCamera(fov, aspect, near, far); cameraNY.layers = this.layers; cameraNY.up.set(0, 0, -1); cameraNY.lookAt(new Vector3(0, -1, 0)); this.add(cameraNY); const cameraPZ = new PerspectiveCamera(fov, aspect, near, far); cameraPZ.layers = this.layers; cameraPZ.up.set(0, -1, 0); cameraPZ.lookAt(new Vector3(0, 0, 1)); this.add(cameraPZ); const cameraNZ = new PerspectiveCamera(fov, aspect, near, far); cameraNZ.layers = this.layers; cameraNZ.up.set(0, -1, 0); cameraNZ.lookAt(new Vector3(0, 0, -1)); this.add(cameraNZ); } update(renderer, scene) { if (this.parent === null) this.updateMatrixWorld(); const renderTarget = this.renderTarget; const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = this.children; const currentXrEnabled = renderer.xr.enabled; const currentRenderTarget = renderer.getRenderTarget(); renderer.xr.enabled = false; const 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); renderer.xr.enabled = currentXrEnabled; } }; var CubeTexture = class extends Texture { constructor(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) { images = images !== void 0 ? images : []; mapping = mapping !== void 0 ? mapping : CubeReflectionMapping; format = format !== void 0 ? format : RGBFormat; super(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); this.flipY = false; } get images() { return this.image; } set images(value) { this.image = value; } }; CubeTexture.prototype.isCubeTexture = true; var WebGLCubeRenderTarget = class extends WebGLRenderTarget { constructor(size, options, dummy) { if (Number.isInteger(options)) { console.warn("THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )"); options = dummy; } super(size, size, options); options = options || {}; this.texture = new CubeTexture(void 0, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); this.texture.isRenderTargetTexture = true; this.texture.generateMipmaps = options.generateMipmaps !== void 0 ? options.generateMipmaps : false; this.texture.minFilter = options.minFilter !== void 0 ? options.minFilter : LinearFilter; this.texture._needsFlipEnvMap = false; } fromEquirectangularTexture(renderer, texture) { this.texture.type = texture.type; this.texture.format = RGBAFormat; this.texture.encoding = texture.encoding; this.texture.generateMipmaps = texture.generateMipmaps; this.texture.minFilter = texture.minFilter; this.texture.magFilter = texture.magFilter; const 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 #include } `, fragmentShader: ` uniform sampler2D tEquirect; varying vec3 vWorldDirection; #include void main() { vec3 direction = normalize( vWorldDirection ); vec2 sampleUV = equirectUv( direction ); gl_FragColor = texture2D( tEquirect, sampleUV ); } ` }; const geometry = new BoxGeometry(5, 5, 5); const material = new ShaderMaterial({ name: "CubemapFromEquirect", uniforms: cloneUniforms(shader.uniforms), vertexShader: shader.vertexShader, fragmentShader: shader.fragmentShader, side: BackSide, blending: NoBlending }); material.uniforms.tEquirect.value = texture; const mesh = new Mesh(geometry, material); const currentMinFilter = texture.minFilter; if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; const camera = new CubeCamera(1, 10, this); camera.update(renderer, mesh); texture.minFilter = currentMinFilter; mesh.geometry.dispose(); mesh.material.dispose(); return this; } clear(renderer, color, depth, stencil) { const currentRenderTarget = renderer.getRenderTarget(); for (let i = 0; i < 6; i++) { renderer.setRenderTarget(this, i); renderer.clear(color, depth, stencil); } renderer.setRenderTarget(currentRenderTarget); } }; WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true; var _vector1 = /* @__PURE__ */ new Vector3(); var _vector2 = /* @__PURE__ */ new Vector3(); var _normalMatrix = /* @__PURE__ */ new Matrix3(); var Plane = class { constructor(normal = new Vector3(1, 0, 0), constant = 0) { this.normal = normal; this.constant = constant; } set(normal, constant) { this.normal.copy(normal); this.constant = constant; return this; } setComponents(x, y, z, w2) { this.normal.set(x, y, z); this.constant = w2; return this; } setFromNormalAndCoplanarPoint(normal, point) { this.normal.copy(normal); this.constant = -point.dot(this.normal); return this; } setFromCoplanarPoints(a2, b2, c2) { const normal = _vector1.subVectors(c2, b2).cross(_vector2.subVectors(a2, b2)).normalize(); this.setFromNormalAndCoplanarPoint(normal, a2); return this; } copy(plane) { this.normal.copy(plane.normal); this.constant = plane.constant; return this; } normalize() { const inverseNormalLength = 1 / this.normal.length(); this.normal.multiplyScalar(inverseNormalLength); this.constant *= inverseNormalLength; return this; } negate() { this.constant *= -1; this.normal.negate(); return this; } distanceToPoint(point) { return this.normal.dot(point) + this.constant; } distanceToSphere(sphere) { return this.distanceToPoint(sphere.center) - sphere.radius; } projectPoint(point, target) { return target.copy(this.normal).multiplyScalar(-this.distanceToPoint(point)).add(point); } intersectLine(line, target) { const direction = line.delta(_vector1); const denominator = this.normal.dot(direction); if (denominator === 0) { if (this.distanceToPoint(line.start) === 0) { return target.copy(line.start); } return null; } const t = -(line.start.dot(this.normal) + this.constant) / denominator; if (t < 0 || t > 1) { return null; } return target.copy(direction).multiplyScalar(t).add(line.start); } intersectsLine(line) { const startSign = this.distanceToPoint(line.start); const endSign = this.distanceToPoint(line.end); return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0; } intersectsBox(box) { return box.intersectsPlane(this); } intersectsSphere(sphere) { return sphere.intersectsPlane(this); } coplanarPoint(target) { return target.copy(this.normal).multiplyScalar(-this.constant); } applyMatrix4(matrix, optionalNormalMatrix) { const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix); const referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix); const normal = this.normal.applyMatrix3(normalMatrix).normalize(); this.constant = -referencePoint.dot(normal); return this; } translate(offset) { this.constant -= offset.dot(this.normal); return this; } equals(plane) { return plane.normal.equals(this.normal) && plane.constant === this.constant; } clone() { return new this.constructor().copy(this); } }; Plane.prototype.isPlane = true; var _sphere$2 = /* @__PURE__ */ new Sphere(); var _vector$7 = /* @__PURE__ */ new Vector3(); var Frustum = class { constructor(p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane()) { this.planes = [p0, p1, p2, p3, p4, p5]; } set(p0, p1, p2, p3, p4, p5) { const 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; } copy(frustum) { const planes = this.planes; for (let i = 0; i < 6; i++) { planes[i].copy(frustum.planes[i]); } return this; } setFromProjectionMatrix(m) { const planes = this.planes; const me = m.elements; const me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3]; const me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7]; const me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11]; const 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(object) { const geometry = object.geometry; if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$2.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld); return this.intersectsSphere(_sphere$2); } intersectsSprite(sprite) { _sphere$2.center.set(0, 0, 0); _sphere$2.radius = 0.7071067811865476; _sphere$2.applyMatrix4(sprite.matrixWorld); return this.intersectsSphere(_sphere$2); } intersectsSphere(sphere) { const planes = this.planes; const center = sphere.center; const negRadius = -sphere.radius; for (let i = 0; i < 6; i++) { const distance = planes[i].distanceToPoint(center); if (distance < negRadius) { return false; } } return true; } intersectsBox(box) { const planes = this.planes; for (let i = 0; i < 6; i++) { const plane = planes[i]; _vector$7.x = plane.normal.x > 0 ? box.max.x : box.min.x; _vector$7.y = plane.normal.y > 0 ? box.max.y : box.min.y; _vector$7.z = plane.normal.z > 0 ? box.max.z : box.min.z; if (plane.distanceToPoint(_vector$7) < 0) { return false; } } return true; } containsPoint(point) { const planes = this.planes; for (let i = 0; i < 6; i++) { if (planes[i].distanceToPoint(point) < 0) { return false; } } return true; } clone() { return new this.constructor().copy(this); } }; function WebGLAnimation() { let context = null; let isAnimating = false; let animationLoop = null; let requestId = null; function onAnimationFrame(time, frame) { animationLoop(time, frame); requestId = context.requestAnimationFrame(onAnimationFrame); } return { start: function() { if (isAnimating === true) return; if (animationLoop === null) return; requestId = context.requestAnimationFrame(onAnimationFrame); isAnimating = true; }, stop: function() { context.cancelAnimationFrame(requestId); isAnimating = false; }, setAnimationLoop: function(callback) { animationLoop = callback; }, setContext: function(value) { context = value; } }; } function WebGLAttributes(gl, capabilities) { const isWebGL2 = capabilities.isWebGL2; const buffers = new WeakMap(); function createBuffer(attribute, bufferType) { const array = attribute.array; const usage = attribute.usage; const buffer = gl.createBuffer(); gl.bindBuffer(bufferType, buffer); gl.bufferData(bufferType, array, usage); attribute.onUploadCallback(); let 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) { if (attribute.isFloat16BufferAttribute) { if (isWebGL2) { type = 5131; } else { console.warn("THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2."); } } else { 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; } else if (array instanceof Uint8ClampedArray) { type = 5121; } return { buffer, type, bytesPerElement: array.BYTES_PER_ELEMENT, version: attribute.version }; } function updateBuffer(buffer, attribute, bufferType) { const array = attribute.array; const updateRange = attribute.updateRange; gl.bindBuffer(bufferType, buffer); if (updateRange.count === -1) { 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; } } function get(attribute) { if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; return buffers.get(attribute); } function remove(attribute) { if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; const data = buffers.get(attribute); if (data) { gl.deleteBuffer(data.buffer); buffers.delete(attribute); } } function update(attribute, bufferType) { if (attribute.isGLBufferAttribute) { const cached = buffers.get(attribute); if (!cached || cached.version < attribute.version) { buffers.set(attribute, { buffer: attribute.buffer, type: attribute.type, bytesPerElement: attribute.elementSize, version: attribute.version }); } return; } if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; const data = buffers.get(attribute); if (data === void 0) { buffers.set(attribute, createBuffer(attribute, bufferType)); } else if (data.version < attribute.version) { updateBuffer(data.buffer, attribute, bufferType); data.version = attribute.version; } } return { get, remove, update }; } var PlaneGeometry = class extends BufferGeometry { constructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) { super(); this.type = "PlaneGeometry"; this.parameters = { width, height, widthSegments, heightSegments }; const width_half = width / 2; const height_half = height / 2; const gridX = Math.floor(widthSegments); const gridY = Math.floor(heightSegments); const gridX1 = gridX + 1; const gridY1 = gridY + 1; const segment_width = width / gridX; const segment_height = height / gridY; const indices = []; const vertices = []; const normals = []; const uvs = []; for (let iy = 0; iy < gridY1; iy++) { const y = iy * segment_height - height_half; for (let ix = 0; ix < gridX1; ix++) { const 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); } } for (let iy = 0; iy < gridY; iy++) { for (let ix = 0; ix < gridX; ix++) { const a2 = ix + gridX1 * iy; const b2 = ix + gridX1 * (iy + 1); const c2 = ix + 1 + gridX1 * (iy + 1); const d = ix + 1 + gridX1 * iy; indices.push(a2, b2, d); indices.push(b2, c2, d); } } this.setIndex(indices); this.setAttribute("position", new Float32BufferAttribute(vertices, 3)); this.setAttribute("normal", new Float32BufferAttribute(normals, 3)); this.setAttribute("uv", new Float32BufferAttribute(uvs, 2)); } static fromJSON(data) { return new PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments); } }; var alphamap_fragment = "#ifdef USE_ALPHAMAP\n diffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n uniform sampler2D alphaMap;\n#endif"; var alphatest_fragment = "#ifdef USE_ALPHATEST\n if ( diffuseColor.a < alphaTest ) discard;\n#endif"; var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n uniform float alphaTest;\n#endif"; var aomap_fragment = "#ifdef USE_AOMAP\n float ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n reflectedLight.indirectDiffuse *= ambientOcclusion;\n #if defined( USE_ENVMAP ) && defined( STANDARD )\n float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n #endif\n#endif"; var aomap_pars_fragment = "#ifdef USE_AOMAP\n uniform sampler2D aoMap;\n uniform float aoMapIntensity;\n#endif"; var begin_vertex = "vec3 transformed = vec3( position );"; var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n vec3 objectTangent = vec3( tangent.xyz );\n#endif"; var bsdfs = "vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n return RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n float fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n float a2 = pow2( alpha );\n float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n return 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n float a2 = pow2( alpha );\n float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n return RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\n float alpha = pow2( roughness );\n vec3 halfDir = normalize( incidentLight.direction + viewDir );\n float dotNL = saturate( dot( normal, incidentLight.direction ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float dotVH = saturate( dot( viewDir, halfDir ) );\n vec3 F = F_Schlick( f0, f90, dotVH );\n float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n float D = D_GGX( alpha, dotNH );\n return F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n const float LUT_SIZE = 64.0;\n const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n const float LUT_BIAS = 0.5 / LUT_SIZE;\n float dotNV = saturate( dot( N, V ) );\n vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n uv = uv * LUT_SCALE + LUT_BIAS;\n return uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n float l = length( f );\n return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n float x = dot( v1, v2 );\n float y = abs( x );\n float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n float b = 3.4175940 + ( 4.1616724 + y ) * y;\n float v = a / b;\n float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n return 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 vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n vec3 lightNormal = cross( v1, v2 );\n if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n vec3 T1, T2;\n T1 = normalize( V - N * dot( V, N ) );\n T2 = - cross( N, T1 );\n mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n vec3 coords[ 4 ];\n coords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n coords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n coords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n coords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n coords[ 0 ] = normalize( coords[ 0 ] );\n coords[ 1 ] = normalize( coords[ 1 ] );\n coords[ 2 ] = normalize( coords[ 2 ] );\n coords[ 3 ] = normalize( coords[ 3 ] );\n vec3 vectorFormFactor = vec3( 0.0 );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n float result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n return vec3( result );\n}\nfloat G_BlinnPhong_Implicit( ) {\n return 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n float dotNH = saturate( dot( geometry.normal, halfDir ) );\n float dotVH = saturate( dot( geometry.viewDir, halfDir ) );\n vec3 F = F_Schlick( specularColor, 1.0, dotVH );\n float G = G_BlinnPhong_Implicit( );\n float D = D_BlinnPhong( shininess, dotNH );\n return F * ( G * D );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float NoH ) {\n float invAlpha = 1.0 / roughness;\n float cos2h = NoH * NoH;\n float sin2h = max( 1.0 - cos2h, 0.0078125 );\n return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float NoV, float NoL ) {\n return saturate( 1.0 / ( 4.0 * ( NoL + NoV - NoL * NoV ) ) );\n}\nvec3 BRDF_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n vec3 N = geometry.normal;\n vec3 V = geometry.viewDir;\n vec3 H = normalize( V + L );\n float dotNH = saturate( dot( N, H ) );\n return specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif"; var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n uniform sampler2D bumpMap;\n uniform float bumpScale;\n vec2 dHdxy_fwd() {\n vec2 dSTdx = dFdx( vUv );\n vec2 dSTdy = dFdy( vUv );\n float Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n return vec2( dBx, dBy );\n }\n vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n vec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n vec3 vN = surf_norm;\n vec3 R1 = cross( vSigmaY, vN );\n vec3 R2 = cross( vN, vSigmaX );\n float fDet = dot( vSigmaX, R1 ) * faceDirection;\n vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n return normalize( abs( fDet ) * surf_norm - vGrad );\n }\n#endif"; var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n vec4 plane;\n #pragma unroll_loop_start\n for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n plane = clippingPlanes[ i ];\n if ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n }\n #pragma unroll_loop_end\n #if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n bool clipped = true;\n #pragma unroll_loop_start\n for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n plane = clippingPlanes[ i ];\n clipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n }\n #pragma unroll_loop_end\n if ( clipped ) discard;\n #endif\n#endif"; var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n varying vec3 vClipPosition;\n uniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n varying vec3 vClipPosition;\n#endif"; var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n vClipPosition = - mvPosition.xyz;\n#endif"; var color_fragment = "#if defined( USE_COLOR_ALPHA )\n diffuseColor *= vColor;\n#elif defined( USE_COLOR )\n diffuseColor.rgb *= vColor;\n#endif"; var color_pars_fragment = "#if defined( USE_COLOR_ALPHA )\n varying vec4 vColor;\n#elif defined( USE_COLOR )\n varying vec3 vColor;\n#endif"; var color_pars_vertex = "#if defined( USE_COLOR_ALPHA )\n varying vec4 vColor;\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n varying vec3 vColor;\n#endif"; var color_vertex = "#if defined( USE_COLOR_ALPHA )\n vColor = vec4( 1.0 );\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n vColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n vColor *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n vColor.xyz *= instanceColor.xyz;\n#endif"; var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\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 max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n const highp float a = 12.9898, b = 78.233, c = 43758.5453;\n highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n return fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n float precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n float precisionSafeLength( vec3 v ) {\n float maxComponent = max3( abs( v ) );\n return length( v / maxComponent ) * maxComponent;\n }\n#endif\nstruct IncidentLight {\n vec3 color;\n vec3 direction;\n bool visible;\n};\nstruct ReflectedLight {\n vec3 directDiffuse;\n vec3 directSpecular;\n vec3 indirectDiffuse;\n vec3 indirectSpecular;\n};\nstruct GeometricContext {\n vec3 position;\n vec3 normal;\n vec3 viewDir;\n#ifdef USE_CLEARCOAT\n vec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nmat3 transposeMat3( const in mat3 m ) {\n mat3 tmp;\n tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n return tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n vec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n return dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n return vec2( u, v );\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\n float 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 }\n vec2 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 = vec2( - direction.x, direction.y ) / 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 = vec2( - direction.x, direction.z ) / abs( direction.y );\n } else {\n uv = vec2( direction.x, direction.y ) / abs( direction.z );\n }\n return 0.5 * ( uv + 1.0 );\n }\n vec3 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\n float 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 }\n vec4 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 mat3 m = mat3( instanceMatrix );\n transformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n transformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n transformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n vec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n #ifdef FLIP_SIDED\n transformedTangent = - transformedTangent;\n #endif\n#endif"; var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n uniform sampler2D displacementMap;\n uniform float displacementScale;\n uniform float displacementBias;\n#endif"; var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif"; var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n vec4 emissiveColor = texture2D( emissiveMap, vUv );\n emissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n totalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n uniform sampler2D emissiveMap;\n#endif"; var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n return value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n return 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 return 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 return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n float maxComponent = max( max( value.r, value.g ), value.b );\n float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n return vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n float maxRGB = max( value.r, max( value.g, value.b ) );\n float M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n M = ceil( M * 255.0 ) / 255.0;\n return vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n float maxRGB = max( value.r, max( value.g, value.b ) );\n float D = max( maxRange / maxRGB, 1.0 );\n D = clamp( floor( D ) / 255.0, 0.0, 1.0 );\n return 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 vec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n vec4 vResult;\n vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n vResult.w = fract( Le );\n vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n return 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 float Le = value.z * 255.0 + value.w;\n vec3 Xp_Y_XYZp;\n Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n return vec4( max( vRGB, 0.0 ), 1.0 );\n}"; var envmap_fragment = "#ifdef USE_ENVMAP\n #ifdef ENV_WORLDPOS\n vec3 cameraToFrag;\n if ( isOrthographic ) {\n cameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n } else {\n cameraToFrag = normalize( vWorldPosition - cameraPosition );\n }\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n #ifdef ENVMAP_MODE_REFLECTION\n vec3 reflectVec = reflect( cameraToFrag, worldNormal );\n #else\n vec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n #endif\n #else\n vec3 reflectVec = vReflect;\n #endif\n #ifdef ENVMAP_TYPE_CUBE\n vec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n envColor = envMapTexelToLinear( envColor );\n #elif defined( ENVMAP_TYPE_CUBE_UV )\n vec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n #else\n vec4 envColor = vec4( 0.0 );\n #endif\n #ifdef ENVMAP_BLENDING_MULTIPLY\n outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n #elif defined( ENVMAP_BLENDING_MIX )\n outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n #elif defined( ENVMAP_BLENDING_ADD )\n outgoingLight += envColor.xyz * specularStrength * reflectivity;\n #endif\n#endif"; var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n uniform float envMapIntensity;\n uniform float flipEnvMap;\n uniform int maxMipLevel;\n #ifdef ENVMAP_TYPE_CUBE\n uniform samplerCube envMap;\n #else\n uniform sampler2D envMap;\n #endif\n \n#endif"; var envmap_pars_fragment = "#ifdef USE_ENVMAP\n uniform float reflectivity;\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n #define ENV_WORLDPOS\n #endif\n #ifdef ENV_WORLDPOS\n varying vec3 vWorldPosition;\n uniform float refractionRatio;\n #else\n varying vec3 vReflect;\n #endif\n#endif"; var envmap_pars_vertex = "#ifdef USE_ENVMAP\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n #define ENV_WORLDPOS\n #endif\n #ifdef ENV_WORLDPOS\n \n varying vec3 vWorldPosition;\n #else\n varying vec3 vReflect;\n uniform float refractionRatio;\n #endif\n#endif"; var envmap_vertex = "#ifdef USE_ENVMAP\n #ifdef ENV_WORLDPOS\n vWorldPosition = worldPosition.xyz;\n #else\n vec3 cameraToVertex;\n if ( isOrthographic ) {\n cameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n } else {\n cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n }\n vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n #ifdef ENVMAP_MODE_REFLECTION\n vReflect = reflect( cameraToVertex, worldNormal );\n #else\n vReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n #endif\n #endif\n#endif"; var fog_vertex = "#ifdef USE_FOG\n vFogDepth = - mvPosition.z;\n#endif"; var fog_pars_vertex = "#ifdef USE_FOG\n varying float vFogDepth;\n#endif"; var fog_fragment = "#ifdef USE_FOG\n #ifdef FOG_EXP2\n float fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n #else\n float fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n #endif\n gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; var fog_pars_fragment = "#ifdef USE_FOG\n uniform vec3 fogColor;\n varying float vFogDepth;\n #ifdef FOG_EXP2\n uniform float fogDensity;\n #else\n uniform float fogNear;\n uniform float fogFar;\n #endif\n#endif"; var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n uniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n float dotNL = dot( normal, lightDirection );\n vec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n #ifdef USE_GRADIENTMAP\n return texture2D( gradientMap, coord ).rgb;\n #else\n return ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n #endif\n}"; var lightmap_fragment = "#ifdef USE_LIGHTMAP\n vec4 lightMapTexel = texture2D( lightMap, vUv2 );\n vec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n #ifndef PHYSICALLY_CORRECT_LIGHTS\n lightMapIrradiance *= PI;\n #endif\n reflectedLight.indirectDiffuse += lightMapIrradiance;\n#endif"; var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n uniform sampler2D lightMap;\n uniform 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 vLightBack = vec3( 0.0 );\n vIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry );\n#ifdef DOUBLE_SIDED\n vIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry );\n#endif\n#if NUM_POINT_LIGHTS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n getPointLightInfo( pointLights[ i ], geometry, directLight );\n dotNL = dot( geometry.normal, directLight.direction );\n directLightColor_Diffuse = directLight.color;\n vLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n #ifdef DOUBLE_SIDED\n vLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n #endif\n }\n #pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n getSpotLightInfo( spotLights[ i ], geometry, directLight );\n dotNL = dot( geometry.normal, directLight.direction );\n directLightColor_Diffuse = directLight.color;\n vLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n #ifdef DOUBLE_SIDED\n vLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n #endif\n }\n #pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n getDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\n dotNL = dot( geometry.normal, directLight.direction );\n directLightColor_Diffuse = directLight.color;\n vLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n #ifdef DOUBLE_SIDED\n vLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n #endif\n }\n #pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n #ifdef DOUBLE_SIDED\n vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n #endif\n }\n #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 float x = normal.x, y = normal.y, z = normal.z;\n vec3 result = shCoefficients[ 0 ] * 0.886227;\n result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n return result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n return irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n vec3 irradiance = ambientLightColor;\n return irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n #if defined ( PHYSICALLY_CORRECT_LIGHTS )\n float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n if ( cutoffDistance > 0.0 ) {\n distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n }\n return distanceFalloff;\n #else\n if ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n return pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\n }\n return 1.0;\n #endif\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n return smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n struct DirectionalLight {\n vec3 direction;\n vec3 color;\n };\n uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n void getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\n light.color = directionalLight.color;\n light.direction = directionalLight.direction;\n light.visible = true;\n }\n#endif\n#if NUM_POINT_LIGHTS > 0\n struct PointLight {\n vec3 position;\n vec3 color;\n float distance;\n float decay;\n };\n uniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n void getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\n vec3 lVector = pointLight.position - geometry.position;\n light.direction = normalize( lVector );\n float lightDistance = length( lVector );\n light.color = pointLight.color;\n light.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n light.visible = ( light.color != vec3( 0.0 ) );\n }\n#endif\n#if NUM_SPOT_LIGHTS > 0\n struct SpotLight {\n vec3 position;\n vec3 direction;\n vec3 color;\n float distance;\n float decay;\n float coneCos;\n float penumbraCos;\n };\n uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n void getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\n vec3 lVector = spotLight.position - geometry.position;\n light.direction = normalize( lVector );\n float angleCos = dot( light.direction, spotLight.direction );\n float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n if ( spotAttenuation > 0.0 ) {\n float lightDistance = length( lVector );\n light.color = spotLight.color * spotAttenuation;\n light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n light.visible = ( light.color != vec3( 0.0 ) );\n } else {\n light.color = vec3( 0.0 );\n light.visible = false;\n }\n }\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n struct RectAreaLight {\n vec3 color;\n vec3 position;\n vec3 halfWidth;\n vec3 halfHeight;\n };\n uniform sampler2D ltc_1; uniform sampler2D ltc_2;\n uniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n struct HemisphereLight {\n vec3 direction;\n vec3 skyColor;\n vec3 groundColor;\n };\n uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n float dotNL = dot( geometry.normal, hemiLight.direction );\n float hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n return irradiance;\n }\n#endif"; var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n #ifdef ENVMAP_MODE_REFRACTION\n uniform float refractionRatio;\n #endif\n vec3 getIBLIrradiance( const in GeometricContext geometry ) {\n #if defined( ENVMAP_TYPE_CUBE_UV )\n vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n return PI * envMapColor.rgb * envMapIntensity;\n #else\n return vec3( 0.0 );\n #endif\n }\n vec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n #if defined( ENVMAP_TYPE_CUBE_UV )\n vec3 reflectVec;\n #ifdef ENVMAP_MODE_REFLECTION\n reflectVec = reflect( - viewDir, normal );\n reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n #else\n reflectVec = refract( - viewDir, normal, refractionRatio );\n #endif\n reflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n return envMapColor.rgb * envMapIntensity;\n #else\n return vec3( 0.0 );\n #endif\n }\n#endif"; var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;"; var lights_toon_pars_fragment = "varying vec3 vViewPosition;\nstruct ToonMaterial {\n vec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_Toon\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material ) (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;\nstruct BlinnPhongMaterial {\n vec3 diffuseColor;\n vec3 specularColor;\n float specularShininess;\n float specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n reflectedLight.directSpecular += irradiance * BRDF_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 reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_BlinnPhong\n#define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material ) (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.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n #ifdef SPECULAR\n float specularIntensityFactor = specularIntensity;\n vec3 specularTintFactor = specularTint;\n #ifdef USE_SPECULARINTENSITYMAP\n specularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n #endif\n #ifdef USE_SPECULARTINTMAP\n specularTintFactor *= specularTintMapTexelToLinear( texture2D( specularTintMap, vUv ) ).rgb;\n #endif\n material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n #else\n float specularIntensityFactor = 1.0;\n vec3 specularTintFactor = vec3( 1.0 );\n material.specularF90 = 1.0;\n #endif\n material.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularTintFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n material.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n material.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n material.clearcoat = clearcoat;\n material.clearcoatRoughness = clearcoatRoughness;\n material.clearcoatF0 = vec3( 0.04 );\n material.clearcoatF90 = 1.0;\n #ifdef USE_CLEARCOATMAP\n material.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n #endif\n #ifdef USE_CLEARCOAT_ROUGHNESSMAP\n material.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n #endif\n material.clearcoat = saturate( material.clearcoat ); material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n material.clearcoatRoughness += geometryRoughness;\n material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n material.sheenTint = sheenTint;\n#endif"; var lights_physical_pars_fragment = "struct PhysicalMaterial {\n vec3 diffuseColor;\n float roughness;\n vec3 specularColor;\n float specularF90;\n #ifdef USE_CLEARCOAT\n float clearcoat;\n float clearcoatRoughness;\n vec3 clearcoatF0;\n float clearcoatF90;\n #endif\n #ifdef USE_SHEEN\n vec3 sheenTint;\n #endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n float dotNV = saturate( dot( normal, viewDir ) );\n const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n vec4 r = roughness * c0 + c1;\n float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n vec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n return fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n vec2 fab = DFGApprox( normal, viewDir, roughness );\n return specularColor * fab.x + specularF90 * fab.y;\n}\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n vec2 fab = DFGApprox( normal, viewDir, roughness );\n vec3 FssEss = specularColor * fab.x + specularF90 * fab.y;\n float Ess = fab.x + fab.y;\n float Ems = 1.0 - Ess;\n vec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n singleScatter += FssEss;\n multiScatter += Fms * Ems;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 normal = geometry.normal;\n vec3 viewDir = geometry.viewDir;\n vec3 position = geometry.position;\n vec3 lightPos = rectAreaLight.position;\n vec3 halfWidth = rectAreaLight.halfWidth;\n vec3 halfHeight = rectAreaLight.halfHeight;\n vec3 lightColor = rectAreaLight.color;\n float roughness = material.roughness;\n vec3 rectCoords[ 4 ];\n rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; rectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n rectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n rectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n vec2 uv = LTC_Uv( normal, viewDir, roughness );\n vec4 t1 = texture2D( ltc_1, uv );\n vec4 t2 = texture2D( ltc_2, uv );\n mat3 mInv = mat3(\n vec3( t1.x, 0, t1.y ),\n vec3( 0, 1, 0 ),\n vec3( t1.z, 0, t1.w )\n );\n vec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n reflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n }\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n #ifdef USE_CLEARCOAT\n float dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n vec3 ccIrradiance = dotNLcc * directLight.color;\n clearcoatSpecular += ccIrradiance * BRDF_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n #endif\n #ifdef USE_SHEEN\n reflectedLight.directSpecular += irradiance * BRDF_Sheen( material.roughness, directLight.direction, geometry, material.sheenTint );\n #else\n reflectedLight.directSpecular += irradiance * BRDF_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n #endif\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_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 #ifdef USE_CLEARCOAT\n clearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n #endif\n vec3 singleScattering = vec3( 0.0 );\n vec3 multiScattering = vec3( 0.0 );\n vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n computeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n vec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n reflectedLight.indirectSpecular += radiance * singleScattering;\n reflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n reflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct RE_Direct_Physical\n#define RE_Direct_RectArea RE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular RE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n return 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 USE_CLEARCOAT\n geometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n PointLight pointLight;\n #if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n PointLightShadow pointLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n pointLight = pointLights[ i ];\n getPointLightInfo( pointLight, geometry, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n pointLightShadow = pointLightShadows[ i ];\n directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n #endif\n RE_Direct( directLight, geometry, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n SpotLight spotLight;\n #if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n SpotLightShadow spotLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n spotLight = spotLights[ i ];\n getSpotLightInfo( spotLight, geometry, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n spotLightShadow = spotLightShadows[ i ];\n directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometry, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n DirectionalLight directionalLight;\n #if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n DirectionalLightShadow directionalLightShadow;\n #endif\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n directionalLight = directionalLights[ i ];\n getDirectionalLightInfo( directionalLight, geometry, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n directionalLightShadow = directionalLightShadows[ i ];\n directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometry, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n RectAreaLight rectAreaLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n rectAreaLight = rectAreaLights[ i ];\n RE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n vec3 iblIrradiance = vec3( 0.0 );\n vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n irradiance += getLightProbeIrradiance( lightProbe, geometry );\n #if ( NUM_HEMI_LIGHTS > 0 )\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n }\n #pragma unroll_loop_end\n #endif\n#endif\n#if defined( RE_IndirectSpecular )\n vec3 radiance = vec3( 0.0 );\n vec3 clearcoatRadiance = vec3( 0.0 );\n#endif"; var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n #ifdef USE_LIGHTMAP\n vec4 lightMapTexel = texture2D( lightMap, vUv2 );\n vec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n #ifndef PHYSICALLY_CORRECT_LIGHTS\n lightMapIrradiance *= PI;\n #endif\n irradiance += lightMapIrradiance;\n #endif\n #if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n iblIrradiance += getIBLIrradiance( geometry );\n #endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n radiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\n #ifdef USE_CLEARCOAT\n clearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\n #endif\n#endif"; var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif"; var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n gl_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 uniform float logDepthBufFC;\n varying float vFragDepth;\n varying float vIsPerspective;\n#endif"; var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n #ifdef USE_LOGDEPTHBUF_EXT\n varying float vFragDepth;\n varying float vIsPerspective;\n #else\n uniform float logDepthBufFC;\n #endif\n#endif"; var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n #ifdef USE_LOGDEPTHBUF_EXT\n vFragDepth = 1.0 + gl_Position.w;\n vIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n #else\n if ( isPerspectiveMatrix( projectionMatrix ) ) {\n gl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n gl_Position.z *= gl_Position.w;\n }\n #endif\n#endif"; var map_fragment = "#ifdef USE_MAP\n vec4 texelColor = texture2D( map, vUv );\n texelColor = mapTexelToLinear( texelColor );\n diffuseColor *= texelColor;\n#endif"; var map_pars_fragment = "#ifdef USE_MAP\n uniform sampler2D map;\n#endif"; var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n vec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n vec4 mapTexel = texture2D( map, uv );\n diffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n#ifdef USE_ALPHAMAP\n diffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif"; var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n uniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n uniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n uniform sampler2D alphaMap;\n#endif"; var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n vec4 texelMetalness = texture2D( metalnessMap, vUv );\n metalnessFactor *= texelMetalness.b;\n#endif"; var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n uniform sampler2D metalnessMap;\n#endif"; var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n objectNormal *= morphTargetBaseInfluence;\n objectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n objectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n objectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n objectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n#endif"; var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n uniform float morphTargetBaseInfluence;\n #ifndef USE_MORPHNORMALS\n uniform float morphTargetInfluences[ 8 ];\n #else\n uniform float morphTargetInfluences[ 4 ];\n #endif\n#endif"; var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n transformed *= morphTargetBaseInfluence;\n transformed += morphTarget0 * morphTargetInfluences[ 0 ];\n transformed += morphTarget1 * morphTargetInfluences[ 1 ];\n transformed += morphTarget2 * morphTargetInfluences[ 2 ];\n transformed += morphTarget3 * morphTargetInfluences[ 3 ];\n #ifndef USE_MORPHNORMALS\n transformed += morphTarget4 * morphTargetInfluences[ 4 ];\n transformed += morphTarget5 * morphTargetInfluences[ 5 ];\n transformed += morphTarget6 * morphTargetInfluences[ 6 ];\n transformed += morphTarget7 * morphTargetInfluences[ 7 ];\n #endif\n#endif"; var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n vec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n vec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n vec3 normal = normalize( cross( fdx, fdy ) );\n#else\n vec3 normal = normalize( vNormal );\n #ifdef DOUBLE_SIDED\n normal = normal * faceDirection;\n #endif\n #ifdef USE_TANGENT\n vec3 tangent = normalize( vTangent );\n vec3 bitangent = normalize( vBitangent );\n #ifdef DOUBLE_SIDED\n tangent = tangent * faceDirection;\n bitangent = bitangent * faceDirection;\n #endif\n #if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n mat3 vTBN = mat3( tangent, bitangent, normal );\n #endif\n #endif\n#endif\nvec3 geometryNormal = normal;"; var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n normal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n #ifdef FLIP_SIDED\n normal = - normal;\n #endif\n #ifdef DOUBLE_SIDED\n normal = normal * faceDirection;\n #endif\n normal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n mapN.xy *= normalScale;\n #ifdef USE_TANGENT\n normal = normalize( vTBN * mapN );\n #else\n normal = perturbNormal2Arb( - vViewPosition, normal, mapN, faceDirection );\n #endif\n#elif defined( USE_BUMPMAP )\n normal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif"; var normal_pars_fragment = "#ifndef FLAT_SHADED\n varying vec3 vNormal;\n #ifdef USE_TANGENT\n varying vec3 vTangent;\n varying vec3 vBitangent;\n #endif\n#endif"; var normal_pars_vertex = "#ifndef FLAT_SHADED\n varying vec3 vNormal;\n #ifdef USE_TANGENT\n varying vec3 vTangent;\n varying vec3 vBitangent;\n #endif\n#endif"; var normal_vertex = "#ifndef FLAT_SHADED\n vNormal = normalize( transformedNormal );\n #ifdef USE_TANGENT\n vTangent = normalize( transformedTangent );\n vBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n #endif\n#endif"; var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n uniform sampler2D normalMap;\n uniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n uniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection ) {\n vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n vec2 st0 = dFdx( vUv.st );\n vec2 st1 = dFdy( vUv.st );\n vec3 N = surf_norm;\n vec3 q1perp = cross( q1, N );\n vec3 q0perp = cross( N, q0 );\n vec3 T = q1perp * st0.x + q0perp * st1.x;\n vec3 B = q1perp * st0.y + q0perp * st1.y;\n float det = max( dot( T, T ), dot( B, B ) );\n float scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );\n return normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );\n }\n#endif"; var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n vec3 clearcoatNormal = geometryNormal;\n#endif"; var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n vec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n clearcoatMapN.xy *= clearcoatNormalScale;\n #ifdef USE_TANGENT\n clearcoatNormal = normalize( vTBN * clearcoatMapN );\n #else\n clearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN, faceDirection );\n #endif\n#endif"; var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n uniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n uniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n uniform sampler2D clearcoatNormalMap;\n uniform vec2 clearcoatNormalScale;\n#endif"; var output_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );"; var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n return normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n return 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 vec4 r = vec4( fract( v * PackFactors ), v );\n r.yzw -= r.xyz * ShiftRight8; return r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n return dot( v, UnpackFactors );\n}\nvec4 pack2HalfToRGBA( vec2 v ) {\n vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\n return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n return 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 return ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n return linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n return ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n return ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif"; var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n mvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;"; var dithering_fragment = "#ifdef DITHERING\n gl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; var dithering_pars_fragment = "#ifdef DITHERING\n vec3 dithering( vec3 color ) {\n float grid_position = rand( gl_FragCoord.xy );\n vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n return color + dither_shift_RGB;\n }\n#endif"; var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n vec4 texelRoughness = texture2D( roughnessMap, vUv );\n roughnessFactor *= texelRoughness.g;\n#endif"; var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n uniform sampler2D roughnessMap;\n#endif"; var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHT_SHADOWS > 0\n uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n struct DirectionalLightShadow {\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n struct SpotLightShadow {\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n uniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n struct PointLightShadow {\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n float shadowCameraNear;\n float shadowCameraFar;\n };\n uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n float texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n }\n vec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n return unpackRGBATo2Half( texture2D( shadow, uv ) );\n }\n float VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n float occlusion = 1.0;\n vec2 distribution = texture2DDistribution( shadow, uv );\n float hard_shadow = step( compare , distribution.x );\n if (hard_shadow != 1.0 ) {\n float distance = compare - distribution.x ;\n float variance = max( 0.00000, distribution.y * distribution.y );\n float softness_probability = variance / (variance + distance * distance ); softness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 ); occlusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n }\n return occlusion;\n }\n float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n shadowCoord.z += shadowBias;\n bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n bool inFrustum = all( inFrustumVec );\n bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n bool frustumTest = all( frustumTestVec );\n if ( frustumTest ) {\n #if defined( SHADOWMAP_TYPE_PCF )\n vec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n float dx0 = - texelSize.x * shadowRadius;\n float dy0 = - texelSize.y * shadowRadius;\n float dx1 = + texelSize.x * shadowRadius;\n float dy1 = + texelSize.y * shadowRadius;\n float dx2 = dx0 / 2.0;\n float dy2 = dy0 / 2.0;\n float dx3 = dx1 / 2.0;\n float dy3 = dy1 / 2.0;\n shadow = (\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n ) * ( 1.0 / 17.0 );\n #elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n vec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n float dx = texelSize.x;\n float dy = texelSize.y;\n vec2 uv = shadowCoord.xy;\n vec2 f = fract( uv * shadowMapSize + 0.5 );\n uv -= f * texelSize;\n shadow = (\n texture2DCompare( shadowMap, uv, shadowCoord.z ) +\n texture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n texture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n mix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n f.x ) +\n mix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n f.x ) +\n mix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n f.y ) +\n mix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n f.y ) +\n mix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n f.x ),\n mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n f.x ),\n f.y )\n ) * ( 1.0 / 9.0 );\n #elif defined( SHADOWMAP_TYPE_VSM )\n shadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n #else\n shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n #endif\n }\n return shadow;\n }\n vec2 cubeToUV( vec3 v, float texelSizeY ) {\n vec3 absV = abs( v );\n float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n absV *= scaleToCube;\n v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n vec2 planar = v.xy;\n float almostATexel = 1.5 * texelSizeY;\n float almostOne = 1.0 - almostATexel;\n if ( absV.z >= almostOne ) {\n if ( v.z > 0.0 )\n planar.x = 4.0 - v.x;\n } else if ( absV.x >= almostOne ) {\n float signX = sign( v.x );\n planar.x = v.z * signX + 2.0 * signX;\n } else if ( absV.y >= almostOne ) {\n float signY = sign( v.y );\n planar.x = v.x + 2.0 * signY + 2.0;\n planar.y = v.z * signY - 2.0;\n }\n return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n }\n float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n vec3 lightToPosition = shadowCoord.xyz;\n float dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); dp += shadowBias;\n vec3 bd3D = normalize( lightToPosition );\n #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n return (\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n ) * ( 1.0 / 9.0 );\n #else\n return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n #endif\n }\n#endif"; var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHT_SHADOWS > 0\n uniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n struct DirectionalLightShadow {\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n uniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n struct SpotLightShadow {\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n uniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n struct PointLightShadow {\n float shadowBias;\n float shadowNormalBias;\n float shadowRadius;\n vec2 shadowMapSize;\n float shadowCameraNear;\n float shadowCameraFar;\n };\n uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n #endif\n#endif"; var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0\n vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n vec4 shadowWorldPosition;\n #endif\n #if NUM_DIR_LIGHT_SHADOWS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );\n vSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n vPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\n #endif\n#endif"; var shadowmask_pars_fragment = "float getShadowMask() {\n float shadow = 1.0;\n #ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHT_SHADOWS > 0\n DirectionalLightShadow directionalLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n directionalLight = directionalLightShadows[ i ];\n shadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_SPOT_LIGHT_SHADOWS > 0\n SpotLightShadow spotLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n spotLight = spotLightShadows[ i ];\n shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #if NUM_POINT_LIGHT_SHADOWS > 0\n PointLightShadow pointLight;\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n pointLight = pointLightShadows[ i ];\n shadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n }\n #pragma unroll_loop_end\n #endif\n #endif\n return shadow;\n}"; var skinbase_vertex = "#ifdef USE_SKINNING\n mat4 boneMatX = getBoneMatrix( skinIndex.x );\n mat4 boneMatY = getBoneMatrix( skinIndex.y );\n mat4 boneMatZ = getBoneMatrix( skinIndex.z );\n mat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; var skinning_pars_vertex = "#ifdef USE_SKINNING\n uniform mat4 bindMatrix;\n uniform mat4 bindMatrixInverse;\n #ifdef BONE_TEXTURE\n uniform highp sampler2D boneTexture;\n uniform int boneTextureSize;\n mat4 getBoneMatrix( const in float i ) {\n float j = i * 4.0;\n float x = mod( j, float( boneTextureSize ) );\n float y = floor( j / float( boneTextureSize ) );\n float dx = 1.0 / float( boneTextureSize );\n float dy = 1.0 / float( boneTextureSize );\n y = dy * ( y + 0.5 );\n vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n mat4 bone = mat4( v1, v2, v3, v4 );\n return bone;\n }\n #else\n uniform mat4 boneMatrices[ MAX_BONES ];\n mat4 getBoneMatrix( const in float i ) {\n mat4 bone = boneMatrices[ int(i) ];\n return bone;\n }\n #endif\n#endif"; var skinning_vertex = "#ifdef USE_SKINNING\n vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n vec4 skinned = vec4( 0.0 );\n skinned += boneMatX * skinVertex * skinWeight.x;\n skinned += boneMatY * skinVertex * skinWeight.y;\n skinned += boneMatZ * skinVertex * skinWeight.z;\n skinned += boneMatW * skinVertex * skinWeight.w;\n transformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; var skinnormal_vertex = "#ifdef USE_SKINNING\n mat4 skinMatrix = mat4( 0.0 );\n skinMatrix += skinWeight.x * boneMatX;\n skinMatrix += skinWeight.y * boneMatY;\n skinMatrix += skinWeight.z * boneMatZ;\n skinMatrix += skinWeight.w * boneMatW;\n skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n #ifdef USE_TANGENT\n objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n #endif\n#endif"; var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n vec4 texelSpecular = texture2D( specularMap, vUv );\n specularStrength = texelSpecular.r;\n#else\n specularStrength = 1.0;\n#endif"; var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n uniform sampler2D specularMap;\n#endif"; var tonemapping_fragment = "#if defined( TONE_MAPPING )\n gl_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;\nvec3 LinearToneMapping( vec3 color ) {\n return toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n return saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n color = max( vec3( 0.0 ), color - 0.004 );\n return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n vec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n return a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n const mat3 ACESInputMat = mat3(\n vec3( 0.59719, 0.07600, 0.02840 ), vec3( 0.35458, 0.90834, 0.13383 ),\n vec3( 0.04823, 0.01566, 0.83777 )\n );\n const mat3 ACESOutputMat = mat3(\n vec3( 1.60475, -0.10208, -0.00327 ), vec3( -0.53108, 1.10813, -0.07276 ),\n vec3( -0.07367, -0.00605, 1.07602 )\n );\n color *= toneMappingExposure / 0.6;\n color = ACESInputMat * color;\n color = RRTAndODTFit( color );\n color = ACESOutputMat * color;\n return saturate( color );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }"; var transmission_fragment = "#ifdef USE_TRANSMISSION\n float transmissionAlpha = 1.0;\n float transmissionFactor = transmission;\n float thicknessFactor = thickness;\n #ifdef USE_TRANSMISSIONMAP\n transmissionFactor *= texture2D( transmissionMap, vUv ).r;\n #endif\n #ifdef USE_THICKNESSMAP\n thicknessFactor *= texture2D( thicknessMap, vUv ).g;\n #endif\n vec3 pos = vWorldPosition;\n vec3 v = normalize( cameraPosition - pos );\n vec3 n = inverseTransformDirection( normal, viewMatrix );\n vec4 transmission = getIBLVolumeRefraction(\n n, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,\n pos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,\n attenuationTint, attenuationDistance );\n totalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );\n transmissionAlpha = transmission.a;\n#endif"; var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n uniform float transmission;\n uniform float thickness;\n uniform float attenuationDistance;\n uniform vec3 attenuationTint;\n #ifdef USE_TRANSMISSIONMAP\n uniform sampler2D transmissionMap;\n #endif\n #ifdef USE_THICKNESSMAP\n uniform sampler2D thicknessMap;\n #endif\n uniform vec2 transmissionSamplerSize;\n uniform sampler2D transmissionSamplerMap;\n uniform mat4 modelMatrix;\n uniform mat4 projectionMatrix;\n varying vec3 vWorldPosition;\n vec3 getVolumeTransmissionRay( vec3 n, vec3 v, float thickness, float ior, mat4 modelMatrix ) {\n vec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n vec3 modelScale;\n modelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n modelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n modelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n return normalize( refractionVector ) * thickness * modelScale;\n }\n float applyIorToRoughness( float roughness, float ior ) {\n return roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n }\n vec4 getTransmissionSample( vec2 fragCoord, float roughness, float ior ) {\n float framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n #ifdef TEXTURE_LOD_EXT\n return texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n #else\n return texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n #endif\n }\n vec3 applyVolumeAttenuation( vec3 radiance, float transmissionDistance, vec3 attenuationColor, float attenuationDistance ) {\n if ( attenuationDistance == 0.0 ) {\n return radiance;\n } else {\n vec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n vec3 transmittance = exp( - attenuationCoefficient * transmissionDistance ); return transmittance * radiance;\n }\n }\n vec4 getIBLVolumeRefraction( vec3 n, vec3 v, float roughness, vec3 diffuseColor, vec3 specularColor, float specularF90,\n vec3 position, mat4 modelMatrix, mat4 viewMatrix, mat4 projMatrix, float ior, float thickness,\n vec3 attenuationColor, float attenuationDistance ) {\n vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n vec3 refractedRayExit = position + transmissionRay;\n vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n vec2 refractionCoords = ndcPos.xy / ndcPos.w;\n refractionCoords += 1.0;\n refractionCoords /= 2.0;\n vec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n vec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n vec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n return vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n }\n#endif"; var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n varying vec2 vUv;\n#endif"; var uv_pars_vertex = "#ifdef USE_UV\n #ifdef UVS_VERTEX_ONLY\n vec2 vUv;\n #else\n varying vec2 vUv;\n #endif\n uniform mat3 uvTransform;\n#endif"; var uv_vertex = "#ifdef USE_UV\n vUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n varying vec2 vUv2;\n#endif"; var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n attribute vec2 uv2;\n varying vec2 vUv2;\n uniform mat3 uv2Transform;\n#endif"; var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n vUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )\n vec4 worldPosition = vec4( transformed, 1.0 );\n #ifdef USE_INSTANCING\n worldPosition = instanceMatrix * worldPosition;\n #endif\n worldPosition = modelMatrix * worldPosition;\n#endif"; var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n vec4 texColor = texture2D( t2D, vUv );\n gl_FragColor = mapTexelToLinear( texColor );\n #include \n #include \n}"; var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n vUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n gl_Position = vec4( position.xy, 1.0, 1.0 );\n}"; var cube_frag = "#include \nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n vec3 vReflect = vWorldDirection;\n #include \n gl_FragColor = envColor;\n gl_FragColor.a *= opacity;\n #include \n #include \n}"; var cube_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n vWorldDirection = transformDirection( position, modelMatrix );\n #include \n #include \n gl_Position.z = gl_Position.w;\n}"; var depth_frag = "#if DEPTH_PACKING == 3200\n uniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n #include \n vec4 diffuseColor = vec4( 1.0 );\n #if DEPTH_PACKING == 3200\n diffuseColor.a = opacity;\n #endif\n #include \n #include \n #include \n #include \n float fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n #if DEPTH_PACKING == 3200\n gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n #elif DEPTH_PACKING == 3201\n gl_FragColor = packDepthToRGBA( fragCoordZ );\n #endif\n}"; var depth_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n #include \n #include \n #ifdef USE_DISPLACEMENTMAP\n #include \n #include \n #include \n #endif\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vHighPrecisionZW = gl_Position.zw;\n}"; var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n #include \n vec4 diffuseColor = vec4( 1.0 );\n #include \n #include \n #include \n float dist = length( vWorldPosition - referencePosition );\n dist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n dist = saturate( dist );\n gl_FragColor = packDepthToRGBA( dist );\n}"; var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #ifdef USE_DISPLACEMENTMAP\n #include \n #include \n #include \n #endif\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vWorldPosition = worldPosition.xyz;\n}"; var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n vec3 direction = normalize( vWorldDirection );\n vec2 sampleUV = equirectUv( direction );\n vec4 texColor = texture2D( tEquirect, sampleUV );\n gl_FragColor = mapTexelToLinear( texColor );\n #include \n #include \n}"; var equirect_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n vWorldDirection = transformDirection( position, modelMatrix );\n #include \n #include \n}"; var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n if ( mod( vLineDistance, totalSize ) > dashSize ) {\n discard;\n }\n vec3 outgoingLight = vec3( 0.0 );\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include \n #include \n outgoingLight = diffuseColor.rgb;\n #include \n #include \n #include \n #include \n #include \n}"; var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n vLineDistance = scale * lineDistance;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n}"; var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n varying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( diffuse, opacity );\n #include \n #include \n #include \n #include \n #include \n #include \n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n #ifdef USE_LIGHTMAP\n vec4 lightMapTexel= texture2D( lightMap, vUv2 );\n reflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n #else\n reflectedLight.indirectDiffuse += vec3( 1.0 );\n #endif\n #include \n reflectedLight.indirectDiffuse *= diffuseColor.rgb;\n vec3 outgoingLight = reflectedLight.indirectDiffuse;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n}"; var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n #include \n #include \n #include \n #include \n #include \n #endif\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n}"; var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n varying vec3 vLightBack;\n varying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( diffuse, opacity );\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #ifdef DOUBLE_SIDED\n reflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n #else\n reflectedLight.indirectDiffuse += vIndirectFront;\n #endif\n #include \n reflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb );\n #ifdef DOUBLE_SIDED\n reflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n #else\n reflectedLight.directDiffuse = vLightFront;\n #endif\n reflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask();\n #include \n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n}"; var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n varying vec3 vLightBack;\n varying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n}"; var meshmatcap_frag = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( diffuse, opacity );\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vec3 viewDir = normalize( vViewPosition );\n vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n vec3 y = cross( viewDir, x );\n vec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n #ifdef USE_MATCAP\n vec4 matcapColor = texture2D( matcap, uv );\n matcapColor = matcapTexelToLinear( matcapColor );\n #else\n vec4 matcapColor = vec4( 1.0 );\n #endif\n vec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n #include \n #include \n #include \n #include \n #include \n #include \n}"; var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vViewPosition = - mvPosition.xyz;\n}"; var meshnormal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n varying vec3 vViewPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n gl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; var meshnormal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n varying vec3 vViewPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n vViewPosition = - mvPosition.xyz;\n#endif\n}"; var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( diffuse, opacity );\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n}"; var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vViewPosition = - mvPosition.xyz;\n #include \n #include \n #include \n #include \n}"; var meshphysical_frag = "#define STANDARD\n#ifdef PHYSICAL\n #define IOR\n #define SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n uniform float ior;\n#endif\n#ifdef SPECULAR\n uniform float specularIntensity;\n uniform vec3 specularTint;\n #ifdef USE_SPECULARINTENSITYMAP\n uniform sampler2D specularIntensityMap;\n #endif\n #ifdef USE_SPECULARTINTMAP\n uniform sampler2D specularTintMap;\n #endif\n#endif\n#ifdef USE_CLEARCOAT\n uniform float clearcoat;\n uniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n uniform vec3 sheenTint;\n#endif\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( diffuse, opacity );\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n vec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n #include \n vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n #ifdef USE_CLEARCOAT\n float dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n vec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n outgoingLight = outgoingLight * ( 1.0 - clearcoat * Fcc ) + clearcoatSpecular * clearcoat;\n #endif\n #include \n #include \n #include \n #include \n #include \n #include \n}"; var meshphysical_vert = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n varying vec3 vWorldPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vViewPosition = - mvPosition.xyz;\n #include \n #include \n #include \n#ifdef USE_TRANSMISSION\n vWorldPosition = worldPosition.xyz;\n#endif\n}"; var meshtoon_frag = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( diffuse, opacity );\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n #include \n #include \n #include \n #include \n #include \n #include \n}"; var meshtoon_vert = "#define TOON\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vViewPosition = - mvPosition.xyz;\n #include \n #include \n #include \n}"; var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec3 outgoingLight = vec3( 0.0 );\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include \n #include \n #include \n #include \n outgoingLight = diffuseColor.rgb;\n #include \n #include \n #include \n #include \n #include \n}"; var points_vert = "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n gl_PointSize = size;\n #ifdef USE_SIZEATTENUATION\n bool isPerspective = isPerspectiveMatrix( projectionMatrix );\n if ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n #endif\n #include \n #include \n #include \n #include \n}"; var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n gl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n #include \n #include \n #include \n}"; var shadow_vert = "#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n}"; var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec3 outgoingLight = vec3( 0.0 );\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include \n #include \n #include \n #include \n outgoingLight = diffuseColor.rgb;\n #include \n #include \n #include \n #include \n}"; var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n vec2 scale;\n scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n #ifndef USE_SIZEATTENUATION\n bool isPerspective = isPerspectiveMatrix( projectionMatrix );\n if ( isPerspective ) scale *= - mvPosition.z;\n #endif\n vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n vec2 rotatedPosition;\n rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n mvPosition.xy += rotatedPosition;\n gl_Position = projectionMatrix * mvPosition;\n #include \n #include \n #include \n}"; var ShaderChunk = { alphamap_fragment, alphamap_pars_fragment, alphatest_fragment, alphatest_pars_fragment, aomap_fragment, aomap_pars_fragment, begin_vertex, beginnormal_vertex, bsdfs, bumpmap_pars_fragment, clipping_planes_fragment, clipping_planes_pars_fragment, clipping_planes_pars_vertex, clipping_planes_vertex, color_fragment, color_pars_fragment, color_pars_vertex, color_vertex, common, cube_uv_reflection_fragment, defaultnormal_vertex, displacementmap_pars_vertex, displacementmap_vertex, emissivemap_fragment, emissivemap_pars_fragment, encodings_fragment, encodings_pars_fragment, envmap_fragment, envmap_common_pars_fragment, envmap_pars_fragment, envmap_pars_vertex, envmap_physical_pars_fragment, envmap_vertex, fog_vertex, fog_pars_vertex, fog_fragment, fog_pars_fragment, gradientmap_pars_fragment, lightmap_fragment, lightmap_pars_fragment, lights_lambert_vertex, lights_pars_begin, lights_toon_fragment, lights_toon_pars_fragment, lights_phong_fragment, lights_phong_pars_fragment, lights_physical_fragment, lights_physical_pars_fragment, lights_fragment_begin, lights_fragment_maps, lights_fragment_end, logdepthbuf_fragment, logdepthbuf_pars_fragment, logdepthbuf_pars_vertex, logdepthbuf_vertex, map_fragment, map_pars_fragment, map_particle_fragment, map_particle_pars_fragment, metalnessmap_fragment, metalnessmap_pars_fragment, morphnormal_vertex, morphtarget_pars_vertex, morphtarget_vertex, normal_fragment_begin, normal_fragment_maps, normal_pars_fragment, normal_pars_vertex, normal_vertex, normalmap_pars_fragment, clearcoat_normal_fragment_begin, clearcoat_normal_fragment_maps, clearcoat_pars_fragment, output_fragment, packing, premultiplied_alpha_fragment, project_vertex, dithering_fragment, dithering_pars_fragment, roughnessmap_fragment, roughnessmap_pars_fragment, shadowmap_pars_fragment, shadowmap_pars_vertex, shadowmap_vertex, shadowmask_pars_fragment, skinbase_vertex, skinning_pars_vertex, skinning_vertex, skinnormal_vertex, specularmap_fragment, specularmap_pars_fragment, tonemapping_fragment, tonemapping_pars_fragment, transmission_fragment, transmission_pars_fragment, uv_pars_fragment, uv_pars_vertex, uv_vertex, uv2_pars_fragment, uv2_pars_vertex, uv2_vertex, worldpos_vertex, background_frag, background_vert, cube_frag, cube_vert, depth_frag, depth_vert, distanceRGBA_frag, distanceRGBA_vert, equirect_frag, equirect_vert, linedashed_frag, linedashed_vert, meshbasic_frag, meshbasic_vert, meshlambert_frag, meshlambert_vert, meshmatcap_frag, meshmatcap_vert, meshnormal_frag, meshnormal_vert, meshphong_frag, meshphong_vert, meshphysical_frag, meshphysical_vert, meshtoon_frag, meshtoon_vert, points_frag, points_vert, shadow_frag, shadow_vert, sprite_frag, sprite_vert }; var UniformsLib = { common: { diffuse: { value: new Color(16777215) }, opacity: { value: 1 }, map: { value: null }, uvTransform: { value: new Matrix3() }, uv2Transform: { value: new Matrix3() }, alphaMap: { value: null }, alphaTest: { value: 0 } }, specularmap: { specularMap: { value: null } }, envmap: { envMap: { value: null }, flipEnvMap: { value: -1 }, reflectivity: { value: 1 }, ior: { value: 1.5 }, 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: 25e-5 }, fogNear: { value: 1 }, fogFar: { value: 2e3 }, fogColor: { value: new Color(16777215) } }, lights: { ambientLightColor: { value: [] }, lightProbe: { value: [] }, directionalLights: { value: [], properties: { direction: {}, color: {} } }, directionalLightShadows: { value: [], properties: { shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {} } }, directionalShadowMap: { value: [] }, directionalShadowMatrix: { value: [] }, spotLights: { value: [], properties: { color: {}, position: {}, direction: {}, distance: {}, coneCos: {}, penumbraCos: {}, decay: {} } }, spotLightShadows: { value: [], properties: { shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {} } }, spotShadowMap: { value: [] }, spotShadowMatrix: { value: [] }, pointLights: { value: [], properties: { color: {}, position: {}, decay: {}, distance: {} } }, pointLightShadows: { value: [], properties: { shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {}, shadowCameraNear: {}, shadowCameraFar: {} } }, pointShadowMap: { value: [] }, pointShadowMatrix: { value: [] }, hemisphereLights: { value: [], properties: { direction: {}, skyColor: {}, groundColor: {} } }, rectAreaLights: { value: [], properties: { color: {}, position: {}, width: {}, height: {} } }, ltc_1: { value: null }, ltc_2: { value: null } }, points: { diffuse: { value: new Color(16777215) }, opacity: { value: 1 }, size: { value: 1 }, scale: { value: 1 }, map: { value: null }, alphaMap: { value: null }, alphaTest: { value: 0 }, uvTransform: { value: new Matrix3() } }, sprite: { diffuse: { value: new Color(16777215) }, opacity: { value: 1 }, center: { value: new Vector2(0.5, 0.5) }, rotation: { value: 0 }, map: { value: null }, alphaMap: { value: null }, alphaTest: { value: 0 }, uvTransform: { value: new Matrix3() } } }; 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(0) } } ]), 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(0) }, specular: { value: new Color(1118481) }, 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(0) }, roughness: { value: 1 }, metalness: { value: 0 }, envMapIntensity: { value: 1 } } ]), vertexShader: ShaderChunk.meshphysical_vert, fragmentShader: ShaderChunk.meshphysical_frag }, toon: { uniforms: mergeUniforms([ UniformsLib.common, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.gradientmap, UniformsLib.fog, UniformsLib.lights, { emissive: { value: new Color(0) } } ]), 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 } } ]), vertexShader: ShaderChunk.meshnormal_vert, fragmentShader: ShaderChunk.meshnormal_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: { uniforms: mergeUniforms([ UniformsLib.envmap, { opacity: { value: 1 } } ]), 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: 1e3 } } ]), vertexShader: ShaderChunk.distanceRGBA_vert, fragmentShader: ShaderChunk.distanceRGBA_frag }, shadow: { uniforms: mergeUniforms([ UniformsLib.lights, UniformsLib.fog, { color: { value: new Color(0) }, opacity: { value: 1 } } ]), 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 }, sheenTint: { value: new Color(0) }, transmission: { value: 0 }, transmissionMap: { value: null }, transmissionSamplerSize: { value: new Vector2() }, transmissionSamplerMap: { value: null }, thickness: { value: 0 }, thicknessMap: { value: null }, attenuationDistance: { value: 0 }, attenuationTint: { value: new Color(0) }, specularIntensity: { value: 0 }, specularIntensityMap: { value: null }, specularTint: { value: new Color(1, 1, 1) }, specularTintMap: { value: null } } ]), vertexShader: ShaderChunk.meshphysical_vert, fragmentShader: ShaderChunk.meshphysical_frag }; function WebGLBackground(renderer, cubemaps, state, objects, premultipliedAlpha) { const clearColor = new Color(0); let clearAlpha = 0; let planeMesh; let boxMesh; let currentBackground = null; let currentBackgroundVersion = 0; let currentTonemapping = null; function render(renderList, scene) { let forceClear = false; let background = scene.isScene === true ? scene.background : null; if (background && background.isTexture) { background = cubemaps.get(background); } const xr = renderer.xr; const 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.mapping === CubeUVReflectionMapping)) { if (boxMesh === void 0) { boxMesh = new Mesh(new BoxGeometry(1, 1, 1), new ShaderMaterial({ name: "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(renderer2, scene2, camera) { this.matrixWorld.copyPosition(camera.matrixWorld); }; Object.defineProperty(boxMesh.material, "envMap", { get: function() { return this.uniforms.envMap.value; } }); objects.update(boxMesh); } boxMesh.material.uniforms.envMap.value = background; boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background.isRenderTargetTexture === false ? -1 : 1; if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) { boxMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = background.version; currentTonemapping = renderer.toneMapping; } renderList.unshift(boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null); } else if (background && background.isTexture) { if (planeMesh === void 0) { planeMesh = new Mesh(new PlaneGeometry(2, 2), new ShaderMaterial({ name: "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"); 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; } 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 = 1) { clearColor.set(color); clearAlpha = alpha; setClear(clearColor, clearAlpha); }, getClearAlpha: function() { return clearAlpha; }, setClearAlpha: function(alpha) { clearAlpha = alpha; setClear(clearColor, clearAlpha); }, render }; } function WebGLBindingStates(gl, extensions, attributes, capabilities) { const maxVertexAttributes = gl.getParameter(34921); const extension = capabilities.isWebGL2 ? null : extensions.get("OES_vertex_array_object"); const vaoAvailable = capabilities.isWebGL2 || extension !== null; const bindingStates = {}; const defaultState = createBindingState(null); let currentState = defaultState; function setup(object, material, program, geometry, index) { let updateBuffers = false; if (vaoAvailable) { const state = getBindingState(geometry, program, material); if (currentState !== state) { currentState = state; bindVertexArrayObject(currentState.object); } updateBuffers = needsUpdate(geometry, index); if (updateBuffers) saveCache(geometry, index); } else { const wireframe = material.wireframe === true; if (currentState.geometry !== geometry.id || currentState.program !== program.id || currentState.wireframe !== wireframe) { currentState.geometry = geometry.id; currentState.program = program.id; currentState.wireframe = wireframe; updateBuffers = true; } } if (object.isInstancedMesh === true) { updateBuffers = true; } if (index !== null) { attributes.update(index, 34963); } if (updateBuffers) { setupVertexAttributes(object, material, program, geometry); if (index !== null) { gl.bindBuffer(34963, attributes.get(index).buffer); } } } function createVertexArrayObject() { if (capabilities.isWebGL2) return gl.createVertexArray(); return extension.createVertexArrayOES(); } function bindVertexArrayObject(vao) { if (capabilities.isWebGL2) return gl.bindVertexArray(vao); return extension.bindVertexArrayOES(vao); } function deleteVertexArrayObject(vao) { if (capabilities.isWebGL2) return gl.deleteVertexArray(vao); return extension.deleteVertexArrayOES(vao); } function getBindingState(geometry, program, material) { const wireframe = material.wireframe === true; let programMap = bindingStates[geometry.id]; if (programMap === void 0) { programMap = {}; bindingStates[geometry.id] = programMap; } let stateMap = programMap[program.id]; if (stateMap === void 0) { stateMap = {}; programMap[program.id] = stateMap; } let state = stateMap[wireframe]; if (state === void 0) { state = createBindingState(createVertexArrayObject()); stateMap[wireframe] = state; } return state; } function createBindingState(vao) { const newAttributes = []; const enabledAttributes = []; const attributeDivisors = []; for (let i = 0; i < maxVertexAttributes; i++) { newAttributes[i] = 0; enabledAttributes[i] = 0; attributeDivisors[i] = 0; } return { geometry: null, program: null, wireframe: false, newAttributes, enabledAttributes, attributeDivisors, object: vao, attributes: {}, index: null }; } function needsUpdate(geometry, index) { const cachedAttributes = currentState.attributes; const geometryAttributes = geometry.attributes; let attributesNum = 0; for (const key in geometryAttributes) { const cachedAttribute = cachedAttributes[key]; const geometryAttribute = geometryAttributes[key]; if (cachedAttribute === void 0) return true; if (cachedAttribute.attribute !== geometryAttribute) return true; if (cachedAttribute.data !== geometryAttribute.data) return true; attributesNum++; } if (currentState.attributesNum !== attributesNum) return true; if (currentState.index !== index) return true; return false; } function saveCache(geometry, index) { const cache = {}; const attributes2 = geometry.attributes; let attributesNum = 0; for (const key in attributes2) { const attribute = attributes2[key]; const data = {}; data.attribute = attribute; if (attribute.data) { data.data = attribute.data; } cache[key] = data; attributesNum++; } currentState.attributes = cache; currentState.attributesNum = attributesNum; currentState.index = index; } function initAttributes() { const newAttributes = currentState.newAttributes; for (let i = 0, il = newAttributes.length; i < il; i++) { newAttributes[i] = 0; } } function enableAttribute(attribute) { enableAttributeAndDivisor(attribute, 0); } function enableAttributeAndDivisor(attribute, meshPerAttribute) { const newAttributes = currentState.newAttributes; const enabledAttributes = currentState.enabledAttributes; const attributeDivisors = currentState.attributeDivisors; newAttributes[attribute] = 1; if (enabledAttributes[attribute] === 0) { gl.enableVertexAttribArray(attribute); enabledAttributes[attribute] = 1; } if (attributeDivisors[attribute] !== meshPerAttribute) { const extension2 = capabilities.isWebGL2 ? gl : extensions.get("ANGLE_instanced_arrays"); extension2[capabilities.isWebGL2 ? "vertexAttribDivisor" : "vertexAttribDivisorANGLE"](attribute, meshPerAttribute); attributeDivisors[attribute] = meshPerAttribute; } } function disableUnusedAttributes() { const newAttributes = currentState.newAttributes; const enabledAttributes = currentState.enabledAttributes; for (let i = 0, il = enabledAttributes.length; i < il; i++) { if (enabledAttributes[i] !== newAttributes[i]) { gl.disableVertexAttribArray(i); enabledAttributes[i] = 0; } } } function vertexAttribPointer(index, size, type, normalized, stride, offset) { if (capabilities.isWebGL2 === true && (type === 5124 || type === 5125)) { gl.vertexAttribIPointer(index, size, type, stride, offset); } else { gl.vertexAttribPointer(index, size, type, normalized, stride, offset); } } function setupVertexAttributes(object, material, program, geometry) { if (capabilities.isWebGL2 === false && (object.isInstancedMesh || geometry.isInstancedBufferGeometry)) { if (extensions.get("ANGLE_instanced_arrays") === null) return; } initAttributes(); const geometryAttributes = geometry.attributes; const programAttributes = program.getAttributes(); const materialDefaultAttributeValues = material.defaultAttributeValues; for (const name in programAttributes) { const programAttribute = programAttributes[name]; if (programAttribute.location >= 0) { let geometryAttribute = geometryAttributes[name]; if (geometryAttribute === void 0) { if (name === "instanceMatrix" && object.instanceMatrix) geometryAttribute = object.instanceMatrix; if (name === "instanceColor" && object.instanceColor) geometryAttribute = object.instanceColor; } if (geometryAttribute !== void 0) { const normalized = geometryAttribute.normalized; const size = geometryAttribute.itemSize; const attribute = attributes.get(geometryAttribute); if (attribute === void 0) continue; const buffer = attribute.buffer; const type = attribute.type; const bytesPerElement = attribute.bytesPerElement; if (geometryAttribute.isInterleavedBufferAttribute) { const data = geometryAttribute.data; const stride = data.stride; const offset = geometryAttribute.offset; if (data && data.isInstancedInterleavedBuffer) { for (let i = 0; i < programAttribute.locationSize; i++) { enableAttributeAndDivisor(programAttribute.location + i, data.meshPerAttribute); } if (object.isInstancedMesh !== true && geometry._maxInstanceCount === void 0) { geometry._maxInstanceCount = data.meshPerAttribute * data.count; } } else { for (let i = 0; i < programAttribute.locationSize; i++) { enableAttribute(programAttribute.location + i); } } gl.bindBuffer(34962, buffer); for (let i = 0; i < programAttribute.locationSize; i++) { vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, stride * bytesPerElement, (offset + size / programAttribute.locationSize * i) * bytesPerElement); } } else { if (geometryAttribute.isInstancedBufferAttribute) { for (let i = 0; i < programAttribute.locationSize; i++) { enableAttributeAndDivisor(programAttribute.location + i, geometryAttribute.meshPerAttribute); } if (object.isInstancedMesh !== true && geometry._maxInstanceCount === void 0) { geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count; } } else { for (let i = 0; i < programAttribute.locationSize; i++) { enableAttribute(programAttribute.location + i); } } gl.bindBuffer(34962, buffer); for (let i = 0; i < programAttribute.locationSize; i++) { vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, size * bytesPerElement, size / programAttribute.locationSize * i * bytesPerElement); } } } else if (materialDefaultAttributeValues !== void 0) { const value = materialDefaultAttributeValues[name]; if (value !== void 0) { switch (value.length) { case 2: gl.vertexAttrib2fv(programAttribute.location, value); break; case 3: gl.vertexAttrib3fv(programAttribute.location, value); break; case 4: gl.vertexAttrib4fv(programAttribute.location, value); break; default: gl.vertexAttrib1fv(programAttribute.location, value); } } } } } disableUnusedAttributes(); } function dispose() { reset(); for (const geometryId in bindingStates) { const programMap = bindingStates[geometryId]; for (const programId in programMap) { const stateMap = programMap[programId]; for (const wireframe in stateMap) { deleteVertexArrayObject(stateMap[wireframe].object); delete stateMap[wireframe]; } delete programMap[programId]; } delete bindingStates[geometryId]; } } function releaseStatesOfGeometry(geometry) { if (bindingStates[geometry.id] === void 0) return; const programMap = bindingStates[geometry.id]; for (const programId in programMap) { const stateMap = programMap[programId]; for (const wireframe in stateMap) { deleteVertexArrayObject(stateMap[wireframe].object); delete stateMap[wireframe]; } delete programMap[programId]; } delete bindingStates[geometry.id]; } function releaseStatesOfProgram(program) { for (const geometryId in bindingStates) { const programMap = bindingStates[geometryId]; if (programMap[program.id] === void 0) continue; const stateMap = programMap[program.id]; for (const wireframe in stateMap) { deleteVertexArrayObject(stateMap[wireframe].object); delete stateMap[wireframe]; } delete programMap[program.id]; } } function reset() { resetDefaultState(); if (currentState === defaultState) return; currentState = defaultState; bindVertexArrayObject(currentState.object); } function resetDefaultState() { defaultState.geometry = null; defaultState.program = null; defaultState.wireframe = false; } return { setup, reset, resetDefaultState, dispose, releaseStatesOfGeometry, releaseStatesOfProgram, initAttributes, enableAttribute, disableUnusedAttributes }; } function WebGLBufferRenderer(gl, extensions, info, capabilities) { const isWebGL2 = capabilities.isWebGL2; let mode; function setMode(value) { mode = value; } function render(start, count) { gl.drawArrays(mode, start, count); info.update(count, mode, 1); } function renderInstances(start, count, primcount) { if (primcount === 0) return; let 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; } function WebGLCapabilities(gl, extensions, parameters) { let maxAnisotropy; function getMaxAnisotropy() { if (maxAnisotropy !== void 0) return maxAnisotropy; if (extensions.has("EXT_texture_filter_anisotropic") === true) { const extension = extensions.get("EXT_texture_filter_anisotropic"); maxAnisotropy = gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT); } else { maxAnisotropy = 0; } return maxAnisotropy; } function getMaxPrecision(precision2) { if (precision2 === "highp") { if (gl.getShaderPrecisionFormat(35633, 36338).precision > 0 && gl.getShaderPrecisionFormat(35632, 36338).precision > 0) { return "highp"; } precision2 = "mediump"; } if (precision2 === "mediump") { if (gl.getShaderPrecisionFormat(35633, 36337).precision > 0 && gl.getShaderPrecisionFormat(35632, 36337).precision > 0) { return "mediump"; } } return "lowp"; } const isWebGL2 = typeof WebGL2RenderingContext !== "undefined" && gl instanceof WebGL2RenderingContext || typeof WebGL2ComputeRenderingContext !== "undefined" && gl instanceof WebGL2ComputeRenderingContext; let precision = parameters.precision !== void 0 ? parameters.precision : "highp"; const maxPrecision = getMaxPrecision(precision); if (maxPrecision !== precision) { console.warn("THREE.WebGLRenderer:", precision, "not supported, using", maxPrecision, "instead."); precision = maxPrecision; } const drawBuffers = isWebGL2 || extensions.has("WEBGL_draw_buffers"); const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; const maxTextures = gl.getParameter(34930); const maxVertexTextures = gl.getParameter(35660); const maxTextureSize = gl.getParameter(3379); const maxCubemapSize = gl.getParameter(34076); const maxAttributes = gl.getParameter(34921); const maxVertexUniforms = gl.getParameter(36347); const maxVaryings = gl.getParameter(36348); const maxFragmentUniforms = gl.getParameter(36349); const vertexTextures = maxVertexTextures > 0; const floatFragmentTextures = isWebGL2 || extensions.has("OES_texture_float"); const floatVertexTextures = vertexTextures && floatFragmentTextures; const maxSamples = isWebGL2 ? gl.getParameter(36183) : 0; return { isWebGL2, drawBuffers, getMaxAnisotropy, getMaxPrecision, precision, logarithmicDepthBuffer, maxTextures, maxVertexTextures, maxTextureSize, maxCubemapSize, maxAttributes, maxVertexUniforms, maxVaryings, maxFragmentUniforms, vertexTextures, floatFragmentTextures, floatVertexTextures, maxSamples }; } function WebGLClipping(properties) { const scope = this; let globalState = null, numGlobalPlanes = 0, localClippingEnabled = false, renderingShadows = false; const 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) { const enabled = planes.length !== 0 || enableLocalClipping || 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(material, camera, useCache) { const planes = material.clippingPlanes, clipIntersection = material.clipIntersection, clipShadows = material.clipShadows; const materialProperties = properties.get(material); if (!localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && !clipShadows) { if (renderingShadows) { projectPlanes(null); } else { resetGlobalState(); } } else { const nGlobal = renderingShadows ? 0 : numGlobalPlanes, lGlobal = nGlobal * 4; let dstArray = materialProperties.clippingState || null; uniform.value = dstArray; dstArray = projectPlanes(planes, camera, lGlobal, useCache); for (let i = 0; i !== lGlobal; ++i) { dstArray[i] = globalState[i]; } materialProperties.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) { const nPlanes = planes !== null ? planes.length : 0; let dstArray = null; if (nPlanes !== 0) { dstArray = uniform.value; if (skipTransform !== true || dstArray === null) { const flatSize = dstOffset + nPlanes * 4, viewMatrix = camera.matrixWorldInverse; viewNormalMatrix.getNormalMatrix(viewMatrix); if (dstArray === null || dstArray.length < flatSize) { dstArray = new Float32Array(flatSize); } for (let 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; } } function WebGLCubeMaps(renderer) { let cubemaps = new WeakMap(); function mapTextureMapping(texture, mapping) { if (mapping === EquirectangularReflectionMapping) { texture.mapping = CubeReflectionMapping; } else if (mapping === EquirectangularRefractionMapping) { texture.mapping = CubeRefractionMapping; } return texture; } function get(texture) { if (texture && texture.isTexture && texture.isRenderTargetTexture === false) { const mapping = texture.mapping; if (mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping) { if (cubemaps.has(texture)) { const cubemap = cubemaps.get(texture).texture; return mapTextureMapping(cubemap, texture.mapping); } else { const image = texture.image; if (image && image.height > 0) { const currentRenderTarget = renderer.getRenderTarget(); const renderTarget = new WebGLCubeRenderTarget(image.height / 2); renderTarget.fromEquirectangularTexture(renderer, texture); cubemaps.set(texture, renderTarget); renderer.setRenderTarget(currentRenderTarget); texture.addEventListener("dispose", onTextureDispose); return mapTextureMapping(renderTarget.texture, texture.mapping); } else { return null; } } } } return texture; } function onTextureDispose(event) { const texture = event.target; texture.removeEventListener("dispose", onTextureDispose); const cubemap = cubemaps.get(texture); if (cubemap !== void 0) { cubemaps.delete(texture); cubemap.dispose(); } } function dispose() { cubemaps = new WeakMap(); } return { get, dispose }; } var OrthographicCamera = class extends Camera { constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2e3) { super(); this.type = "OrthographicCamera"; this.zoom = 1; this.view = null; this.left = left; this.right = right; this.top = top; this.bottom = bottom; this.near = near; this.far = far; this.updateProjectionMatrix(); } copy(source, recursive) { super.copy(source, recursive); this.left = source.left; this.right = source.right; this.top = source.top; this.bottom = source.bottom; this.near = source.near; this.far = source.far; this.zoom = source.zoom; this.view = source.view === null ? null : Object.assign({}, source.view); return this; } setViewOffset(fullWidth, fullHeight, x, y, width, height) { 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() { if (this.view !== null) { this.view.enabled = false; } this.updateProjectionMatrix(); } updateProjectionMatrix() { const dx = (this.right - this.left) / (2 * this.zoom); const dy = (this.top - this.bottom) / (2 * this.zoom); const cx = (this.right + this.left) / 2; const cy = (this.top + this.bottom) / 2; let left = cx - dx; let right = cx + dx; let top = cy + dy; let bottom = cy - dy; if (this.view !== null && this.view.enabled) { const scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom; const scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom; left += scaleW * this.view.offsetX; right = left + scaleW * this.view.width; top -= scaleH * this.view.offsetY; bottom = top - scaleH * this.view.height; } this.projectionMatrix.makeOrthographic(left, right, top, bottom, this.near, this.far); this.projectionMatrixInverse.copy(this.projectionMatrix).invert(); } toJSON(meta) { const data = super.toJSON(meta); data.object.zoom = this.zoom; data.object.left = this.left; data.object.right = this.right; data.object.top = this.top; data.object.bottom = this.bottom; data.object.near = this.near; data.object.far = this.far; if (this.view !== null) data.object.view = Object.assign({}, this.view); return data; } }; OrthographicCamera.prototype.isOrthographicCamera = true; var RawShaderMaterial = class extends ShaderMaterial { constructor(parameters) { super(parameters); this.type = "RawShaderMaterial"; } }; RawShaderMaterial.prototype.isRawShaderMaterial = true; var LOD_MIN = 4; var LOD_MAX = 8; var SIZE_MAX = Math.pow(2, LOD_MAX); var EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; var TOTAL_LODS = LOD_MAX - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; var MAX_SAMPLES = 20; var ENCODINGS = { [LinearEncoding]: 0, [sRGBEncoding]: 1, [RGBEEncoding]: 2, [RGBM7Encoding]: 3, [RGBM16Encoding]: 4, [RGBDEncoding]: 5, [GammaEncoding]: 6 }; var _flatCamera = /* @__PURE__ */ new OrthographicCamera(); var { _lodPlanes, _sizeLods, _sigmas } = /* @__PURE__ */ _createPlanes(); var _clearColor = /* @__PURE__ */ new Color(); var _oldTarget = null; var PHI = (1 + Math.sqrt(5)) / 2; var INV_PHI = 1 / PHI; var _axisDirections = [ /* @__PURE__ */ new Vector3(1, 1, 1), /* @__PURE__ */ new Vector3(-1, 1, 1), /* @__PURE__ */ new Vector3(1, 1, -1), /* @__PURE__ */ new Vector3(-1, 1, -1), /* @__PURE__ */ new Vector3(0, PHI, INV_PHI), /* @__PURE__ */ new Vector3(0, PHI, -INV_PHI), /* @__PURE__ */ new Vector3(INV_PHI, 0, PHI), /* @__PURE__ */ new Vector3(-INV_PHI, 0, PHI), /* @__PURE__ */ new Vector3(PHI, INV_PHI, 0), /* @__PURE__ */ new Vector3(-PHI, INV_PHI, 0) ]; var PMREMGenerator = class { constructor(renderer) { this._renderer = renderer; this._pingPongRenderTarget = null; this._blurMaterial = _getBlurShader(MAX_SAMPLES); this._equirectShader = null; this._cubemapShader = null; this._compileMaterial(this._blurMaterial); } fromScene(scene, sigma = 0, near = 0.1, far = 100) { _oldTarget = this._renderer.getRenderTarget(); const cubeUVRenderTarget = this._allocateTargets(); this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); if (sigma > 0) { this._blur(cubeUVRenderTarget, 0, 0, sigma); } this._applyPMREM(cubeUVRenderTarget); this._cleanup(cubeUVRenderTarget); return cubeUVRenderTarget; } fromEquirectangular(equirectangular) { return this._fromTexture(equirectangular); } fromCubemap(cubemap) { return this._fromTexture(cubemap); } compileCubemapShader() { if (this._cubemapShader === null) { this._cubemapShader = _getCubemapShader(); this._compileMaterial(this._cubemapShader); } } compileEquirectangularShader() { if (this._equirectShader === null) { this._equirectShader = _getEquirectShader(); this._compileMaterial(this._equirectShader); } } dispose() { this._blurMaterial.dispose(); if (this._cubemapShader !== null) this._cubemapShader.dispose(); if (this._equirectShader !== null) this._equirectShader.dispose(); for (let i = 0; i < _lodPlanes.length; i++) { _lodPlanes[i].dispose(); } } _cleanup(outputTarget) { this._pingPongRenderTarget.dispose(); this._renderer.setRenderTarget(_oldTarget); outputTarget.scissorTest = false; _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); } _fromTexture(texture) { _oldTarget = this._renderer.getRenderTarget(); const cubeUVRenderTarget = this._allocateTargets(texture); this._textureToCubeUV(texture, cubeUVRenderTarget); this._applyPMREM(cubeUVRenderTarget); this._cleanup(cubeUVRenderTarget); return cubeUVRenderTarget; } _allocateTargets(texture) { const params = { magFilter: NearestFilter, minFilter: NearestFilter, generateMipmaps: false, type: UnsignedByteType, format: RGBEFormat, encoding: _isLDR(texture) ? texture.encoding : RGBEEncoding, depthBuffer: false }; const cubeUVRenderTarget = _createRenderTarget(params); cubeUVRenderTarget.depthBuffer = texture ? false : true; this._pingPongRenderTarget = _createRenderTarget(params); return cubeUVRenderTarget; } _compileMaterial(material) { const tmpMesh = new Mesh(_lodPlanes[0], material); this._renderer.compile(tmpMesh, _flatCamera); } _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { const fov2 = 90; const aspect2 = 1; const cubeCamera = new PerspectiveCamera(fov2, aspect2, near, far); const upSign = [1, -1, 1, 1, 1, 1]; const forwardSign = [1, 1, 1, -1, -1, -1]; const renderer = this._renderer; const originalAutoClear = renderer.autoClear; const outputEncoding = renderer.outputEncoding; const toneMapping = renderer.toneMapping; renderer.getClearColor(_clearColor); renderer.toneMapping = NoToneMapping; renderer.outputEncoding = LinearEncoding; renderer.autoClear = false; const backgroundMaterial = new MeshBasicMaterial({ name: "PMREM.Background", side: BackSide, depthWrite: false, depthTest: false }); const backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); let useSolidColor = false; const background = scene.background; if (background) { if (background.isColor) { backgroundMaterial.color.copy(background); scene.background = null; useSolidColor = true; } } else { backgroundMaterial.color.copy(_clearColor); useSolidColor = true; } for (let i = 0; i < 6; i++) { const col = i % 3; if (col == 0) { cubeCamera.up.set(0, upSign[i], 0); cubeCamera.lookAt(forwardSign[i], 0, 0); } else if (col == 1) { cubeCamera.up.set(0, 0, upSign[i]); cubeCamera.lookAt(0, forwardSign[i], 0); } else { cubeCamera.up.set(0, upSign[i], 0); cubeCamera.lookAt(0, 0, forwardSign[i]); } _setViewport(cubeUVRenderTarget, col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX); renderer.setRenderTarget(cubeUVRenderTarget); if (useSolidColor) { renderer.render(backgroundBox, cubeCamera); } renderer.render(scene, cubeCamera); } backgroundBox.geometry.dispose(); backgroundBox.material.dispose(); renderer.toneMapping = toneMapping; renderer.outputEncoding = outputEncoding; renderer.autoClear = originalAutoClear; scene.background = background; } _textureToCubeUV(texture, cubeUVRenderTarget) { const renderer = this._renderer; if (texture.isCubeTexture) { if (this._cubemapShader == null) { this._cubemapShader = _getCubemapShader(); } } else { if (this._equirectShader == null) { this._equirectShader = _getEquirectShader(); } } const material = texture.isCubeTexture ? this._cubemapShader : this._equirectShader; const mesh = new Mesh(_lodPlanes[0], material); const uniforms = material.uniforms; uniforms["envMap"].value = texture; if (!texture.isCubeTexture) { uniforms["texelSize"].value.set(1 / texture.image.width, 1 / texture.image.height); } uniforms["inputEncoding"].value = ENCODINGS[texture.encoding]; uniforms["outputEncoding"].value = ENCODINGS[cubeUVRenderTarget.texture.encoding]; _setViewport(cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX); renderer.setRenderTarget(cubeUVRenderTarget); renderer.render(mesh, _flatCamera); } _applyPMREM(cubeUVRenderTarget) { const renderer = this._renderer; const autoClear = renderer.autoClear; renderer.autoClear = false; for (let i = 1; i < TOTAL_LODS; i++) { const sigma = Math.sqrt(_sigmas[i] * _sigmas[i] - _sigmas[i - 1] * _sigmas[i - 1]); const poleAxis = _axisDirections[(i - 1) % _axisDirections.length]; this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); } renderer.autoClear = autoClear; } _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { const pingPongRenderTarget = this._pingPongRenderTarget; this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, "latitudinal", poleAxis); this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, "longitudinal", poleAxis); } _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { const renderer = this._renderer; const blurMaterial = this._blurMaterial; if (direction !== "latitudinal" && direction !== "longitudinal") { console.error("blur direction must be either latitudinal or longitudinal!"); } const STANDARD_DEVIATIONS = 3; const blurMesh = new Mesh(_lodPlanes[lodOut], blurMaterial); const blurUniforms = blurMaterial.uniforms; const pixels = _sizeLods[lodIn] - 1; const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1); const sigmaPixels = sigmaRadians / radiansPerPixel; const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; if (samples > MAX_SAMPLES) { console.warn(`sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${samples} samples when the maximum is set to ${MAX_SAMPLES}`); } const weights = []; let sum = 0; for (let i = 0; i < MAX_SAMPLES; ++i) { const x2 = i / sigmaPixels; const weight = Math.exp(-x2 * x2 / 2); weights.push(weight); if (i == 0) { sum += weight; } else if (i < samples) { sum += 2 * weight; } } for (let i = 0; i < weights.length; i++) { weights[i] = weights[i] / sum; } blurUniforms["envMap"].value = targetIn.texture; blurUniforms["samples"].value = samples; blurUniforms["weights"].value = weights; blurUniforms["latitudinal"].value = direction === "latitudinal"; if (poleAxis) { blurUniforms["poleAxis"].value = poleAxis; } blurUniforms["dTheta"].value = radiansPerPixel; blurUniforms["mipInt"].value = LOD_MAX - lodIn; blurUniforms["inputEncoding"].value = ENCODINGS[targetIn.texture.encoding]; blurUniforms["outputEncoding"].value = ENCODINGS[targetIn.texture.encoding]; const outputSize = _sizeLods[lodOut]; const x = 3 * Math.max(0, SIZE_MAX - 2 * outputSize); const y = (lodOut === 0 ? 0 : 2 * SIZE_MAX) + 2 * outputSize * (lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0); _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); renderer.setRenderTarget(targetOut); renderer.render(blurMesh, _flatCamera); } }; function _isLDR(texture) { if (texture === void 0 || texture.type !== UnsignedByteType) return false; return texture.encoding === LinearEncoding || texture.encoding === sRGBEncoding || texture.encoding === GammaEncoding; } function _createPlanes() { const _lodPlanes2 = []; const _sizeLods2 = []; const _sigmas2 = []; let lod = LOD_MAX; for (let i = 0; i < TOTAL_LODS; i++) { const sizeLod = Math.pow(2, lod); _sizeLods2.push(sizeLod); let sigma = 1 / sizeLod; if (i > LOD_MAX - LOD_MIN) { sigma = EXTRA_LOD_SIGMA[i - LOD_MAX + LOD_MIN - 1]; } else if (i == 0) { sigma = 0; } _sigmas2.push(sigma); const texelSize = 1 / (sizeLod - 1); const min = -texelSize / 2; const max = 1 + texelSize / 2; const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; const cubeFaces = 6; const vertices = 6; const positionSize = 3; const uvSize = 2; const faceIndexSize = 1; const position = new Float32Array(positionSize * vertices * cubeFaces); const uv = new Float32Array(uvSize * vertices * cubeFaces); const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); for (let face = 0; face < cubeFaces; face++) { const x = face % 3 * 2 / 3 - 1; const y = face > 2 ? 0 : -1; const coordinates = [ x, y, 0, x + 2 / 3, y, 0, x + 2 / 3, y + 1, 0, x, y, 0, x + 2 / 3, y + 1, 0, x, y + 1, 0 ]; position.set(coordinates, positionSize * vertices * face); uv.set(uv1, uvSize * vertices * face); const fill = [face, face, face, face, face, face]; faceIndex.set(fill, faceIndexSize * vertices * face); } const planes = new BufferGeometry(); planes.setAttribute("position", new BufferAttribute(position, positionSize)); planes.setAttribute("uv", new BufferAttribute(uv, uvSize)); planes.setAttribute("faceIndex", new BufferAttribute(faceIndex, faceIndexSize)); _lodPlanes2.push(planes); if (lod > LOD_MIN) { lod--; } } return { _lodPlanes: _lodPlanes2, _sizeLods: _sizeLods2, _sigmas: _sigmas2 }; } function _createRenderTarget(params) { const cubeUVRenderTarget = new WebGLRenderTarget(3 * SIZE_MAX, 3 * SIZE_MAX, params); cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; cubeUVRenderTarget.texture.name = "PMREM.cubeUv"; cubeUVRenderTarget.scissorTest = true; return cubeUVRenderTarget; } function _setViewport(target, x, y, width, height) { target.viewport.set(x, y, width, height); target.scissor.set(x, y, width, height); } function _getBlurShader(maxSamples) { const weights = new Float32Array(maxSamples); const poleAxis = new Vector3(0, 1, 0); const shaderMaterial = new RawShaderMaterial({ name: "SphericalGaussianBlur", defines: { "n": maxSamples }, uniforms: { "envMap": { value: null }, "samples": { value: 1 }, "weights": { value: weights }, "latitudinal": { value: false }, "dTheta": { value: 0 }, "mipInt": { value: 0 }, "poleAxis": { value: poleAxis }, "inputEncoding": { value: ENCODINGS[LinearEncoding] }, "outputEncoding": { value: ENCODINGS[LinearEncoding] } }, vertexShader: _getCommonVertexShader(), fragmentShader: ` precision mediump float; precision mediump int; varying vec3 vOutputDirection; uniform sampler2D envMap; uniform int samples; uniform float weights[ n ]; uniform bool latitudinal; uniform float dTheta; uniform float mipInt; uniform vec3 poleAxis; ${_getEncodings()} #define ENVMAP_TYPE_CUBE_UV #include vec3 getSample( float theta, vec3 axis ) { float cosTheta = cos( theta ); // Rodrigues' axis-angle rotation vec3 sampleDirection = vOutputDirection * cosTheta + cross( axis, vOutputDirection ) * sin( theta ) + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta ); return bilinearCubeUV( envMap, sampleDirection, mipInt ); } void main() { vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection ); if ( all( equal( axis, vec3( 0.0 ) ) ) ) { axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x ); } axis = normalize( axis ); gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis ); for ( int i = 1; i < n; i++ ) { if ( i >= samples ) { break; } float theta = dTheta * float( i ); gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis ); gl_FragColor.rgb += weights[ i ] * getSample( theta, axis ); } gl_FragColor = linearToOutputTexel( gl_FragColor ); } `, blending: NoBlending, depthTest: false, depthWrite: false }); return shaderMaterial; } function _getEquirectShader() { const texelSize = new Vector2(1, 1); const shaderMaterial = new RawShaderMaterial({ name: "EquirectangularToCubeUV", uniforms: { "envMap": { value: null }, "texelSize": { value: texelSize }, "inputEncoding": { value: ENCODINGS[LinearEncoding] }, "outputEncoding": { value: ENCODINGS[LinearEncoding] } }, vertexShader: _getCommonVertexShader(), fragmentShader: ` precision mediump float; precision mediump int; varying vec3 vOutputDirection; uniform sampler2D envMap; uniform vec2 texelSize; ${_getEncodings()} #include void main() { gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); vec3 outputDirection = normalize( vOutputDirection ); vec2 uv = equirectUv( outputDirection ); vec2 f = fract( uv / texelSize - 0.5 ); uv -= f * texelSize; vec3 tl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb; uv.x += texelSize.x; vec3 tr = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb; uv.y += texelSize.y; vec3 br = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb; uv.x -= texelSize.x; vec3 bl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb; vec3 tm = mix( tl, tr, f.x ); vec3 bm = mix( bl, br, f.x ); gl_FragColor.rgb = mix( tm, bm, f.y ); gl_FragColor = linearToOutputTexel( gl_FragColor ); } `, blending: NoBlending, depthTest: false, depthWrite: false }); return shaderMaterial; } function _getCubemapShader() { const shaderMaterial = new RawShaderMaterial({ name: "CubemapToCubeUV", uniforms: { "envMap": { value: null }, "inputEncoding": { value: ENCODINGS[LinearEncoding] }, "outputEncoding": { value: ENCODINGS[LinearEncoding] } }, vertexShader: _getCommonVertexShader(), fragmentShader: ` precision mediump float; precision mediump int; varying vec3 vOutputDirection; uniform samplerCube envMap; ${_getEncodings()} void main() { gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); gl_FragColor.rgb = envMapTexelToLinear( textureCube( envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ) ) ).rgb; gl_FragColor = linearToOutputTexel( gl_FragColor ); } `, blending: NoBlending, depthTest: false, depthWrite: false }); return shaderMaterial; } function _getCommonVertexShader() { return ` precision mediump float; precision mediump int; attribute vec3 position; attribute vec2 uv; attribute float faceIndex; varying vec3 vOutputDirection; // RH coordinate system; PMREM face-indexing convention vec3 getDirection( vec2 uv, float face ) { uv = 2.0 * uv - 1.0; vec3 direction = vec3( uv, 1.0 ); if ( face == 0.0 ) { direction = direction.zyx; // ( 1, v, u ) pos x } else if ( face == 1.0 ) { direction = direction.xzy; direction.xz *= -1.0; // ( -u, 1, -v ) pos y } else if ( face == 2.0 ) { direction.x *= -1.0; // ( -u, v, 1 ) pos z } else if ( face == 3.0 ) { direction = direction.zyx; direction.xz *= -1.0; // ( -1, v, -u ) neg x } else if ( face == 4.0 ) { direction = direction.xzy; direction.xy *= -1.0; // ( -u, -1, v ) neg y } else if ( face == 5.0 ) { direction.z *= -1.0; // ( u, v, -1 ) neg z } return direction; } void main() { vOutputDirection = getDirection( uv, faceIndex ); gl_Position = vec4( position, 1.0 ); } `; } function _getEncodings() { return ` uniform int inputEncoding; uniform int outputEncoding; #include vec4 inputTexelToLinear( vec4 value ) { if ( inputEncoding == 0 ) { return value; } else if ( inputEncoding == 1 ) { return sRGBToLinear( value ); } else if ( inputEncoding == 2 ) { return RGBEToLinear( value ); } else if ( inputEncoding == 3 ) { return RGBMToLinear( value, 7.0 ); } else if ( inputEncoding == 4 ) { return RGBMToLinear( value, 16.0 ); } else if ( inputEncoding == 5 ) { return RGBDToLinear( value, 256.0 ); } else { return GammaToLinear( value, 2.2 ); } } vec4 linearToOutputTexel( vec4 value ) { if ( outputEncoding == 0 ) { return value; } else if ( outputEncoding == 1 ) { return LinearTosRGB( value ); } else if ( outputEncoding == 2 ) { return LinearToRGBE( value ); } else if ( outputEncoding == 3 ) { return LinearToRGBM( value, 7.0 ); } else if ( outputEncoding == 4 ) { return LinearToRGBM( value, 16.0 ); } else if ( outputEncoding == 5 ) { return LinearToRGBD( value, 256.0 ); } else { return LinearToGamma( value, 2.2 ); } } vec4 envMapTexelToLinear( vec4 color ) { return inputTexelToLinear( color ); } `; } function WebGLCubeUVMaps(renderer) { let cubeUVmaps = new WeakMap(); let pmremGenerator = null; function get(texture) { if (texture && texture.isTexture && texture.isRenderTargetTexture === false) { const mapping = texture.mapping; const isEquirectMap = mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping; const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping; if (isEquirectMap || isCubeMap) { if (cubeUVmaps.has(texture)) { return cubeUVmaps.get(texture).texture; } else { const image = texture.image; if (isEquirectMap && image && image.height > 0 || isCubeMap && image && isCubeTextureComplete(image)) { const currentRenderTarget = renderer.getRenderTarget(); if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer); const renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture) : pmremGenerator.fromCubemap(texture); cubeUVmaps.set(texture, renderTarget); renderer.setRenderTarget(currentRenderTarget); texture.addEventListener("dispose", onTextureDispose); return renderTarget.texture; } else { return null; } } } } return texture; } function isCubeTextureComplete(image) { let count = 0; const length = 6; for (let i = 0; i < length; i++) { if (image[i] !== void 0) count++; } return count === length; } function onTextureDispose(event) { const texture = event.target; texture.removeEventListener("dispose", onTextureDispose); const cubemapUV = cubeUVmaps.get(texture); if (cubemapUV !== void 0) { cubeUVmaps.delete(texture); cubemapUV.dispose(); } } function dispose() { cubeUVmaps = new WeakMap(); if (pmremGenerator !== null) { pmremGenerator.dispose(); pmremGenerator = null; } } return { get, dispose }; } function WebGLExtensions(gl) { const extensions = {}; function getExtension(name) { if (extensions[name] !== void 0) { return extensions[name]; } let 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); } extensions[name] = extension; return extension; } return { has: function(name) { return getExtension(name) !== null; }, init: function(capabilities) { if (capabilities.isWebGL2) { getExtension("EXT_color_buffer_float"); } else { getExtension("WEBGL_depth_texture"); getExtension("OES_texture_float"); getExtension("OES_texture_half_float"); getExtension("OES_texture_half_float_linear"); getExtension("OES_standard_derivatives"); getExtension("OES_element_index_uint"); getExtension("OES_vertex_array_object"); getExtension("ANGLE_instanced_arrays"); } getExtension("OES_texture_float_linear"); getExtension("EXT_color_buffer_half_float"); }, get: function(name) { const extension = getExtension(name); if (extension === null) { console.warn("THREE.WebGLRenderer: " + name + " extension not supported."); } return extension; } }; } function WebGLGeometries(gl, attributes, info, bindingStates) { const geometries = {}; const wireframeAttributes = new WeakMap(); function onGeometryDispose(event) { const geometry = event.target; if (geometry.index !== null) { attributes.remove(geometry.index); } for (const name in geometry.attributes) { attributes.remove(geometry.attributes[name]); } geometry.removeEventListener("dispose", onGeometryDispose); delete geometries[geometry.id]; const attribute = wireframeAttributes.get(geometry); if (attribute) { attributes.remove(attribute); wireframeAttributes.delete(geometry); } bindingStates.releaseStatesOfGeometry(geometry); if (geometry.isInstancedBufferGeometry === true) { delete geometry._maxInstanceCount; } info.memory.geometries--; } function get(object, geometry) { if (geometries[geometry.id] === true) return geometry; geometry.addEventListener("dispose", onGeometryDispose); geometries[geometry.id] = true; info.memory.geometries++; return geometry; } function update(geometry) { const geometryAttributes = geometry.attributes; for (const name in geometryAttributes) { attributes.update(geometryAttributes[name], 34962); } const morphAttributes = geometry.morphAttributes; for (const name in morphAttributes) { const array = morphAttributes[name]; for (let i = 0, l = array.length; i < l; i++) { attributes.update(array[i], 34962); } } } function updateWireframeAttribute(geometry) { const indices = []; const geometryIndex = geometry.index; const geometryPosition = geometry.attributes.position; let version = 0; if (geometryIndex !== null) { const array = geometryIndex.array; version = geometryIndex.version; for (let i = 0, l = array.length; i < l; i += 3) { const a2 = array[i + 0]; const b2 = array[i + 1]; const c2 = array[i + 2]; indices.push(a2, b2, b2, c2, c2, a2); } } else { const array = geometryPosition.array; version = geometryPosition.version; for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { const a2 = i + 0; const b2 = i + 1; const c2 = i + 2; indices.push(a2, b2, b2, c2, c2, a2); } } const attribute = new (arrayMax(indices) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); attribute.version = version; const previousAttribute = wireframeAttributes.get(geometry); if (previousAttribute) attributes.remove(previousAttribute); wireframeAttributes.set(geometry, attribute); } function getWireframeAttribute(geometry) { const currentAttribute = wireframeAttributes.get(geometry); if (currentAttribute) { const geometryIndex = geometry.index; if (geometryIndex !== null) { if (currentAttribute.version < geometryIndex.version) { updateWireframeAttribute(geometry); } } } else { updateWireframeAttribute(geometry); } return wireframeAttributes.get(geometry); } return { get, update, getWireframeAttribute }; } function WebGLIndexedBufferRenderer(gl, extensions, info, capabilities) { const isWebGL2 = capabilities.isWebGL2; let mode; function setMode(value) { mode = value; } let 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, 1); } function renderInstances(start, count, primcount) { if (primcount === 0) return; let 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; } function WebGLInfo(gl) { const memory = { geometries: 0, textures: 0 }; const render = { frame: 0, calls: 0, triangles: 0, points: 0, lines: 0 }; function update(count, mode, instanceCount) { 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, render, programs: null, autoReset: true, reset, update }; } function numericalSort(a2, b2) { return a2[0] - b2[0]; } function absNumericalSort(a2, b2) { return Math.abs(b2[1]) - Math.abs(a2[1]); } function WebGLMorphtargets(gl) { const influencesList = {}; const morphInfluences = new Float32Array(8); const workInfluences = []; for (let i = 0; i < 8; i++) { workInfluences[i] = [i, 0]; } function update(object, geometry, material, program) { const objectInfluences = object.morphTargetInfluences; const length = objectInfluences === void 0 ? 0 : objectInfluences.length; let influences = influencesList[geometry.id]; if (influences === void 0 || influences.length !== length) { influences = []; for (let i = 0; i < length; i++) { influences[i] = [i, 0]; } influencesList[geometry.id] = influences; } for (let i = 0; i < length; i++) { const influence = influences[i]; influence[0] = i; influence[1] = objectInfluences[i]; } influences.sort(absNumericalSort); for (let i = 0; i < 8; i++) { if (i < length && influences[i][1]) { workInfluences[i][0] = influences[i][0]; workInfluences[i][1] = influences[i][1]; } else { workInfluences[i][0] = Number.MAX_SAFE_INTEGER; workInfluences[i][1] = 0; } } workInfluences.sort(numericalSort); const morphTargets = geometry.morphAttributes.position; const morphNormals = geometry.morphAttributes.normal; let morphInfluencesSum = 0; for (let i = 0; i < 8; i++) { const influence = workInfluences[i]; const index = influence[0]; const value = influence[1]; if (index !== Number.MAX_SAFE_INTEGER && value) { if (morphTargets && geometry.getAttribute("morphTarget" + i) !== morphTargets[index]) { geometry.setAttribute("morphTarget" + i, morphTargets[index]); } if (morphNormals && geometry.getAttribute("morphNormal" + i) !== morphNormals[index]) { geometry.setAttribute("morphNormal" + i, morphNormals[index]); } morphInfluences[i] = value; morphInfluencesSum += value; } else { if (morphTargets && geometry.hasAttribute("morphTarget" + i) === true) { geometry.deleteAttribute("morphTarget" + i); } if (morphNormals && geometry.hasAttribute("morphNormal" + i) === true) { geometry.deleteAttribute("morphNormal" + i); } morphInfluences[i] = 0; } } const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; program.getUniforms().setValue(gl, "morphTargetBaseInfluence", morphBaseInfluence); program.getUniforms().setValue(gl, "morphTargetInfluences", morphInfluences); } return { update }; } function WebGLObjects(gl, geometries, attributes, info) { let updateMap = new WeakMap(); function update(object) { const frame = info.render.frame; const geometry = object.geometry; const buffergeometry = geometries.get(object, geometry); if (updateMap.get(buffergeometry) !== frame) { geometries.update(buffergeometry); updateMap.set(buffergeometry, frame); } if (object.isInstancedMesh) { if (object.hasEventListener("dispose", onInstancedMeshDispose) === false) { object.addEventListener("dispose", onInstancedMeshDispose); } attributes.update(object.instanceMatrix, 34962); if (object.instanceColor !== null) { attributes.update(object.instanceColor, 34962); } } return buffergeometry; } function dispose() { updateMap = new WeakMap(); } function onInstancedMeshDispose(event) { const instancedMesh = event.target; instancedMesh.removeEventListener("dispose", onInstancedMeshDispose); attributes.remove(instancedMesh.instanceMatrix); if (instancedMesh.instanceColor !== null) attributes.remove(instancedMesh.instanceColor); } return { update, dispose }; } var DataTexture2DArray = class extends Texture { constructor(data = null, width = 1, height = 1, depth = 1) { super(null); this.image = { data, width, height, depth }; this.magFilter = NearestFilter; this.minFilter = NearestFilter; this.wrapR = ClampToEdgeWrapping; this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; this.needsUpdate = true; } }; DataTexture2DArray.prototype.isDataTexture2DArray = true; var DataTexture3D = class extends Texture { constructor(data = null, width = 1, height = 1, depth = 1) { super(null); this.image = { data, width, height, depth }; this.magFilter = NearestFilter; this.minFilter = NearestFilter; this.wrapR = ClampToEdgeWrapping; this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; this.needsUpdate = true; } }; DataTexture3D.prototype.isDataTexture3D = true; var emptyTexture = new Texture(); var emptyTexture2dArray = new DataTexture2DArray(); var emptyTexture3d = new DataTexture3D(); var emptyCubeTexture = new CubeTexture(); var arrayCacheF32 = []; var arrayCacheI32 = []; var mat4array = new Float32Array(16); var mat3array = new Float32Array(9); var mat2array = new Float32Array(4); function flatten(array, nBlocks, blockSize) { const firstElem = array[0]; if (firstElem <= 0 || firstElem > 0) return array; const n = nBlocks * blockSize; let r = arrayCacheF32[n]; if (r === void 0) { r = new Float32Array(n); arrayCacheF32[n] = r; } if (nBlocks !== 0) { firstElem.toArray(r, 0); for (let i = 1, offset = 0; i !== nBlocks; ++i) { offset += blockSize; array[i].toArray(r, offset); } } return r; } function arraysEqual(a2, b2) { if (a2.length !== b2.length) return false; for (let i = 0, l = a2.length; i < l; i++) { if (a2[i] !== b2[i]) return false; } return true; } function copyArray(a2, b2) { for (let i = 0, l = b2.length; i < l; i++) { a2[i] = b2[i]; } } function allocTexUnits(textures, n) { let r = arrayCacheI32[n]; if (r === void 0) { r = new Int32Array(n); arrayCacheI32[n] = r; } for (let i = 0; i !== n; ++i) { r[i] = textures.allocateTextureUnit(); } return r; } function setValueV1f(gl, v) { const cache = this.cache; if (cache[0] === v) return; gl.uniform1f(this.addr, v); cache[0] = v; } function setValueV2f(gl, v) { const cache = this.cache; if (v.x !== void 0) { 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) { const cache = this.cache; if (v.x !== void 0) { 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 !== void 0) { 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) { const cache = this.cache; if (v.x !== void 0) { 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); } } function setValueM2(gl, v) { const cache = this.cache; const elements = v.elements; if (elements === void 0) { 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) { const cache = this.cache; const elements = v.elements; if (elements === void 0) { 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) { const cache = this.cache; const elements = v.elements; if (elements === void 0) { 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); } } function setValueV1i(gl, v) { const cache = this.cache; if (cache[0] === v) return; gl.uniform1i(this.addr, v); cache[0] = v; } function setValueV2i(gl, v) { const cache = this.cache; if (arraysEqual(cache, v)) return; gl.uniform2iv(this.addr, v); copyArray(cache, v); } function setValueV3i(gl, v) { const cache = this.cache; if (arraysEqual(cache, v)) return; gl.uniform3iv(this.addr, v); copyArray(cache, v); } function setValueV4i(gl, v) { const cache = this.cache; if (arraysEqual(cache, v)) return; gl.uniform4iv(this.addr, v); copyArray(cache, v); } function setValueV1ui(gl, v) { const cache = this.cache; if (cache[0] === v) return; gl.uniform1ui(this.addr, v); cache[0] = v; } function setValueV2ui(gl, v) { const cache = this.cache; if (arraysEqual(cache, v)) return; gl.uniform2uiv(this.addr, v); copyArray(cache, v); } function setValueV3ui(gl, v) { const cache = this.cache; if (arraysEqual(cache, v)) return; gl.uniform3uiv(this.addr, v); copyArray(cache, v); } function setValueV4ui(gl, v) { const cache = this.cache; if (arraysEqual(cache, v)) return; gl.uniform4uiv(this.addr, v); copyArray(cache, v); } function setValueT1(gl, v, textures) { const cache = this.cache; const unit = textures.allocateTextureUnit(); if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } textures.safeSetTexture2D(v || emptyTexture, unit); } function setValueT3D1(gl, v, textures) { const cache = this.cache; const 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) { const cache = this.cache; const unit = textures.allocateTextureUnit(); if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } textures.safeSetTextureCube(v || emptyCubeTexture, unit); } function setValueT2DArray1(gl, v, textures) { const cache = this.cache; const unit = textures.allocateTextureUnit(); if (cache[0] !== unit) { gl.uniform1i(this.addr, unit); cache[0] = unit; } textures.setTexture2DArray(v || emptyTexture2dArray, unit); } function getSingularSetter(type) { switch (type) { case 5126: return setValueV1f; case 35664: return setValueV2f; case 35665: return setValueV3f; case 35666: return setValueV4f; case 35674: return setValueM2; case 35675: return setValueM3; case 35676: return setValueM4; case 5124: case 35670: return setValueV1i; case 35667: case 35671: return setValueV2i; case 35668: case 35672: return setValueV3i; case 35669: case 35673: return setValueV4i; case 5125: return setValueV1ui; case 36294: return setValueV2ui; case 36295: return setValueV3ui; case 36296: return setValueV4ui; case 35678: case 36198: case 36298: case 36306: case 35682: return setValueT1; case 35679: case 36299: case 36307: return setValueT3D1; case 35680: case 36300: case 36308: case 36293: return setValueT6; case 36289: case 36303: case 36311: case 36292: return setValueT2DArray1; } } function setValueV1fArray(gl, v) { gl.uniform1fv(this.addr, v); } function setValueV2fArray(gl, v) { const data = flatten(v, this.size, 2); gl.uniform2fv(this.addr, data); } function setValueV3fArray(gl, v) { const data = flatten(v, this.size, 3); gl.uniform3fv(this.addr, data); } function setValueV4fArray(gl, v) { const data = flatten(v, this.size, 4); gl.uniform4fv(this.addr, data); } function setValueM2Array(gl, v) { const data = flatten(v, this.size, 4); gl.uniformMatrix2fv(this.addr, false, data); } function setValueM3Array(gl, v) { const data = flatten(v, this.size, 9); gl.uniformMatrix3fv(this.addr, false, data); } function setValueM4Array(gl, v) { const data = flatten(v, this.size, 16); gl.uniformMatrix4fv(this.addr, false, data); } 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); } function setValueV1uiArray(gl, v) { gl.uniform1uiv(this.addr, v); } function setValueV2uiArray(gl, v) { gl.uniform2uiv(this.addr, v); } function setValueV3uiArray(gl, v) { gl.uniform3uiv(this.addr, v); } function setValueV4uiArray(gl, v) { gl.uniform4uiv(this.addr, v); } function setValueT1Array(gl, v, textures) { const n = v.length; const units = allocTexUnits(textures, n); gl.uniform1iv(this.addr, units); for (let i = 0; i !== n; ++i) { textures.safeSetTexture2D(v[i] || emptyTexture, units[i]); } } function setValueT6Array(gl, v, textures) { const n = v.length; const units = allocTexUnits(textures, n); gl.uniform1iv(this.addr, units); for (let i = 0; i !== n; ++i) { textures.safeSetTextureCube(v[i] || emptyCubeTexture, units[i]); } } function getPureArraySetter(type) { switch (type) { case 5126: return setValueV1fArray; case 35664: return setValueV2fArray; case 35665: return setValueV3fArray; case 35666: return setValueV4fArray; case 35674: return setValueM2Array; case 35675: return setValueM3Array; case 35676: return setValueM4Array; case 5124: case 35670: return setValueV1iArray; case 35667: case 35671: return setValueV2iArray; case 35668: case 35672: return setValueV3iArray; case 35669: case 35673: return setValueV4iArray; case 5125: return setValueV1uiArray; case 36294: return setValueV2uiArray; case 36295: return setValueV3uiArray; case 36296: return setValueV4uiArray; case 35678: case 36198: case 36298: case 36306: case 35682: return setValueT1Array; case 35680: case 36300: case 36308: case 36293: return setValueT6Array; } } function SingleUniform(id, activeInfo, addr) { this.id = id; this.addr = addr; this.cache = []; this.setValue = getSingularSetter(activeInfo.type); } function PureArrayUniform(id, activeInfo, addr) { this.id = id; this.addr = addr; this.cache = []; this.size = activeInfo.size; this.setValue = getPureArraySetter(activeInfo.type); } PureArrayUniform.prototype.updateCache = function(data) { const 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) { const seq = this.seq; for (let i = 0, n = seq.length; i !== n; ++i) { const u = seq[i]; u.setValue(gl, value[u.id], textures); } }; var RePathPart = /(\w+)(\])?(\[|\.)?/g; function addUniform(container, uniformObject) { container.seq.push(uniformObject); container.map[uniformObject.id] = uniformObject; } function parseUniform(activeInfo, addr, container) { const path = activeInfo.name, pathLength = path.length; RePathPart.lastIndex = 0; while (true) { const match = RePathPart.exec(path), matchEnd = RePathPart.lastIndex; let id = match[1]; const idIsIndex = match[2] === "]", subscript = match[3]; if (idIsIndex) id = id | 0; if (subscript === void 0 || subscript === "[" && matchEnd + 2 === pathLength) { addUniform(container, subscript === void 0 ? new SingleUniform(id, activeInfo, addr) : new PureArrayUniform(id, activeInfo, addr)); break; } else { const map = container.map; let next = map[id]; if (next === void 0) { next = new StructuredUniform(id); addUniform(container, next); } container = next; } } } function WebGLUniforms(gl, program) { this.seq = []; this.map = {}; const n = gl.getProgramParameter(program, 35718); for (let i = 0; i < n; ++i) { const info = gl.getActiveUniform(program, i), addr = gl.getUniformLocation(program, info.name); parseUniform(info, addr, this); } } WebGLUniforms.prototype.setValue = function(gl, name, value, textures) { const u = this.map[name]; if (u !== void 0) u.setValue(gl, value, textures); }; WebGLUniforms.prototype.setOptional = function(gl, object, name) { const v = object[name]; if (v !== void 0) this.setValue(gl, name, v); }; WebGLUniforms.upload = function(gl, seq, values, textures) { for (let i = 0, n = seq.length; i !== n; ++i) { const u = seq[i], v = values[u.id]; if (v.needsUpdate !== false) { u.setValue(gl, v.value, textures); } } }; WebGLUniforms.seqWithValue = function(seq, values) { const r = []; for (let i = 0, n = seq.length; i !== n; ++i) { const u = seq[i]; if (u.id in values) r.push(u); } return r; }; function WebGLShader(gl, type, string) { const shader = gl.createShader(type); gl.shaderSource(shader, string); gl.compileShader(shader); return shader; } var programIdCount = 0; function addLineNumbers(string) { const lines = string.split("\n"); for (let 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: console.warn("THREE.WebGLProgram: Unsupported encoding:", encoding); return ["Linear", "( value )"]; } } function getShaderErrors(gl, shader, type) { const status = gl.getShaderParameter(shader, 35713); const errors = gl.getShaderInfoLog(shader).trim(); if (status && errors === "") return ""; return type.toUpperCase() + "\n\n" + errors + "\n\n" + addLineNumbers(gl.getShaderSource(shader)); } function getTexelDecodingFunction(functionName, encoding) { const components = getEncodingComponents(encoding); return "vec4 " + functionName + "( vec4 value ) { return " + components[0] + "ToLinear" + components[1] + "; }"; } function getTexelEncodingFunction(functionName, encoding) { const components = getEncodingComponents(encoding); return "vec4 " + functionName + "( vec4 value ) { return LinearTo" + components[0] + components[1] + "; }"; } function getToneMappingFunction(functionName, toneMapping) { let toneMappingName; switch (toneMapping) { case LinearToneMapping: toneMappingName = "Linear"; break; case ReinhardToneMapping: toneMappingName = "Reinhard"; break; case CineonToneMapping: toneMappingName = "OptimizedCineon"; break; case ACESFilmicToneMapping: toneMappingName = "ACESFilmic"; break; case CustomToneMapping: toneMappingName = "Custom"; break; default: console.warn("THREE.WebGLProgram: Unsupported toneMapping:", toneMapping); toneMappingName = "Linear"; } return "vec3 " + functionName + "( vec3 color ) { return " + toneMappingName + "ToneMapping( color ); }"; } function generateExtensions(parameters) { const 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.transmission) && parameters.rendererExtensionShaderTextureLod ? "#extension GL_EXT_shader_texture_lod : enable" : "" ]; return chunks.filter(filterEmptyLine).join("\n"); } function generateDefines(defines) { const chunks = []; for (const name in defines) { const value = defines[name]; if (value === false) continue; chunks.push("#define " + name + " " + value); } return chunks.join("\n"); } function fetchAttributeLocations(gl, program) { const attributes = {}; const n = gl.getProgramParameter(program, 35721); for (let i = 0; i < n; i++) { const info = gl.getActiveAttrib(program, i); const name = info.name; let locationSize = 1; if (info.type === 35674) locationSize = 2; if (info.type === 35675) locationSize = 3; if (info.type === 35676) locationSize = 4; attributes[name] = { type: info.type, location: gl.getAttribLocation(program, name), locationSize }; } 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); } var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; function resolveIncludes(string) { return string.replace(includePattern, includeReplacer); } function includeReplacer(match, include) { const string = ShaderChunk[include]; if (string === void 0) { throw new Error("Can not resolve #include <" + include + ">"); } return resolveIncludes(string); } var deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; var unrollLoopPattern = /#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\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) { let string = ""; for (let i = parseInt(start); i < parseInt(end); i++) { string += snippet.replace(/\[\s*i\s*\]/g, "[ " + i + " ]").replace(/UNROLLED_LOOP_INDEX/g, i); } return string; } function generatePrecision(parameters) { let 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) { let 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) { let 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; } } return envMapTypeDefine; } function generateEnvMapModeDefine(parameters) { let envMapModeDefine = "ENVMAP_MODE_REFLECTION"; if (parameters.envMap) { switch (parameters.envMapMode) { case CubeRefractionMapping: case CubeUVRefractionMapping: envMapModeDefine = "ENVMAP_MODE_REFRACTION"; break; } } return envMapModeDefine; } function generateEnvMapBlendingDefine(parameters) { let 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, bindingStates) { const gl = renderer.getContext(); const defines = parameters.defines; let vertexShader = parameters.vertexShader; let fragmentShader = parameters.fragmentShader; const shadowMapTypeDefine = generateShadowMapTypeDefine(parameters); const envMapTypeDefine = generateEnvMapTypeDefine(parameters); const envMapModeDefine = generateEnvMapModeDefine(parameters); const envMapBlendingDefine = generateEnvMapBlendingDefine(parameters); const gammaFactorDefine = renderer.gammaFactor > 0 ? renderer.gammaFactor : 1; const customExtensions = parameters.isWebGL2 ? "" : generateExtensions(parameters); const customDefines = generateDefines(defines); const program = gl.createProgram(); let prefixVertex, prefixFragment; let versionString = parameters.glslVersion ? "#version " + parameters.glslVersion + "\n" : ""; 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.instancingColor ? "#define USE_INSTANCING_COLOR" : "", 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.specularIntensityMap ? "#define USE_SPECULARINTENSITYMAP" : "", parameters.specularTintMap ? "#define USE_SPECULARTINTMAP" : "", parameters.roughnessMap ? "#define USE_ROUGHNESSMAP" : "", parameters.metalnessMap ? "#define USE_METALNESSMAP" : "", parameters.alphaMap ? "#define USE_ALPHAMAP" : "", parameters.transmission ? "#define USE_TRANSMISSION" : "", parameters.transmissionMap ? "#define USE_TRANSMISSIONMAP" : "", parameters.thicknessMap ? "#define USE_THICKNESSMAP" : "", parameters.vertexTangents ? "#define USE_TANGENT" : "", parameters.vertexColors ? "#define USE_COLOR" : "", parameters.vertexAlphas ? "#define USE_COLOR_ALPHA" : "", 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", "#ifdef USE_INSTANCING_COLOR", " attribute vec3 instanceColor;", "#endif", "attribute vec3 position;", "attribute vec3 normal;", "attribute vec2 uv;", "#ifdef USE_TANGENT", " attribute vec4 tangent;", "#endif", "#if defined( USE_COLOR_ALPHA )", " attribute vec4 color;", "#elif defined( 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, "#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.clearcoat ? "#define USE_CLEARCOAT" : "", parameters.clearcoatMap ? "#define USE_CLEARCOATMAP" : "", parameters.clearcoatRoughnessMap ? "#define USE_CLEARCOAT_ROUGHNESSMAP" : "", parameters.clearcoatNormalMap ? "#define USE_CLEARCOAT_NORMALMAP" : "", parameters.specularMap ? "#define USE_SPECULARMAP" : "", parameters.specularIntensityMap ? "#define USE_SPECULARINTENSITYMAP" : "", parameters.specularTintMap ? "#define USE_SPECULARTINTMAP" : "", parameters.roughnessMap ? "#define USE_ROUGHNESSMAP" : "", parameters.metalnessMap ? "#define USE_METALNESSMAP" : "", parameters.alphaMap ? "#define USE_ALPHAMAP" : "", parameters.alphaTest ? "#define USE_ALPHATEST" : "", parameters.sheenTint ? "#define USE_SHEEN" : "", parameters.transmission ? "#define USE_TRANSMISSION" : "", parameters.transmissionMap ? "#define USE_TRANSMISSIONMAP" : "", parameters.thicknessMap ? "#define USE_THICKNESSMAP" : "", parameters.vertexTangents ? "#define USE_TANGENT" : "", parameters.vertexColors || parameters.instancingColor ? "#define USE_COLOR" : "", parameters.vertexAlphas ? "#define USE_COLOR_ALPHA" : "", 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"] : "", parameters.toneMapping !== NoToneMapping ? getToneMappingFunction("toneMapping", parameters.toneMapping) : "", parameters.dithering ? "#define DITHERING" : "", parameters.format === RGBFormat ? "#define OPAQUE" : "", ShaderChunk["encodings_pars_fragment"], parameters.map ? getTexelDecodingFunction("mapTexelToLinear", parameters.mapEncoding) : "", parameters.matcap ? getTexelDecodingFunction("matcapTexelToLinear", parameters.matcapEncoding) : "", parameters.envMap ? getTexelDecodingFunction("envMapTexelToLinear", parameters.envMapEncoding) : "", parameters.emissiveMap ? getTexelDecodingFunction("emissiveMapTexelToLinear", parameters.emissiveMapEncoding) : "", parameters.specularTintMap ? getTexelDecodingFunction("specularTintMapTexelToLinear", parameters.specularTintMapEncoding) : "", parameters.lightMap ? getTexelDecodingFunction("lightMapTexelToLinear", parameters.lightMapEncoding) : "", 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 !== true) { versionString = "#version 300 es\n"; prefixVertex = [ "#define attribute in", "#define varying out", "#define texture2D texture" ].join("\n") + "\n" + prefixVertex; prefixFragment = [ "#define varying in", parameters.glslVersion === GLSL3 ? "" : "out highp vec4 pc_fragColor;", parameters.glslVersion === GLSL3 ? "" : "#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; } const vertexGlsl = versionString + prefixVertex + vertexShader; const fragmentGlsl = versionString + prefixFragment + fragmentShader; const glVertexShader = WebGLShader(gl, 35633, vertexGlsl); const glFragmentShader = WebGLShader(gl, 35632, fragmentGlsl); gl.attachShader(program, glVertexShader); gl.attachShader(program, glFragmentShader); if (parameters.index0AttributeName !== void 0) { gl.bindAttribLocation(program, 0, parameters.index0AttributeName); } else if (parameters.morphTargets === true) { gl.bindAttribLocation(program, 0, "position"); } gl.linkProgram(program); if (renderer.debug.checkShaderErrors) { const programLog = gl.getProgramInfoLog(program).trim(); const vertexLog = gl.getShaderInfoLog(glVertexShader).trim(); const fragmentLog = gl.getShaderInfoLog(glFragmentShader).trim(); let runnable = true; let haveDiagnostics = true; if (gl.getProgramParameter(program, 35714) === false) { runnable = false; const vertexErrors = getShaderErrors(gl, glVertexShader, "vertex"); const fragmentErrors = getShaderErrors(gl, glFragmentShader, "fragment"); console.error("THREE.WebGLProgram: Shader Error " + gl.getError() + " - VALIDATE_STATUS " + gl.getProgramParameter(program, 35715) + "\n\nProgram Info Log: " + programLog + "\n" + vertexErrors + "\n" + fragmentErrors); } else if (programLog !== "") { console.warn("THREE.WebGLProgram: Program Info Log:", programLog); } else if (vertexLog === "" || fragmentLog === "") { haveDiagnostics = false; } if (haveDiagnostics) { this.diagnostics = { runnable, programLog, vertexShader: { log: vertexLog, prefix: prefixVertex }, fragmentShader: { log: fragmentLog, prefix: prefixFragment } }; } } gl.deleteShader(glVertexShader); gl.deleteShader(glFragmentShader); let cachedUniforms; this.getUniforms = function() { if (cachedUniforms === void 0) { cachedUniforms = new WebGLUniforms(gl, program); } return cachedUniforms; }; let cachedAttributes; this.getAttributes = function() { if (cachedAttributes === void 0) { cachedAttributes = fetchAttributeLocations(gl, program); } return cachedAttributes; }; this.destroy = function() { bindingStates.releaseStatesOfProgram(this); gl.deleteProgram(program); this.program = void 0; }; this.name = parameters.shaderName; this.id = programIdCount++; this.cacheKey = cacheKey; this.usedTimes = 1; this.program = program; this.vertexShader = glVertexShader; this.fragmentShader = glFragmentShader; return this; } function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping) { const programs = []; const isWebGL2 = capabilities.isWebGL2; const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; const floatVertexTextures = capabilities.floatVertexTextures; const maxVertexUniforms = capabilities.maxVertexUniforms; const vertexTextures = capabilities.vertexTextures; let precision = capabilities.precision; const 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" }; const parameterNames = [ "precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing", "instancingColor", "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV", "lightMap", "lightMapEncoding", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoat", "clearcoatMap", "clearcoatRoughnessMap", "clearcoatNormalMap", "displacementMap", "specularMap", "specularIntensityMap", "specularTintMap", "specularTintMapEncoding", "roughnessMap", "metalnessMap", "gradientMap", "alphaMap", "alphaTest", "combine", "vertexColors", "vertexAlphas", "vertexTangents", "vertexUvs", "uvsVertexOnly", "fog", "useFog", "fogExp2", "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", "maxBones", "useVertexTexture", "morphTargets", "morphNormals", "premultipliedAlpha", "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights", "numDirLightShadows", "numPointLightShadows", "numSpotLightShadows", "shadowMapEnabled", "shadowMapType", "toneMapping", "physicallyCorrectLights", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering", "format", "sheenTint", "transmission", "transmissionMap", "thicknessMap" ]; function getMaxBones(object) { const skeleton = object.skeleton; const bones = skeleton.bones; if (floatVertexTextures) { return 1024; } else { const nVertexUniforms = maxVertexUniforms; const nVertexMatrices = Math.floor((nVertexUniforms - 20) / 4); const 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) { let encoding; if (map && map.isTexture) { encoding = map.encoding; } else if (map && map.isWebGLRenderTarget) { console.warn("THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead."); encoding = map.texture.encoding; } else { encoding = LinearEncoding; } return encoding; } function getParameters(material, lights, shadows, scene, object) { const fog = scene.fog; const environment = material.isMeshStandardMaterial ? scene.environment : null; const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment); const shaderID = shaderIDs[material.type]; const maxBones = object.isSkinnedMesh ? getMaxBones(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."); } } let vertexShader, fragmentShader; if (shaderID) { const shader = ShaderLib[shaderID]; vertexShader = shader.vertexShader; fragmentShader = shader.fragmentShader; } else { vertexShader = material.vertexShader; fragmentShader = material.fragmentShader; } const currentRenderTarget = renderer.getRenderTarget(); const useAlphaTest = material.alphaTest > 0; const useClearcoat = material.clearcoat > 0; const parameters = { isWebGL2, shaderID, shaderName: material.type, vertexShader, fragmentShader, defines: material.defines, isRawShaderMaterial: material.isRawShaderMaterial === true, glslVersion: material.glslVersion, precision, instancing: object.isInstancedMesh === true, instancingColor: object.isInstancedMesh === true && object.instanceColor !== null, 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, clearcoat: useClearcoat, clearcoatMap: useClearcoat && !!material.clearcoatMap, clearcoatRoughnessMap: useClearcoat && !!material.clearcoatRoughnessMap, clearcoatNormalMap: useClearcoat && !!material.clearcoatNormalMap, displacementMap: !!material.displacementMap, roughnessMap: !!material.roughnessMap, metalnessMap: !!material.metalnessMap, specularMap: !!material.specularMap, specularIntensityMap: !!material.specularIntensityMap, specularTintMap: !!material.specularTintMap, specularTintMapEncoding: getTextureEncodingFromMap(material.specularTintMap), alphaMap: !!material.alphaMap, alphaTest: useAlphaTest, gradientMap: !!material.gradientMap, sheenTint: !!material.sheenTint && (material.sheenTint.r > 0 || material.sheenTint.g > 0 || material.sheenTint.b > 0), transmission: material.transmission > 0, transmissionMap: !!material.transmissionMap, thicknessMap: !!material.thicknessMap, combine: material.combine, vertexTangents: !!material.normalMap && !!object.geometry && !!object.geometry.attributes.tangent, vertexColors: material.vertexColors, vertexAlphas: material.vertexColors === true && !!object.geometry && !!object.geometry.attributes.color && object.geometry.attributes.color.itemSize === 4, 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 || !!material.transmissionMap || !!material.thicknessMap || !!material.specularIntensityMap || !!material.specularTintMap, uvsVertexOnly: !(!!material.map || !!material.bumpMap || !!material.normalMap || !!material.specularMap || !!material.alphaMap || !!material.emissiveMap || !!material.roughnessMap || !!material.metalnessMap || !!material.clearcoatNormalMap || material.transmission > 0 || !!material.transmissionMap || !!material.thicknessMap || !!material.specularIntensityMap || !!material.specularTintMap) && !!material.displacementMap, fog: !!fog, useFog: material.fog, fogExp2: fog && fog.isFogExp2, flatShading: !!material.flatShading, sizeAttenuation: material.sizeAttenuation, logarithmicDepthBuffer, skinning: object.isSkinnedMesh === true && maxBones > 0, maxBones, useVertexTexture: floatVertexTextures, morphTargets: !!object.geometry && !!object.geometry.morphAttributes.position, morphNormals: !!object.geometry && !!object.geometry.morphAttributes.normal, 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: clipping.numPlanes, numClipIntersection: clipping.numIntersection, format: material.format, 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, doubleSided: material.side === DoubleSide, flipSided: material.side === BackSide, depthPacking: material.depthPacking !== void 0 ? 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.has("EXT_frag_depth"), rendererExtensionDrawBuffers: isWebGL2 || extensions.has("WEBGL_draw_buffers"), rendererExtensionShaderTextureLod: isWebGL2 || extensions.has("EXT_shader_texture_lod"), customProgramCacheKey: material.customProgramCacheKey() }; return parameters; } function getProgramCacheKey(parameters) { const array = []; if (parameters.shaderID) { array.push(parameters.shaderID); } else { array.push(parameters.fragmentShader); array.push(parameters.vertexShader); } if (parameters.defines !== void 0) { for (const name in parameters.defines) { array.push(name); array.push(parameters.defines[name]); } } if (parameters.isRawShaderMaterial === false) { for (let i = 0; i < parameterNames.length; i++) { array.push(parameters[parameterNames[i]]); } array.push(renderer.outputEncoding); array.push(renderer.gammaFactor); } array.push(parameters.customProgramCacheKey); return array.join(); } function getUniforms(material) { const shaderID = shaderIDs[material.type]; let uniforms; if (shaderID) { const shader = ShaderLib[shaderID]; uniforms = UniformsUtils.clone(shader.uniforms); } else { uniforms = material.uniforms; } return uniforms; } function acquireProgram(parameters, cacheKey) { let program; for (let p2 = 0, pl = programs.length; p2 < pl; p2++) { const preexistingProgram = programs[p2]; if (preexistingProgram.cacheKey === cacheKey) { program = preexistingProgram; ++program.usedTimes; break; } } if (program === void 0) { program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates); programs.push(program); } return program; } function releaseProgram(program) { if (--program.usedTimes === 0) { const i = programs.indexOf(program); programs[i] = programs[programs.length - 1]; programs.pop(); program.destroy(); } } return { getParameters, getProgramCacheKey, getUniforms, acquireProgram, releaseProgram, programs }; } function WebGLProperties() { let properties = new WeakMap(); function get(object) { let map = properties.get(object); if (map === void 0) { 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, remove, update, dispose }; } function painterSortStable(a2, b2) { if (a2.groupOrder !== b2.groupOrder) { return a2.groupOrder - b2.groupOrder; } else if (a2.renderOrder !== b2.renderOrder) { return a2.renderOrder - b2.renderOrder; } else if (a2.program !== b2.program) { return a2.program.id - b2.program.id; } else if (a2.material.id !== b2.material.id) { return a2.material.id - b2.material.id; } else if (a2.z !== b2.z) { return a2.z - b2.z; } else { return a2.id - b2.id; } } function reversePainterSortStable(a2, b2) { if (a2.groupOrder !== b2.groupOrder) { return a2.groupOrder - b2.groupOrder; } else if (a2.renderOrder !== b2.renderOrder) { return a2.renderOrder - b2.renderOrder; } else if (a2.z !== b2.z) { return b2.z - a2.z; } else { return a2.id - b2.id; } } function WebGLRenderList(properties) { const renderItems = []; let renderItemsIndex = 0; const opaque = []; const transmissive = []; const transparent = []; const defaultProgram = { id: -1 }; function init() { renderItemsIndex = 0; opaque.length = 0; transmissive.length = 0; transparent.length = 0; } function getNextRenderItem(object, geometry, material, groupOrder, z, group) { let renderItem = renderItems[renderItemsIndex]; const materialProperties = properties.get(material); if (renderItem === void 0) { renderItem = { id: object.id, object, geometry, material, program: materialProperties.program || defaultProgram, groupOrder, renderOrder: object.renderOrder, z, group }; renderItems[renderItemsIndex] = renderItem; } else { renderItem.id = object.id; renderItem.object = object; renderItem.geometry = geometry; renderItem.material = material; renderItem.program = materialProperties.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) { const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); if (material.transmission > 0) { transmissive.push(renderItem); } else if (material.transparent === true) { transparent.push(renderItem); } else { opaque.push(renderItem); } } function unshift(object, geometry, material, groupOrder, z, group) { const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); if (material.transmission > 0) { transmissive.unshift(renderItem); } else if (material.transparent === true) { transparent.unshift(renderItem); } else { opaque.unshift(renderItem); } } function sort(customOpaqueSort, customTransparentSort) { if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable); if (transmissive.length > 1) transmissive.sort(customTransparentSort || reversePainterSortStable); if (transparent.length > 1) transparent.sort(customTransparentSort || reversePainterSortStable); } function finish() { for (let i = renderItemsIndex, il = renderItems.length; i < il; i++) { const 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, transmissive, transparent, init, push, unshift, finish, sort }; } function WebGLRenderLists(properties) { let lists = new WeakMap(); function get(scene, renderCallDepth) { let list; if (lists.has(scene) === false) { list = new WebGLRenderList(properties); lists.set(scene, [list]); } else { if (renderCallDepth >= lists.get(scene).length) { list = new WebGLRenderList(properties); lists.get(scene).push(list); } else { list = lists.get(scene)[renderCallDepth]; } } return list; } function dispose() { lists = new WeakMap(); } return { get, dispose }; } function UniformsCache() { const lights = {}; return { get: function(light) { if (lights[light.id] !== void 0) { return lights[light.id]; } let 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() { const lights = {}; return { get: function(light) { if (lights[light.id] !== void 0) { return lights[light.id]; } let uniforms; switch (light.type) { case "DirectionalLight": uniforms = { shadowBias: 0, shadowNormalBias: 0, shadowRadius: 1, shadowMapSize: new Vector2() }; break; case "SpotLight": uniforms = { shadowBias: 0, shadowNormalBias: 0, shadowRadius: 1, shadowMapSize: new Vector2() }; break; case "PointLight": uniforms = { shadowBias: 0, shadowNormalBias: 0, shadowRadius: 1, shadowMapSize: new Vector2(), shadowCameraNear: 1, shadowCameraFar: 1e3 }; break; } lights[light.id] = uniforms; return uniforms; } }; } var nextVersion = 0; function shadowCastingLightsFirst(lightA, lightB) { return (lightB.castShadow ? 1 : 0) - (lightA.castShadow ? 1 : 0); } function WebGLLights(extensions, capabilities) { const cache = new UniformsCache(); const shadowCache = ShadowUniformsCache(); const 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: [], rectAreaLTC1: null, rectAreaLTC2: null, point: [], pointShadow: [], pointShadowMap: [], pointShadowMatrix: [], hemi: [] }; for (let i = 0; i < 9; i++) state.probe.push(new Vector3()); const vector3 = new Vector3(); const matrix4 = new Matrix4(); const matrix42 = new Matrix4(); function setup(lights, physicallyCorrectLights) { let r = 0, g = 0, b2 = 0; for (let i = 0; i < 9; i++) state.probe[i].set(0, 0, 0); let directionalLength = 0; let pointLength = 0; let spotLength = 0; let rectAreaLength = 0; let hemiLength = 0; let numDirectionalShadows = 0; let numPointShadows = 0; let numSpotShadows = 0; lights.sort(shadowCastingLightsFirst); const scaleFactor = physicallyCorrectLights !== true ? Math.PI : 1; for (let i = 0, l = lights.length; i < l; i++) { const light = lights[i]; const color = light.color; const intensity = light.intensity; const distance = light.distance; const shadowMap = light.shadow && light.shadow.map ? light.shadow.map.texture : null; if (light.isAmbientLight) { r += color.r * intensity * scaleFactor; g += color.g * intensity * scaleFactor; b2 += color.b * intensity * scaleFactor; } else if (light.isLightProbe) { for (let j = 0; j < 9; j++) { state.probe[j].addScaledVector(light.sh.coefficients[j], intensity); } } else if (light.isDirectionalLight) { const uniforms = cache.get(light); uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); if (light.castShadow) { const shadow = light.shadow; const shadowUniforms = shadowCache.get(light); shadowUniforms.shadowBias = shadow.bias; shadowUniforms.shadowNormalBias = shadow.normalBias; 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) { const uniforms = cache.get(light); uniforms.position.setFromMatrixPosition(light.matrixWorld); uniforms.color.copy(color).multiplyScalar(intensity * scaleFactor); uniforms.distance = distance; uniforms.coneCos = Math.cos(light.angle); uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra)); uniforms.decay = light.decay; if (light.castShadow) { const shadow = light.shadow; const shadowUniforms = shadowCache.get(light); shadowUniforms.shadowBias = shadow.bias; shadowUniforms.shadowNormalBias = shadow.normalBias; 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) { const uniforms = cache.get(light); uniforms.color.copy(color).multiplyScalar(intensity); uniforms.halfWidth.set(light.width * 0.5, 0, 0); uniforms.halfHeight.set(0, light.height * 0.5, 0); state.rectArea[rectAreaLength] = uniforms; rectAreaLength++; } else if (light.isPointLight) { const uniforms = cache.get(light); uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor); uniforms.distance = light.distance; uniforms.decay = light.decay; if (light.castShadow) { const shadow = light.shadow; const shadowUniforms = shadowCache.get(light); shadowUniforms.shadowBias = shadow.bias; shadowUniforms.shadowNormalBias = shadow.normalBias; 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) { const uniforms = cache.get(light); uniforms.skyColor.copy(light.color).multiplyScalar(intensity * scaleFactor); uniforms.groundColor.copy(light.groundColor).multiplyScalar(intensity * scaleFactor); state.hemi[hemiLength] = uniforms; hemiLength++; } } if (rectAreaLength > 0) { if (capabilities.isWebGL2) { state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; } else { if (extensions.has("OES_texture_float_linear") === true) { state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; } else if (extensions.has("OES_texture_half_float_linear") === true) { state.rectAreaLTC1 = UniformsLib.LTC_HALF_1; state.rectAreaLTC2 = UniformsLib.LTC_HALF_2; } else { console.error("THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions."); } } } state.ambient[0] = r; state.ambient[1] = g; state.ambient[2] = b2; const 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++; } } function setupView(lights, camera) { let directionalLength = 0; let pointLength = 0; let spotLength = 0; let rectAreaLength = 0; let hemiLength = 0; const viewMatrix = camera.matrixWorldInverse; for (let i = 0, l = lights.length; i < l; i++) { const light = lights[i]; if (light.isDirectionalLight) { const uniforms = state.directional[directionalLength]; uniforms.direction.setFromMatrixPosition(light.matrixWorld); vector3.setFromMatrixPosition(light.target.matrixWorld); uniforms.direction.sub(vector3); uniforms.direction.transformDirection(viewMatrix); directionalLength++; } else if (light.isSpotLight) { const uniforms = state.spot[spotLength]; uniforms.position.setFromMatrixPosition(light.matrixWorld); uniforms.position.applyMatrix4(viewMatrix); uniforms.direction.setFromMatrixPosition(light.matrixWorld); vector3.setFromMatrixPosition(light.target.matrixWorld); uniforms.direction.sub(vector3); uniforms.direction.transformDirection(viewMatrix); spotLength++; } else if (light.isRectAreaLight) { const uniforms = state.rectArea[rectAreaLength]; uniforms.position.setFromMatrixPosition(light.matrixWorld); uniforms.position.applyMatrix4(viewMatrix); matrix42.identity(); matrix4.copy(light.matrixWorld); matrix4.premultiply(viewMatrix); matrix42.extractRotation(matrix4); uniforms.halfWidth.set(light.width * 0.5, 0, 0); uniforms.halfHeight.set(0, light.height * 0.5, 0); uniforms.halfWidth.applyMatrix4(matrix42); uniforms.halfHeight.applyMatrix4(matrix42); rectAreaLength++; } else if (light.isPointLight) { const uniforms = state.point[pointLength]; uniforms.position.setFromMatrixPosition(light.matrixWorld); uniforms.position.applyMatrix4(viewMatrix); pointLength++; } else if (light.isHemisphereLight) { const uniforms = state.hemi[hemiLength]; uniforms.direction.setFromMatrixPosition(light.matrixWorld); uniforms.direction.transformDirection(viewMatrix); uniforms.direction.normalize(); hemiLength++; } } } return { setup, setupView, state }; } function WebGLRenderState(extensions, capabilities) { const lights = new WebGLLights(extensions, capabilities); const lightsArray = []; const shadowsArray = []; function init() { lightsArray.length = 0; shadowsArray.length = 0; } function pushLight(light) { lightsArray.push(light); } function pushShadow(shadowLight) { shadowsArray.push(shadowLight); } function setupLights(physicallyCorrectLights) { lights.setup(lightsArray, physicallyCorrectLights); } function setupLightsView(camera) { lights.setupView(lightsArray, camera); } const state = { lightsArray, shadowsArray, lights }; return { init, state, setupLights, setupLightsView, pushLight, pushShadow }; } function WebGLRenderStates(extensions, capabilities) { let renderStates = new WeakMap(); function get(scene, renderCallDepth = 0) { let renderState; if (renderStates.has(scene) === false) { renderState = new WebGLRenderState(extensions, capabilities); renderStates.set(scene, [renderState]); } else { if (renderCallDepth >= renderStates.get(scene).length) { renderState = new WebGLRenderState(extensions, capabilities); renderStates.get(scene).push(renderState); } else { renderState = renderStates.get(scene)[renderCallDepth]; } } return renderState; } function dispose() { renderStates = new WeakMap(); } return { get, dispose }; } var MeshDepthMaterial = class extends Material { constructor(parameters) { super(); this.type = "MeshDepthMaterial"; this.depthPacking = BasicDepthPacking; 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); } copy(source) { super.copy(source); this.depthPacking = source.depthPacking; 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; } }; MeshDepthMaterial.prototype.isMeshDepthMaterial = true; var MeshDistanceMaterial = class extends Material { constructor(parameters) { super(); this.type = "MeshDistanceMaterial"; this.referencePosition = new Vector3(); this.nearDistance = 1; this.farDistance = 1e3; this.map = null; this.alphaMap = null; this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.fog = false; this.setValues(parameters); } copy(source) { super.copy(source); this.referencePosition.copy(source.referencePosition); this.nearDistance = source.nearDistance; this.farDistance = source.farDistance; this.map = source.map; this.alphaMap = source.alphaMap; this.displacementMap = source.displacementMap; this.displacementScale = source.displacementScale; this.displacementBias = source.displacementBias; return this; } }; MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true; var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\nuniform float samples;\n#include \nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\n float uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n float uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n for ( float i = 0.0; i < samples; i ++ ) {\n float uvOffset = uvStart + i * uvStride;\n #ifdef HORIZONTAL_PASS\n vec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 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, uvOffset ) * radius ) / resolution ) );\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean / samples;\n squared_mean = squared_mean / samples;\n float std_dev = sqrt( squared_mean - mean * mean );\n gl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}"; var vsm_vert = "void main() {\n gl_Position = vec4( position, 1.0 );\n}"; function WebGLShadowMap(_renderer, _objects, _capabilities) { let _frustum = new Frustum(); const _shadowMapSize = new Vector2(), _viewportSize = new Vector2(), _viewport = new Vector4(), _depthMaterial = new MeshDepthMaterial({ depthPacking: RGBADepthPacking }), _distanceMaterial = new MeshDistanceMaterial(), _materialCache = {}, _maxTextureSize = _capabilities.maxTextureSize; const shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide }; const shadowMaterialVertical = new ShaderMaterial({ uniforms: { shadow_pass: { value: null }, resolution: { value: new Vector2() }, radius: { value: 4 }, samples: { value: 8 } }, vertexShader: vsm_vert, fragmentShader: vsm_frag }); const shadowMaterialHorizontal = shadowMaterialVertical.clone(); shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1; const fullScreenTri = new BufferGeometry(); fullScreenTri.setAttribute("position", new BufferAttribute(new Float32Array([-1, -1, 0.5, 3, -1, 0.5, -1, 3, 0.5]), 3)); const fullScreenMesh = new Mesh(fullScreenTri, shadowMaterialVertical); const 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; const currentRenderTarget = _renderer.getRenderTarget(); const activeCubeFace = _renderer.getActiveCubeFace(); const activeMipmapLevel = _renderer.getActiveMipmapLevel(); const _state = _renderer.state; _state.setBlending(NoBlending); _state.buffers.color.setClear(1, 1, 1, 1); _state.buffers.depth.setTest(true); _state.setScissorTest(false); for (let i = 0, il = lights.length; i < il; i++) { const light = lights[i]; const shadow = light.shadow; if (shadow === void 0) { console.warn("THREE.WebGLShadowMap:", light, "has no shadow."); continue; } if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue; _shadowMapSize.copy(shadow.mapSize); const shadowFrameExtents = shadow.getFrameExtents(); _shadowMapSize.multiply(shadowFrameExtents); _viewportSize.copy(shadow.mapSize); if (_shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize) { 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) { const 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) { const 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(); const viewportCount = shadow.getViewportCount(); for (let vp = 0; vp < viewportCount; vp++) { const 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); } if (!shadow.isPointLightShadow && this.type === VSMShadowMap) { VSMPass(shadow, camera); } shadow.needsUpdate = false; } scope.needsUpdate = false; _renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel); }; function VSMPass(shadow, camera) { const geometry = _objects.update(fullScreenMesh); shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; shadowMaterialVertical.uniforms.radius.value = shadow.radius; shadowMaterialVertical.uniforms.samples.value = shadow.blurSamples; _renderer.setRenderTarget(shadow.mapPass); _renderer.clear(); _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture; shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize; shadowMaterialHorizontal.uniforms.radius.value = shadow.radius; shadowMaterialHorizontal.uniforms.samples.value = shadow.blurSamples; _renderer.setRenderTarget(shadow.map); _renderer.clear(); _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null); } function getDepthMaterial(object, geometry, material, light, shadowCameraNear, shadowCameraFar, type) { let result = null; const customMaterial = light.isPointLight === true ? object.customDistanceMaterial : object.customDepthMaterial; if (customMaterial !== void 0) { result = customMaterial; } else { result = light.isPointLight === true ? _distanceMaterial : _depthMaterial; } if (_renderer.localClippingEnabled && material.clipShadows === true && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0) { const keyA = result.uuid, keyB = material.uuid; let materialsForVariant = _materialCache[keyA]; if (materialsForVariant === void 0) { materialsForVariant = {}; _materialCache[keyA] = materialsForVariant; } let cachedMaterial = materialsForVariant[keyB]; if (cachedMaterial === void 0) { 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.alphaMap = material.alphaMap; result.alphaTest = material.alphaTest; result.clipShadows = material.clipShadows; result.clippingPlanes = material.clippingPlanes; result.clipIntersection = material.clipIntersection; result.displacementMap = material.displacementMap; result.displacementScale = material.displacementScale; result.displacementBias = material.displacementBias; 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; const 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); const geometry = _objects.update(object); const material = object.material; if (Array.isArray(material)) { const groups = geometry.groups; for (let k = 0, kl = groups.length; k < kl; k++) { const group = groups[k]; const groupMaterial = material[group.materialIndex]; if (groupMaterial && groupMaterial.visible) { const depthMaterial = getDepthMaterial(object, geometry, groupMaterial, light, shadowCamera.near, shadowCamera.far, type); _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group); } } } else if (material.visible) { const depthMaterial = getDepthMaterial(object, geometry, material, light, shadowCamera.near, shadowCamera.far, type); _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null); } } } const children = object.children; for (let i = 0, l = children.length; i < l; i++) { renderObject(children[i], camera, shadowCamera, light, type); } } } function WebGLState(gl, extensions, capabilities) { const isWebGL2 = capabilities.isWebGL2; function ColorBuffer() { let locked = false; const color = new Vector4(); let currentColorMask = null; const 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, b2, a2, premultipliedAlpha) { if (premultipliedAlpha === true) { r *= a2; g *= a2; b2 *= a2; } color.set(r, g, b2, a2); if (currentColorClear.equals(color) === false) { gl.clearColor(r, g, b2, a2); currentColorClear.copy(color); } }, reset: function() { locked = false; currentColorMask = null; currentColorClear.set(-1, 0, 0, 0); } }; } function DepthBuffer() { let locked = false; let currentDepthMask = null; let currentDepthFunc = null; let 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() { let locked = false; let currentStencilMask = null; let currentStencilFunc = null; let currentStencilRef = null; let currentStencilFuncMask = null; let currentStencilFail = null; let currentStencilZFail = null; let currentStencilZPass = null; let 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; } }; } const colorBuffer = new ColorBuffer(); const depthBuffer = new DepthBuffer(); const stencilBuffer = new StencilBuffer(); let enabledCapabilities = {}; let xrFramebuffer = null; let currentBoundFramebuffers = {}; let currentProgram = null; let currentBlendingEnabled = false; let currentBlending = null; let currentBlendEquation = null; let currentBlendSrc = null; let currentBlendDst = null; let currentBlendEquationAlpha = null; let currentBlendSrcAlpha = null; let currentBlendDstAlpha = null; let currentPremultipledAlpha = false; let currentFlipSided = null; let currentCullFace = null; let currentLineWidth = null; let currentPolygonOffsetFactor = null; let currentPolygonOffsetUnits = null; const maxTextures = gl.getParameter(35661); let lineWidthAvailable = false; let version = 0; const glVersion = gl.getParameter(7938); if (glVersion.indexOf("WebGL") !== -1) { version = parseFloat(/^WebGL (\d)/.exec(glVersion)[1]); lineWidthAvailable = version >= 1; } else if (glVersion.indexOf("OpenGL ES") !== -1) { version = parseFloat(/^OpenGL ES (\d)/.exec(glVersion)[1]); lineWidthAvailable = version >= 2; } let currentTextureSlot = null; let currentBoundTextures = {}; const scissorParam = gl.getParameter(3088); const viewportParam = gl.getParameter(2978); const currentScissor = new Vector4().fromArray(scissorParam); const currentViewport = new Vector4().fromArray(viewportParam); function createTexture(type, target, count) { const data = new Uint8Array(4); const texture = gl.createTexture(); gl.bindTexture(type, texture); gl.texParameteri(type, 10241, 9728); gl.texParameteri(type, 10240, 9728); for (let i = 0; i < count; i++) { gl.texImage2D(target + i, 0, 6408, 1, 1, 0, 6408, 5121, data); } return texture; } const emptyTextures = {}; emptyTextures[3553] = createTexture(3553, 3553, 1); emptyTextures[34067] = createTexture(34067, 34069, 6); 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 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 bindXRFramebuffer(framebuffer) { if (framebuffer !== xrFramebuffer) { gl.bindFramebuffer(36160, framebuffer); xrFramebuffer = framebuffer; } } function bindFramebuffer(target, framebuffer) { if (framebuffer === null && xrFramebuffer !== null) framebuffer = xrFramebuffer; if (currentBoundFramebuffers[target] !== framebuffer) { gl.bindFramebuffer(target, framebuffer); currentBoundFramebuffers[target] = framebuffer; if (isWebGL2) { if (target === 36009) { currentBoundFramebuffers[36160] = framebuffer; } if (target === 36160) { currentBoundFramebuffers[36009] = framebuffer; } } return true; } return false; } function useProgram(program) { if (currentProgram !== program) { gl.useProgram(program); currentProgram = program; return true; } return false; } const equationToGL = { [AddEquation]: 32774, [SubtractEquation]: 32778, [ReverseSubtractEquation]: 32779 }; if (isWebGL2) { equationToGL[MinEquation] = 32775; equationToGL[MaxEquation] = 32776; } else { const extension = extensions.get("EXT_blend_minmax"); if (extension !== null) { equationToGL[MinEquation] = extension.MIN_EXT; equationToGL[MaxEquation] = extension.MAX_EXT; } } const factorToGL = { [ZeroFactor]: 0, [OneFactor]: 1, [SrcColorFactor]: 768, [SrcAlphaFactor]: 770, [SrcAlphaSaturateFactor]: 776, [DstColorFactor]: 774, [DstAlphaFactor]: 772, [OneMinusSrcColorFactor]: 769, [OneMinusSrcAlphaFactor]: 771, [OneMinusDstColorFactor]: 775, [OneMinusDstAlphaFactor]: 773 }; function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha) { if (blending === NoBlending) { if (currentBlendingEnabled === true) { disable(3042); currentBlendingEnabled = false; } return; } if (currentBlendingEnabled === false) { 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; } 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); let 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); const 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); material.alphaToCoverage === true ? enable(32926) : disable(32926); } 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); } } function activeTexture(webglSlot) { if (webglSlot === void 0) webglSlot = 33984 + maxTextures - 1; if (currentTextureSlot !== webglSlot) { gl.activeTexture(webglSlot); currentTextureSlot = webglSlot; } } function bindTexture(webglType, webglTexture) { if (currentTextureSlot === null) { activeTexture(); } let boundTexture = currentBoundTextures[currentTextureSlot]; if (boundTexture === void 0) { boundTexture = { type: void 0, texture: void 0 }; currentBoundTextures[currentTextureSlot] = boundTexture; } if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) { gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]); boundTexture.type = webglType; boundTexture.texture = webglTexture; } } function unbindTexture() { const boundTexture = currentBoundTextures[currentTextureSlot]; if (boundTexture !== void 0 && boundTexture.type !== void 0) { gl.bindTexture(boundTexture.type, null); boundTexture.type = void 0; boundTexture.texture = void 0; } } 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(scissor2) { if (currentScissor.equals(scissor2) === false) { gl.scissor(scissor2.x, scissor2.y, scissor2.z, scissor2.w); currentScissor.copy(scissor2); } } function viewport(viewport2) { if (currentViewport.equals(viewport2) === false) { gl.viewport(viewport2.x, viewport2.y, viewport2.z, viewport2.w); currentViewport.copy(viewport2); } } function reset() { gl.disable(3042); gl.disable(2884); gl.disable(2929); gl.disable(32823); gl.disable(3089); gl.disable(2960); gl.disable(32926); gl.blendEquation(32774); gl.blendFunc(1, 0); gl.blendFuncSeparate(1, 0, 1, 0); gl.colorMask(true, true, true, true); gl.clearColor(0, 0, 0, 0); gl.depthMask(true); gl.depthFunc(513); gl.clearDepth(1); gl.stencilMask(4294967295); gl.stencilFunc(519, 0, 4294967295); gl.stencilOp(7680, 7680, 7680); gl.clearStencil(0); gl.cullFace(1029); gl.frontFace(2305); gl.polygonOffset(0, 0); gl.activeTexture(33984); gl.bindFramebuffer(36160, null); if (isWebGL2 === true) { gl.bindFramebuffer(36009, null); gl.bindFramebuffer(36008, null); } gl.useProgram(null); gl.lineWidth(1); gl.scissor(0, 0, gl.canvas.width, gl.canvas.height); gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); enabledCapabilities = {}; currentTextureSlot = null; currentBoundTextures = {}; xrFramebuffer = null; currentBoundFramebuffers = {}; currentProgram = null; currentBlendingEnabled = false; currentBlending = null; currentBlendEquation = null; currentBlendSrc = null; currentBlendDst = null; currentBlendEquationAlpha = null; currentBlendSrcAlpha = null; currentBlendDstAlpha = null; currentPremultipledAlpha = false; currentFlipSided = null; currentCullFace = null; currentLineWidth = null; currentPolygonOffsetFactor = null; currentPolygonOffsetUnits = null; currentScissor.set(0, 0, gl.canvas.width, gl.canvas.height); currentViewport.set(0, 0, gl.canvas.width, gl.canvas.height); colorBuffer.reset(); depthBuffer.reset(); stencilBuffer.reset(); } return { buffers: { color: colorBuffer, depth: depthBuffer, stencil: stencilBuffer }, enable, disable, bindFramebuffer, bindXRFramebuffer, useProgram, setBlending, setMaterial, setFlipSided, setCullFace, setLineWidth, setPolygonOffset, setScissorTest, activeTexture, bindTexture, unbindTexture, compressedTexImage2D, texImage2D, texImage3D, scissor, viewport, reset }; } function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info) { const isWebGL2 = capabilities.isWebGL2; const maxTextures = capabilities.maxTextures; const maxCubemapSize = capabilities.maxCubemapSize; const maxTextureSize = capabilities.maxTextureSize; const maxSamples = capabilities.maxSamples; const _videoTextures = new WeakMap(); let _canvas2; let useOffscreenCanvas = false; try { useOffscreenCanvas = typeof OffscreenCanvas !== "undefined" && new OffscreenCanvas(1, 1).getContext("2d") !== null; } catch (err) { } function createCanvas(width, height) { return useOffscreenCanvas ? new OffscreenCanvas(width, height) : document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); } function resizeImage(image, needsPowerOfTwo, needsNewCanvas, maxSize) { let scale = 1; if (image.width > maxSize || image.height > maxSize) { scale = maxSize / Math.max(image.width, image.height); } if (scale < 1 || needsPowerOfTwo === true) { if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) { const floor = needsPowerOfTwo ? floorPowerOfTwo : Math.floor; const width = floor(scale * image.width); const height = floor(scale * image.height); if (_canvas2 === void 0) _canvas2 = createCanvas(width, height); const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas2; canvas.width = width; canvas.height = height; const 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$1(image) { return isPowerOfTwo(image.width) && 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, depth = 1) { _gl.generateMipmap(target); const textureProperties = properties.get(texture); textureProperties.__maxMipLevel = Math.log2(Math.max(width, height, depth)); } function getInternalFormat(internalFormatName, glFormat, glType) { if (isWebGL2 === false) return glFormat; if (internalFormatName !== null) { if (_gl[internalFormatName] !== void 0) return _gl[internalFormatName]; console.warn("THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format '" + internalFormatName + "'"); } let 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; } function filterFallback(f) { if (f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter) { return 9728; } return 9729; } function onTextureDispose(event) { const texture = event.target; texture.removeEventListener("dispose", onTextureDispose); deallocateTexture(texture); if (texture.isVideoTexture) { _videoTextures.delete(texture); } info.memory.textures--; } function onRenderTargetDispose(event) { const renderTarget = event.target; renderTarget.removeEventListener("dispose", onRenderTargetDispose); deallocateRenderTarget(renderTarget); } function deallocateTexture(texture) { const textureProperties = properties.get(texture); if (textureProperties.__webglInit === void 0) return; _gl.deleteTexture(textureProperties.__webglTexture); properties.remove(texture); } function deallocateRenderTarget(renderTarget) { const texture = renderTarget.texture; const renderTargetProperties = properties.get(renderTarget); const textureProperties = properties.get(texture); if (!renderTarget) return; if (textureProperties.__webglTexture !== void 0) { _gl.deleteTexture(textureProperties.__webglTexture); info.memory.textures--; } if (renderTarget.depthTexture) { renderTarget.depthTexture.dispose(); } if (renderTarget.isWebGLCubeRenderTarget) { for (let i = 0; i < 6; i++) { _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]); if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]); } } else { _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer); if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer); if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer); if (renderTargetProperties.__webglColorRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer); if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer); } if (renderTarget.isWebGLMultipleRenderTargets) { for (let i = 0, il = texture.length; i < il; i++) { const attachmentProperties = properties.get(texture[i]); if (attachmentProperties.__webglTexture) { _gl.deleteTexture(attachmentProperties.__webglTexture); info.memory.textures--; } properties.remove(texture[i]); } } properties.remove(texture); properties.remove(renderTarget); } let textureUnits = 0; function resetTextureUnits() { textureUnits = 0; } function allocateTextureUnit() { const textureUnit = textureUnits; if (textureUnit >= maxTextures) { console.warn("THREE.WebGLTextures: Trying to use " + textureUnit + " texture units while this GPU supports only " + maxTextures); } textureUnits += 1; return textureUnit; } function setTexture2D(texture, slot) { const textureProperties = properties.get(texture); if (texture.isVideoTexture) updateVideoTexture(texture); if (texture.version > 0 && textureProperties.__version !== texture.version) { const image = texture.image; if (image === void 0) { console.warn("THREE.WebGLRenderer: Texture marked for update but image is undefined"); } else if (image.complete === false) { console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete"); } else { uploadTexture(textureProperties, texture, slot); return; } } state.activeTexture(33984 + slot); state.bindTexture(3553, textureProperties.__webglTexture); } function setTexture2DArray(texture, slot) { const textureProperties = properties.get(texture); if (texture.version > 0 && textureProperties.__version !== texture.version) { uploadTexture(textureProperties, texture, slot); return; } state.activeTexture(33984 + slot); state.bindTexture(35866, textureProperties.__webglTexture); } function setTexture3D(texture, slot) { const textureProperties = properties.get(texture); if (texture.version > 0 && textureProperties.__version !== texture.version) { uploadTexture(textureProperties, texture, slot); return; } state.activeTexture(33984 + slot); state.bindTexture(32879, textureProperties.__webglTexture); } function setTextureCube(texture, slot) { const textureProperties = properties.get(texture); if (texture.version > 0 && textureProperties.__version !== texture.version) { uploadCubeTexture(textureProperties, texture, slot); return; } state.activeTexture(33984 + slot); state.bindTexture(34067, textureProperties.__webglTexture); } const wrappingToGL = { [RepeatWrapping]: 10497, [ClampToEdgeWrapping]: 33071, [MirroredRepeatWrapping]: 33648 }; const filterToGL = { [NearestFilter]: 9728, [NearestMipmapNearestFilter]: 9984, [NearestMipmapLinearFilter]: 9986, [LinearFilter]: 9729, [LinearMipmapNearestFilter]: 9985, [LinearMipmapLinearFilter]: 9987 }; function setTextureParameters(textureType, texture, supportsMips) { if (supportsMips) { _gl.texParameteri(textureType, 10242, wrappingToGL[texture.wrapS]); _gl.texParameteri(textureType, 10243, wrappingToGL[texture.wrapT]); if (textureType === 32879 || textureType === 35866) { _gl.texParameteri(textureType, 32882, wrappingToGL[texture.wrapR]); } _gl.texParameteri(textureType, 10240, filterToGL[texture.magFilter]); _gl.texParameteri(textureType, 10241, filterToGL[texture.minFilter]); } else { _gl.texParameteri(textureType, 10242, 33071); _gl.texParameteri(textureType, 10243, 33071); if (textureType === 32879 || textureType === 35866) { _gl.texParameteri(textureType, 32882, 33071); } if (texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping) { console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping."); } _gl.texParameteri(textureType, 10240, filterFallback(texture.magFilter)); _gl.texParameteri(textureType, 10241, filterFallback(texture.minFilter)); if (texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) { console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter."); } } if (extensions.has("EXT_texture_filter_anisotropic") === true) { const extension = extensions.get("EXT_texture_filter_anisotropic"); if (texture.type === FloatType && extensions.has("OES_texture_float_linear") === false) return; if (isWebGL2 === false && (texture.type === HalfFloatType && extensions.has("OES_texture_half_float_linear") === false)) return; if (texture.anisotropy > 1 || properties.get(texture).__currentAnisotropy) { _gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture.anisotropy, capabilities.getMaxAnisotropy())); properties.get(texture).__currentAnisotropy = texture.anisotropy; } } } function initTexture(textureProperties, texture) { if (textureProperties.__webglInit === void 0) { textureProperties.__webglInit = true; texture.addEventListener("dispose", onTextureDispose); textureProperties.__webglTexture = _gl.createTexture(); info.memory.textures++; } } function uploadTexture(textureProperties, texture, slot) { let textureType = 3553; if (texture.isDataTexture2DArray) textureType = 35866; if (texture.isDataTexture3D) textureType = 32879; initTexture(textureProperties, texture); state.activeTexture(33984 + slot); state.bindTexture(textureType, textureProperties.__webglTexture); _gl.pixelStorei(37440, texture.flipY); _gl.pixelStorei(37441, texture.premultiplyAlpha); _gl.pixelStorei(3317, texture.unpackAlignment); _gl.pixelStorei(37443, 0); const needsPowerOfTwo = textureNeedsPowerOfTwo(texture) && isPowerOfTwo$1(texture.image) === false; const image = resizeImage(texture.image, needsPowerOfTwo, false, maxTextureSize); const supportsMips = isPowerOfTwo$1(image) || isWebGL2, glFormat = utils.convert(texture.format); let glType = utils.convert(texture.type), glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType); setTextureParameters(textureType, texture, supportsMips); let mipmap; const mipmaps = texture.mipmaps; if (texture.isDepthTexture) { glInternalFormat = 6402; if (isWebGL2) { if (texture.type === FloatType) { glInternalFormat = 36012; } else if (texture.type === UnsignedIntType) { glInternalFormat = 33190; } else if (texture.type === UnsignedInt248Type) { glInternalFormat = 35056; } else { glInternalFormat = 33189; } } else { if (texture.type === FloatType) { console.error("WebGLRenderer: Floating point depth texture requires WebGL2."); } } if (texture.format === DepthFormat && glInternalFormat === 6402) { if (texture.type !== UnsignedShortType && texture.type !== UnsignedIntType) { console.warn("THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture."); texture.type = UnsignedShortType; glType = utils.convert(texture.type); } } if (texture.format === DepthStencilFormat && glInternalFormat === 6402) { glInternalFormat = 34041; if (texture.type !== UnsignedInt248Type) { console.warn("THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture."); texture.type = UnsignedInt248Type; glType = utils.convert(texture.type); } } state.texImage2D(3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null); } else if (texture.isDataTexture) { if (mipmaps.length > 0 && supportsMips) { for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; state.texImage2D(3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); } texture.generateMipmaps = false; textureProperties.__maxMipLevel = mipmaps.length - 1; } else { state.texImage2D(3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data); textureProperties.__maxMipLevel = 0; } } else if (texture.isCompressedTexture) { for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; if (texture.format !== RGBAFormat && texture.format !== RGBFormat) { if (glFormat !== null) { state.compressedTexImage2D(3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); } else { console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"); } } else { state.texImage2D(3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); } } textureProperties.__maxMipLevel = mipmaps.length - 1; } else if (texture.isDataTexture2DArray) { state.texImage3D(35866, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); textureProperties.__maxMipLevel = 0; } else if (texture.isDataTexture3D) { state.texImage3D(32879, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); textureProperties.__maxMipLevel = 0; } else { if (mipmaps.length > 0 && supportsMips) { for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; state.texImage2D(3553, i, glInternalFormat, glFormat, glType, mipmap); } texture.generateMipmaps = false; textureProperties.__maxMipLevel = mipmaps.length - 1; } else { state.texImage2D(3553, 0, glInternalFormat, glFormat, glType, image); textureProperties.__maxMipLevel = 0; } } if (textureNeedsGenerateMipmaps(texture, supportsMips)) { generateMipmap(textureType, texture, image.width, image.height); } textureProperties.__version = texture.version; if (texture.onUpdate) texture.onUpdate(texture); } function uploadCubeTexture(textureProperties, texture, slot) { if (texture.image.length !== 6) return; initTexture(textureProperties, texture); state.activeTexture(33984 + slot); state.bindTexture(34067, textureProperties.__webglTexture); _gl.pixelStorei(37440, texture.flipY); _gl.pixelStorei(37441, texture.premultiplyAlpha); _gl.pixelStorei(3317, texture.unpackAlignment); _gl.pixelStorei(37443, 0); const isCompressed = texture && (texture.isCompressedTexture || texture.image[0].isCompressedTexture); const isDataTexture = texture.image[0] && texture.image[0].isDataTexture; const cubeImage = []; for (let i = 0; i < 6; i++) { if (!isCompressed && !isDataTexture) { cubeImage[i] = resizeImage(texture.image[i], false, true, maxCubemapSize); } else { cubeImage[i] = isDataTexture ? texture.image[i].image : texture.image[i]; } } const image = cubeImage[0], supportsMips = isPowerOfTwo$1(image) || isWebGL2, glFormat = utils.convert(texture.format), glType = utils.convert(texture.type), glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType); setTextureParameters(34067, texture, supportsMips); let mipmaps; if (isCompressed) { for (let i = 0; i < 6; i++) { mipmaps = cubeImage[i].mipmaps; for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; if (texture.format !== RGBAFormat && texture.format !== RGBFormat) { if (glFormat !== null) { state.compressedTexImage2D(34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); } else { console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()"); } } else { state.texImage2D(34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); } } } textureProperties.__maxMipLevel = mipmaps.length - 1; } else { mipmaps = texture.mipmaps; for (let i = 0; i < 6; i++) { if (isDataTexture) { state.texImage2D(34069 + i, 0, glInternalFormat, cubeImage[i].width, cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data); for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; const mipmapImage = mipmap.image[i].image; state.texImage2D(34069 + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data); } } else { state.texImage2D(34069 + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; state.texImage2D(34069 + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]); } } } textureProperties.__maxMipLevel = mipmaps.length; } if (textureNeedsGenerateMipmaps(texture, supportsMips)) { generateMipmap(34067, texture, image.width, image.height); } textureProperties.__version = texture.version; if (texture.onUpdate) texture.onUpdate(texture); } function setupFrameBufferTexture(framebuffer, renderTarget, texture, attachment, textureTarget) { const glFormat = utils.convert(texture.format); const glType = utils.convert(texture.type); const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType); if (textureTarget === 32879 || textureTarget === 35866) { state.texImage3D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.depth, 0, glFormat, glType, null); } else { state.texImage2D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null); } state.bindFramebuffer(36160, framebuffer); _gl.framebufferTexture2D(36160, attachment, textureTarget, properties.get(texture).__webglTexture, 0); state.bindFramebuffer(36160, null); } function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) { _gl.bindRenderbuffer(36161, renderbuffer); if (renderTarget.depthBuffer && !renderTarget.stencilBuffer) { let glInternalFormat = 33189; if (isMultisample) { const depthTexture = renderTarget.depthTexture; if (depthTexture && depthTexture.isDepthTexture) { if (depthTexture.type === FloatType) { glInternalFormat = 36012; } else if (depthTexture.type === UnsignedIntType) { glInternalFormat = 33190; } } const samples = getRenderTargetSamples(renderTarget); _gl.renderbufferStorageMultisample(36161, samples, glInternalFormat, renderTarget.width, renderTarget.height); } else { _gl.renderbufferStorage(36161, glInternalFormat, renderTarget.width, renderTarget.height); } _gl.framebufferRenderbuffer(36160, 36096, 36161, renderbuffer); } else if (renderTarget.depthBuffer && renderTarget.stencilBuffer) { if (isMultisample) { const samples = getRenderTargetSamples(renderTarget); _gl.renderbufferStorageMultisample(36161, samples, 35056, renderTarget.width, renderTarget.height); } else { _gl.renderbufferStorage(36161, 34041, renderTarget.width, renderTarget.height); } _gl.framebufferRenderbuffer(36160, 33306, 36161, renderbuffer); } else { const texture = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture[0] : renderTarget.texture; const glFormat = utils.convert(texture.format); const glType = utils.convert(texture.type); const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType); if (isMultisample) { const samples = getRenderTargetSamples(renderTarget); _gl.renderbufferStorageMultisample(36161, samples, glInternalFormat, renderTarget.width, renderTarget.height); } else { _gl.renderbufferStorage(36161, glInternalFormat, renderTarget.width, renderTarget.height); } } _gl.bindRenderbuffer(36161, null); } function setupDepthTexture(framebuffer, renderTarget) { const isCube = renderTarget && renderTarget.isWebGLCubeRenderTarget; if (isCube) throw new Error("Depth Texture with cube render targets is not supported"); state.bindFramebuffer(36160, framebuffer); if (!(renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture)) { throw new Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture"); } if (!properties.get(renderTarget.depthTexture).__webglTexture || renderTarget.depthTexture.image.width !== renderTarget.width || renderTarget.depthTexture.image.height !== renderTarget.height) { renderTarget.depthTexture.image.width = renderTarget.width; renderTarget.depthTexture.image.height = renderTarget.height; renderTarget.depthTexture.needsUpdate = true; } setTexture2D(renderTarget.depthTexture, 0); const webglDepthTexture = properties.get(renderTarget.depthTexture).__webglTexture; if (renderTarget.depthTexture.format === DepthFormat) { _gl.framebufferTexture2D(36160, 36096, 3553, webglDepthTexture, 0); } else if (renderTarget.depthTexture.format === DepthStencilFormat) { _gl.framebufferTexture2D(36160, 33306, 3553, webglDepthTexture, 0); } else { throw new Error("Unknown depthTexture format"); } } function setupDepthRenderbuffer(renderTarget) { const renderTargetProperties = properties.get(renderTarget); const isCube = renderTarget.isWebGLCubeRenderTarget === true; if (renderTarget.depthTexture) { if (isCube) throw new Error("target.depthTexture not supported in Cube render targets"); setupDepthTexture(renderTargetProperties.__webglFramebuffer, renderTarget); } else { if (isCube) { renderTargetProperties.__webglDepthbuffer = []; for (let i = 0; i < 6; i++) { state.bindFramebuffer(36160, renderTargetProperties.__webglFramebuffer[i]); renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer(); setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false); } } else { state.bindFramebuffer(36160, renderTargetProperties.__webglFramebuffer); renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false); } } state.bindFramebuffer(36160, null); } function setupRenderTarget(renderTarget) { const texture = renderTarget.texture; const renderTargetProperties = properties.get(renderTarget); const textureProperties = properties.get(texture); renderTarget.addEventListener("dispose", onRenderTargetDispose); if (renderTarget.isWebGLMultipleRenderTargets !== true) { textureProperties.__webglTexture = _gl.createTexture(); textureProperties.__version = texture.version; info.memory.textures++; } const isCube = renderTarget.isWebGLCubeRenderTarget === true; const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; const isMultisample = renderTarget.isWebGLMultisampleRenderTarget === true; const isRenderTarget3D = texture.isDataTexture3D || texture.isDataTexture2DArray; const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; if (isWebGL2 && texture.format === RGBFormat && (texture.type === FloatType || texture.type === HalfFloatType)) { texture.format = RGBAFormat; console.warn("THREE.WebGLRenderer: Rendering to textures with RGB format is not supported. Using RGBA format instead."); } if (isCube) { renderTargetProperties.__webglFramebuffer = []; for (let i = 0; i < 6; i++) { renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer(); } } else { renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); if (isMultipleRenderTargets) { if (capabilities.drawBuffers) { const textures = renderTarget.texture; for (let i = 0, il = textures.length; i < il; i++) { const attachmentProperties = properties.get(textures[i]); if (attachmentProperties.__webglTexture === void 0) { attachmentProperties.__webglTexture = _gl.createTexture(); info.memory.textures++; } } } else { console.warn("THREE.WebGLRenderer: WebGLMultipleRenderTargets can only be used with WebGL2 or WEBGL_draw_buffers extension."); } } else if (isMultisample) { if (isWebGL2) { renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer(); _gl.bindRenderbuffer(36161, renderTargetProperties.__webglColorRenderbuffer); const glFormat = utils.convert(texture.format); const glType = utils.convert(texture.type); const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType); const samples = getRenderTargetSamples(renderTarget); _gl.renderbufferStorageMultisample(36161, samples, glInternalFormat, renderTarget.width, renderTarget.height); state.bindFramebuffer(36160, renderTargetProperties.__webglMultisampledFramebuffer); _gl.framebufferRenderbuffer(36160, 36064, 36161, renderTargetProperties.__webglColorRenderbuffer); _gl.bindRenderbuffer(36161, null); if (renderTarget.depthBuffer) { renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer(); setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true); } state.bindFramebuffer(36160, null); } else { console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2."); } } } if (isCube) { state.bindTexture(34067, textureProperties.__webglTexture); setTextureParameters(34067, texture, supportsMips); for (let i = 0; i < 6; i++) { setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, texture, 36064, 34069 + i); } if (textureNeedsGenerateMipmaps(texture, supportsMips)) { generateMipmap(34067, texture, renderTarget.width, renderTarget.height); } state.unbindTexture(); } else if (isMultipleRenderTargets) { const textures = renderTarget.texture; for (let i = 0, il = textures.length; i < il; i++) { const attachment = textures[i]; const attachmentProperties = properties.get(attachment); state.bindTexture(3553, attachmentProperties.__webglTexture); setTextureParameters(3553, attachment, supportsMips); setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, attachment, 36064 + i, 3553); if (textureNeedsGenerateMipmaps(attachment, supportsMips)) { generateMipmap(3553, attachment, renderTarget.width, renderTarget.height); } } state.unbindTexture(); } else { let glTextureType = 3553; if (isRenderTarget3D) { if (isWebGL2) { const isTexture3D = texture.isDataTexture3D; glTextureType = isTexture3D ? 32879 : 35866; } else { console.warn("THREE.DataTexture3D and THREE.DataTexture2DArray only supported with WebGL2."); } } state.bindTexture(glTextureType, textureProperties.__webglTexture); setTextureParameters(glTextureType, texture, supportsMips); setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture, 36064, glTextureType); if (textureNeedsGenerateMipmaps(texture, supportsMips)) { generateMipmap(glTextureType, texture, renderTarget.width, renderTarget.height, renderTarget.depth); } state.unbindTexture(); } if (renderTarget.depthBuffer) { setupDepthRenderbuffer(renderTarget); } } function updateRenderTargetMipmap(renderTarget) { const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture]; for (let i = 0, il = textures.length; i < il; i++) { const texture = textures[i]; if (textureNeedsGenerateMipmaps(texture, supportsMips)) { const target = renderTarget.isWebGLCubeRenderTarget ? 34067 : 3553; const webglTexture = properties.get(texture).__webglTexture; state.bindTexture(target, webglTexture); generateMipmap(target, texture, renderTarget.width, renderTarget.height); state.unbindTexture(); } } } function updateMultisampleRenderTarget(renderTarget) { if (renderTarget.isWebGLMultisampleRenderTarget) { if (isWebGL2) { const width = renderTarget.width; const height = renderTarget.height; let mask = 16384; if (renderTarget.depthBuffer) mask |= 256; if (renderTarget.stencilBuffer) mask |= 1024; const renderTargetProperties = properties.get(renderTarget); state.bindFramebuffer(36008, renderTargetProperties.__webglMultisampledFramebuffer); state.bindFramebuffer(36009, renderTargetProperties.__webglFramebuffer); _gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, 9728); state.bindFramebuffer(36008, null); state.bindFramebuffer(36009, renderTargetProperties.__webglMultisampledFramebuffer); } else { console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2."); } } } function getRenderTargetSamples(renderTarget) { return isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ? Math.min(maxSamples, renderTarget.samples) : 0; } function updateVideoTexture(texture) { const frame = info.render.frame; if (_videoTextures.get(texture) !== frame) { _videoTextures.set(texture, frame); texture.update(); } } let warnedTexture2D = false; let warnedTextureCube = false; function safeSetTexture2D(texture, slot) { if (texture && texture.isWebGLRenderTarget) { if (warnedTexture2D === false) { console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."); warnedTexture2D = true; } texture = texture.texture; } setTexture2D(texture, slot); } function safeSetTextureCube(texture, slot) { if (texture && texture.isWebGLCubeRenderTarget) { if (warnedTextureCube === false) { console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."); warnedTextureCube = true; } texture = texture.texture; } setTextureCube(texture, slot); } this.allocateTextureUnit = allocateTextureUnit; this.resetTextureUnits = resetTextureUnits; this.setTexture2D = setTexture2D; this.setTexture2DArray = setTexture2DArray; this.setTexture3D = setTexture3D; this.setTextureCube = setTextureCube; this.setupRenderTarget = setupRenderTarget; this.updateRenderTargetMipmap = updateRenderTargetMipmap; this.updateMultisampleRenderTarget = updateMultisampleRenderTarget; this.safeSetTexture2D = safeSetTexture2D; this.safeSetTextureCube = safeSetTextureCube; } function WebGLUtils(gl, extensions, capabilities) { const isWebGL2 = capabilities.isWebGL2; function convert(p2) { let extension; if (p2 === UnsignedByteType) return 5121; if (p2 === UnsignedShort4444Type) return 32819; if (p2 === UnsignedShort5551Type) return 32820; if (p2 === UnsignedShort565Type) return 33635; if (p2 === ByteType) return 5120; if (p2 === ShortType) return 5122; if (p2 === UnsignedShortType) return 5123; if (p2 === IntType) return 5124; if (p2 === UnsignedIntType) return 5125; if (p2 === FloatType) return 5126; if (p2 === HalfFloatType) { if (isWebGL2) return 5131; extension = extensions.get("OES_texture_half_float"); if (extension !== null) { return extension.HALF_FLOAT_OES; } else { return null; } } if (p2 === AlphaFormat) return 6406; if (p2 === RGBFormat) return 6407; if (p2 === RGBAFormat) return 6408; if (p2 === LuminanceFormat) return 6409; if (p2 === LuminanceAlphaFormat) return 6410; if (p2 === DepthFormat) return 6402; if (p2 === DepthStencilFormat) return 34041; if (p2 === RedFormat) return 6403; if (p2 === RedIntegerFormat) return 36244; if (p2 === RGFormat) return 33319; if (p2 === RGIntegerFormat) return 33320; if (p2 === RGBIntegerFormat) return 36248; if (p2 === RGBAIntegerFormat) return 36249; if (p2 === RGB_S3TC_DXT1_Format || p2 === RGBA_S3TC_DXT1_Format || p2 === RGBA_S3TC_DXT3_Format || p2 === RGBA_S3TC_DXT5_Format) { extension = extensions.get("WEBGL_compressed_texture_s3tc"); if (extension !== null) { if (p2 === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; if (p2 === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; if (p2 === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; if (p2 === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; } else { return null; } } if (p2 === RGB_PVRTC_4BPPV1_Format || p2 === RGB_PVRTC_2BPPV1_Format || p2 === RGBA_PVRTC_4BPPV1_Format || p2 === RGBA_PVRTC_2BPPV1_Format) { extension = extensions.get("WEBGL_compressed_texture_pvrtc"); if (extension !== null) { if (p2 === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; if (p2 === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; if (p2 === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; if (p2 === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; } else { return null; } } if (p2 === RGB_ETC1_Format) { extension = extensions.get("WEBGL_compressed_texture_etc1"); if (extension !== null) { return extension.COMPRESSED_RGB_ETC1_WEBGL; } else { return null; } } if (p2 === RGB_ETC2_Format || p2 === RGBA_ETC2_EAC_Format) { extension = extensions.get("WEBGL_compressed_texture_etc"); if (extension !== null) { if (p2 === RGB_ETC2_Format) return extension.COMPRESSED_RGB8_ETC2; if (p2 === RGBA_ETC2_EAC_Format) return extension.COMPRESSED_RGBA8_ETC2_EAC; } } if (p2 === RGBA_ASTC_4x4_Format || p2 === RGBA_ASTC_5x4_Format || p2 === RGBA_ASTC_5x5_Format || p2 === RGBA_ASTC_6x5_Format || p2 === RGBA_ASTC_6x6_Format || p2 === RGBA_ASTC_8x5_Format || p2 === RGBA_ASTC_8x6_Format || p2 === RGBA_ASTC_8x8_Format || p2 === RGBA_ASTC_10x5_Format || p2 === RGBA_ASTC_10x6_Format || p2 === RGBA_ASTC_10x8_Format || p2 === RGBA_ASTC_10x10_Format || p2 === RGBA_ASTC_12x10_Format || p2 === RGBA_ASTC_12x12_Format || p2 === SRGB8_ALPHA8_ASTC_4x4_Format || p2 === SRGB8_ALPHA8_ASTC_5x4_Format || p2 === SRGB8_ALPHA8_ASTC_5x5_Format || p2 === SRGB8_ALPHA8_ASTC_6x5_Format || p2 === SRGB8_ALPHA8_ASTC_6x6_Format || p2 === SRGB8_ALPHA8_ASTC_8x5_Format || p2 === SRGB8_ALPHA8_ASTC_8x6_Format || p2 === SRGB8_ALPHA8_ASTC_8x8_Format || p2 === SRGB8_ALPHA8_ASTC_10x5_Format || p2 === SRGB8_ALPHA8_ASTC_10x6_Format || p2 === SRGB8_ALPHA8_ASTC_10x8_Format || p2 === SRGB8_ALPHA8_ASTC_10x10_Format || p2 === SRGB8_ALPHA8_ASTC_12x10_Format || p2 === SRGB8_ALPHA8_ASTC_12x12_Format) { extension = extensions.get("WEBGL_compressed_texture_astc"); if (extension !== null) { return p2; } else { return null; } } if (p2 === RGBA_BPTC_Format) { extension = extensions.get("EXT_texture_compression_bptc"); if (extension !== null) { return p2; } else { return null; } } if (p2 === UnsignedInt248Type) { if (isWebGL2) return 34042; extension = extensions.get("WEBGL_depth_texture"); if (extension !== null) { return extension.UNSIGNED_INT_24_8_WEBGL; } else { return null; } } } return { convert }; } var ArrayCamera = class extends PerspectiveCamera { constructor(array = []) { super(); this.cameras = array; } }; ArrayCamera.prototype.isArrayCamera = true; var Group = class extends Object3D { constructor() { super(); this.type = "Group"; } }; Group.prototype.isGroup = true; var _moveEvent = { type: "move" }; var WebXRController = class { constructor() { this._targetRay = null; this._grip = null; this._hand = null; } getHandSpace() { if (this._hand === null) { this._hand = new Group(); this._hand.matrixAutoUpdate = false; this._hand.visible = false; this._hand.joints = {}; this._hand.inputState = { pinching: false }; } return this._hand; } getTargetRaySpace() { if (this._targetRay === null) { this._targetRay = new Group(); this._targetRay.matrixAutoUpdate = false; this._targetRay.visible = false; this._targetRay.hasLinearVelocity = false; this._targetRay.linearVelocity = new Vector3(); this._targetRay.hasAngularVelocity = false; this._targetRay.angularVelocity = new Vector3(); } return this._targetRay; } getGripSpace() { if (this._grip === null) { this._grip = new Group(); this._grip.matrixAutoUpdate = false; this._grip.visible = false; this._grip.hasLinearVelocity = false; this._grip.linearVelocity = new Vector3(); this._grip.hasAngularVelocity = false; this._grip.angularVelocity = new Vector3(); } return this._grip; } dispatchEvent(event) { if (this._targetRay !== null) { this._targetRay.dispatchEvent(event); } if (this._grip !== null) { this._grip.dispatchEvent(event); } if (this._hand !== null) { this._hand.dispatchEvent(event); } return this; } disconnect(inputSource) { this.dispatchEvent({ type: "disconnected", data: inputSource }); if (this._targetRay !== null) { this._targetRay.visible = false; } if (this._grip !== null) { this._grip.visible = false; } if (this._hand !== null) { this._hand.visible = false; } return this; } update(inputSource, frame, referenceSpace) { let inputPose = null; let gripPose = null; let handPose = null; const targetRay = this._targetRay; const grip = this._grip; const hand = this._hand; if (inputSource && frame.session.visibilityState !== "visible-blurred") { if (targetRay !== null) { inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); if (inputPose !== null) { targetRay.matrix.fromArray(inputPose.transform.matrix); targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale); if (inputPose.linearVelocity) { targetRay.hasLinearVelocity = true; targetRay.linearVelocity.copy(inputPose.linearVelocity); } else { targetRay.hasLinearVelocity = false; } if (inputPose.angularVelocity) { targetRay.hasAngularVelocity = true; targetRay.angularVelocity.copy(inputPose.angularVelocity); } else { targetRay.hasAngularVelocity = false; } this.dispatchEvent(_moveEvent); } } if (hand && inputSource.hand) { handPose = true; for (const inputjoint of inputSource.hand.values()) { const jointPose = frame.getJointPose(inputjoint, referenceSpace); if (hand.joints[inputjoint.jointName] === void 0) { const joint2 = new Group(); joint2.matrixAutoUpdate = false; joint2.visible = false; hand.joints[inputjoint.jointName] = joint2; hand.add(joint2); } const joint = hand.joints[inputjoint.jointName]; if (jointPose !== null) { joint.matrix.fromArray(jointPose.transform.matrix); joint.matrix.decompose(joint.position, joint.rotation, joint.scale); joint.jointRadius = jointPose.radius; } joint.visible = jointPose !== null; } const indexTip = hand.joints["index-finger-tip"]; const thumbTip = hand.joints["thumb-tip"]; const distance = indexTip.position.distanceTo(thumbTip.position); const distanceToPinch = 0.02; const threshold = 5e-3; if (hand.inputState.pinching && distance > distanceToPinch + threshold) { hand.inputState.pinching = false; this.dispatchEvent({ type: "pinchend", handedness: inputSource.handedness, target: this }); } else if (!hand.inputState.pinching && distance <= distanceToPinch - threshold) { hand.inputState.pinching = true; this.dispatchEvent({ type: "pinchstart", handedness: inputSource.handedness, target: this }); } } else { if (grip !== null && inputSource.gripSpace) { gripPose = frame.getPose(inputSource.gripSpace, referenceSpace); if (gripPose !== null) { grip.matrix.fromArray(gripPose.transform.matrix); grip.matrix.decompose(grip.position, grip.rotation, grip.scale); if (gripPose.linearVelocity) { grip.hasLinearVelocity = true; grip.linearVelocity.copy(gripPose.linearVelocity); } else { grip.hasLinearVelocity = false; } if (gripPose.angularVelocity) { grip.hasAngularVelocity = true; grip.angularVelocity.copy(gripPose.angularVelocity); } else { grip.hasAngularVelocity = false; } } } } } if (targetRay !== null) { targetRay.visible = inputPose !== null; } if (grip !== null) { grip.visible = gripPose !== null; } if (hand !== null) { hand.visible = handPose !== null; } return this; } }; var WebXRManager = class extends EventDispatcher { constructor(renderer, gl) { super(); const scope = this; const state = renderer.state; let session = null; let framebufferScaleFactor = 1; let referenceSpace = null; let referenceSpaceType = "local-floor"; let pose = null; let glBinding = null; let glFramebuffer = null; let glProjLayer = null; let glBaseLayer = null; let isMultisample = false; let glMultisampledFramebuffer = null; let glColorRenderbuffer = null; let glDepthRenderbuffer = null; let xrFrame = null; let depthStyle = null; let clearStyle = null; const controllers = []; const inputSourcesMap = /* @__PURE__ */ new Map(); const cameraL = new PerspectiveCamera(); cameraL.layers.enable(1); cameraL.viewport = new Vector4(); const cameraR = new PerspectiveCamera(); cameraR.layers.enable(2); cameraR.viewport = new Vector4(); const cameras = [cameraL, cameraR]; const cameraVR = new ArrayCamera(); cameraVR.layers.enable(1); cameraVR.layers.enable(2); let _currentDepthNear = null; let _currentDepthFar = null; this.cameraAutoUpdate = true; this.enabled = false; this.isPresenting = false; this.getController = function(index) { let controller = controllers[index]; if (controller === void 0) { controller = new WebXRController(); controllers[index] = controller; } return controller.getTargetRaySpace(); }; this.getControllerGrip = function(index) { let controller = controllers[index]; if (controller === void 0) { controller = new WebXRController(); controllers[index] = controller; } return controller.getGripSpace(); }; this.getHand = function(index) { let controller = controllers[index]; if (controller === void 0) { controller = new WebXRController(); controllers[index] = controller; } return controller.getHandSpace(); }; function onSessionEvent(event) { const controller = inputSourcesMap.get(event.inputSource); if (controller) { controller.dispatchEvent({ type: event.type, data: event.inputSource }); } } function onSessionEnd() { inputSourcesMap.forEach(function(controller, inputSource) { controller.disconnect(inputSource); }); inputSourcesMap.clear(); _currentDepthNear = null; _currentDepthFar = null; state.bindXRFramebuffer(null); renderer.setRenderTarget(renderer.getRenderTarget()); if (glFramebuffer) gl.deleteFramebuffer(glFramebuffer); if (glMultisampledFramebuffer) gl.deleteFramebuffer(glMultisampledFramebuffer); if (glColorRenderbuffer) gl.deleteRenderbuffer(glColorRenderbuffer); if (glDepthRenderbuffer) gl.deleteRenderbuffer(glDepthRenderbuffer); glFramebuffer = null; glMultisampledFramebuffer = null; glColorRenderbuffer = null; glDepthRenderbuffer = null; glBaseLayer = null; glProjLayer = null; glBinding = null; session = null; animation.stop(); scope.isPresenting = false; scope.dispatchEvent({ type: "sessionend" }); } this.setFramebufferScaleFactor = function(value) { framebufferScaleFactor = value; if (scope.isPresenting === true) { console.warn("THREE.WebXRManager: Cannot change framebuffer scale while presenting."); } }; this.setReferenceSpaceType = function(value) { referenceSpaceType = value; if (scope.isPresenting === true) { console.warn("THREE.WebXRManager: Cannot change reference space type while presenting."); } }; this.getReferenceSpace = function() { return referenceSpace; }; this.getBaseLayer = function() { return glProjLayer !== null ? glProjLayer : glBaseLayer; }; this.getBinding = function() { return glBinding; }; this.getFrame = function() { return xrFrame; }; this.getSession = function() { return session; }; this.setSession = function(value) { return __async(this, null, function* () { session = value; if (session !== null) { session.addEventListener("select", onSessionEvent); session.addEventListener("selectstart", onSessionEvent); session.addEventListener("selectend", onSessionEvent); session.addEventListener("squeeze", onSessionEvent); session.addEventListener("squeezestart", onSessionEvent); session.addEventListener("squeezeend", onSessionEvent); session.addEventListener("end", onSessionEnd); session.addEventListener("inputsourceschange", onInputSourcesChange); const attributes = gl.getContextAttributes(); if (attributes.xrCompatible !== true) { yield gl.makeXRCompatible(); } if (session.renderState.layers === void 0) { const layerInit = { antialias: attributes.antialias, alpha: attributes.alpha, depth: attributes.depth, stencil: attributes.stencil, framebufferScaleFactor }; glBaseLayer = new XRWebGLLayer(session, gl, layerInit); session.updateRenderState({ baseLayer: glBaseLayer }); } else if (gl instanceof WebGLRenderingContext) { const layerInit = { antialias: true, alpha: attributes.alpha, depth: attributes.depth, stencil: attributes.stencil, framebufferScaleFactor }; glBaseLayer = new XRWebGLLayer(session, gl, layerInit); session.updateRenderState({ layers: [glBaseLayer] }); } else { isMultisample = attributes.antialias; let depthFormat = null; if (attributes.depth) { clearStyle = 256; if (attributes.stencil) clearStyle |= 1024; depthStyle = attributes.stencil ? 33306 : 36096; depthFormat = attributes.stencil ? 35056 : 33190; } const projectionlayerInit = { colorFormat: attributes.alpha ? 32856 : 32849, depthFormat, scaleFactor: framebufferScaleFactor }; glBinding = new XRWebGLBinding(session, gl); glProjLayer = glBinding.createProjectionLayer(projectionlayerInit); glFramebuffer = gl.createFramebuffer(); session.updateRenderState({ layers: [glProjLayer] }); if (isMultisample) { glMultisampledFramebuffer = gl.createFramebuffer(); glColorRenderbuffer = gl.createRenderbuffer(); gl.bindRenderbuffer(36161, glColorRenderbuffer); gl.renderbufferStorageMultisample(36161, 4, 32856, glProjLayer.textureWidth, glProjLayer.textureHeight); state.bindFramebuffer(36160, glMultisampledFramebuffer); gl.framebufferRenderbuffer(36160, 36064, 36161, glColorRenderbuffer); gl.bindRenderbuffer(36161, null); if (depthFormat !== null) { glDepthRenderbuffer = gl.createRenderbuffer(); gl.bindRenderbuffer(36161, glDepthRenderbuffer); gl.renderbufferStorageMultisample(36161, 4, depthFormat, glProjLayer.textureWidth, glProjLayer.textureHeight); gl.framebufferRenderbuffer(36160, depthStyle, 36161, glDepthRenderbuffer); gl.bindRenderbuffer(36161, null); } state.bindFramebuffer(36160, null); } } referenceSpace = yield session.requestReferenceSpace(referenceSpaceType); animation.setContext(session); animation.start(); scope.isPresenting = true; scope.dispatchEvent({ type: "sessionstart" }); } }); }; function onInputSourcesChange(event) { const inputSources = session.inputSources; for (let i = 0; i < controllers.length; i++) { inputSourcesMap.set(inputSources[i], controllers[i]); } for (let i = 0; i < event.removed.length; i++) { const inputSource = event.removed[i]; const controller = inputSourcesMap.get(inputSource); if (controller) { controller.dispatchEvent({ type: "disconnected", data: inputSource }); inputSourcesMap.delete(inputSource); } } for (let i = 0; i < event.added.length; i++) { const inputSource = event.added[i]; const controller = inputSourcesMap.get(inputSource); if (controller) { controller.dispatchEvent({ type: "connected", data: inputSource }); } } } const cameraLPos = new Vector3(); const cameraRPos = new Vector3(); function setProjectionFromUnion(camera, cameraL2, cameraR2) { cameraLPos.setFromMatrixPosition(cameraL2.matrixWorld); cameraRPos.setFromMatrixPosition(cameraR2.matrixWorld); const ipd = cameraLPos.distanceTo(cameraRPos); const projL = cameraL2.projectionMatrix.elements; const projR = cameraR2.projectionMatrix.elements; const near = projL[14] / (projL[10] - 1); const far = projL[14] / (projL[10] + 1); const topFov = (projL[9] + 1) / projL[5]; const bottomFov = (projL[9] - 1) / projL[5]; const leftFov = (projL[8] - 1) / projL[0]; const rightFov = (projR[8] + 1) / projR[0]; const left = near * leftFov; const right = near * rightFov; const zOffset = ipd / (-leftFov + rightFov); const xOffset = zOffset * -leftFov; cameraL2.matrixWorld.decompose(camera.position, camera.quaternion, camera.scale); camera.translateX(xOffset); camera.translateZ(zOffset); camera.matrixWorld.compose(camera.position, camera.quaternion, camera.scale); camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); const near2 = near + zOffset; const far2 = far + zOffset; const left2 = left - xOffset; const right2 = right + (ipd - xOffset); const top2 = topFov * far / far2 * near2; const bottom2 = bottomFov * far / far2 * near2; camera.projectionMatrix.makePerspective(left2, right2, top2, bottom2, near2, far2); } function updateCamera(camera, parent) { if (parent === null) { camera.matrixWorld.copy(camera.matrix); } else { camera.matrixWorld.multiplyMatrices(parent.matrixWorld, camera.matrix); } camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); } this.updateCamera = function(camera) { if (session === null) return; cameraVR.near = cameraR.near = cameraL.near = camera.near; cameraVR.far = cameraR.far = cameraL.far = camera.far; if (_currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far) { session.updateRenderState({ depthNear: cameraVR.near, depthFar: cameraVR.far }); _currentDepthNear = cameraVR.near; _currentDepthFar = cameraVR.far; } const parent = camera.parent; const cameras2 = cameraVR.cameras; updateCamera(cameraVR, parent); for (let i = 0; i < cameras2.length; i++) { updateCamera(cameras2[i], parent); } cameraVR.matrixWorld.decompose(cameraVR.position, cameraVR.quaternion, cameraVR.scale); camera.position.copy(cameraVR.position); camera.quaternion.copy(cameraVR.quaternion); camera.scale.copy(cameraVR.scale); camera.matrix.copy(cameraVR.matrix); camera.matrixWorld.copy(cameraVR.matrixWorld); const children = camera.children; for (let i = 0, l = children.length; i < l; i++) { children[i].updateMatrixWorld(true); } if (cameras2.length === 2) { setProjectionFromUnion(cameraVR, cameraL, cameraR); } else { cameraVR.projectionMatrix.copy(cameraL.projectionMatrix); } }; this.getCamera = function() { return cameraVR; }; this.getFoveation = function() { if (glProjLayer !== null) { return glProjLayer.fixedFoveation; } if (glBaseLayer !== null) { return glBaseLayer.fixedFoveation; } return void 0; }; this.setFoveation = function(foveation) { if (glProjLayer !== null) { glProjLayer.fixedFoveation = foveation; } if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== void 0) { glBaseLayer.fixedFoveation = foveation; } }; let onAnimationFrameCallback = null; function onAnimationFrame(time, frame) { pose = frame.getViewerPose(referenceSpace); xrFrame = frame; if (pose !== null) { const views = pose.views; if (glBaseLayer !== null) { state.bindXRFramebuffer(glBaseLayer.framebuffer); } let cameraVRNeedsUpdate = false; if (views.length !== cameraVR.cameras.length) { cameraVR.cameras.length = 0; cameraVRNeedsUpdate = true; } for (let i = 0; i < views.length; i++) { const view = views[i]; let viewport = null; if (glBaseLayer !== null) { viewport = glBaseLayer.getViewport(view); } else { const glSubImage = glBinding.getViewSubImage(glProjLayer, view); state.bindXRFramebuffer(glFramebuffer); if (glSubImage.depthStencilTexture !== void 0) { gl.framebufferTexture2D(36160, depthStyle, 3553, glSubImage.depthStencilTexture, 0); } gl.framebufferTexture2D(36160, 36064, 3553, glSubImage.colorTexture, 0); viewport = glSubImage.viewport; } const camera = cameras[i]; camera.matrix.fromArray(view.transform.matrix); camera.projectionMatrix.fromArray(view.projectionMatrix); camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height); if (i === 0) { cameraVR.matrix.copy(camera.matrix); } if (cameraVRNeedsUpdate === true) { cameraVR.cameras.push(camera); } } if (isMultisample) { state.bindXRFramebuffer(glMultisampledFramebuffer); if (clearStyle !== null) gl.clear(clearStyle); } } const inputSources = session.inputSources; for (let i = 0; i < controllers.length; i++) { const controller = controllers[i]; const inputSource = inputSources[i]; controller.update(inputSource, frame, referenceSpace); } if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame); if (isMultisample) { const width = glProjLayer.textureWidth; const height = glProjLayer.textureHeight; state.bindFramebuffer(36008, glMultisampledFramebuffer); state.bindFramebuffer(36009, glFramebuffer); gl.invalidateFramebuffer(36008, [depthStyle]); gl.invalidateFramebuffer(36009, [depthStyle]); gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, 16384, 9728); gl.invalidateFramebuffer(36008, [36064]); state.bindFramebuffer(36008, null); state.bindFramebuffer(36009, null); state.bindFramebuffer(36160, glMultisampledFramebuffer); } xrFrame = null; } const animation = new WebGLAnimation(); animation.setAnimationLoop(onAnimationFrame); this.setAnimationLoop = function(callback) { onAnimationFrameCallback = callback; }; this.dispose = function() { }; } }; function WebGLMaterials(properties) { function refreshFogUniforms(uniforms, fog) { uniforms.fogColor.value.copy(fog.color); if (fog.isFog) { uniforms.fogNear.value = fog.near; uniforms.fogFar.value = fog.far; } else if (fog.isFogExp2) { uniforms.fogDensity.value = fog.density; } } function refreshMaterialUniforms(uniforms, material, pixelRatio, height, transmissionRenderTarget) { if (material.isMeshBasicMaterial) { refreshUniformsCommon(uniforms, material); } else if (material.isMeshLambertMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsLambert(uniforms, material); } else if (material.isMeshToonMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsToon(uniforms, material); } else if (material.isMeshPhongMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsPhong(uniforms, material); } else if (material.isMeshStandardMaterial) { refreshUniformsCommon(uniforms, material); if (material.isMeshPhysicalMaterial) { refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); } else { refreshUniformsStandard(uniforms, material); } } else if (material.isMeshMatcapMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsMatcap(uniforms, material); } else if (material.isMeshDepthMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsDepth(uniforms, material); } else if (material.isMeshDistanceMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsDistance(uniforms, material); } else if (material.isMeshNormalMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsNormal(uniforms, material); } else if (material.isLineBasicMaterial) { refreshUniformsLine(uniforms, material); if (material.isLineDashedMaterial) { refreshUniformsDash(uniforms, material); } } else if (material.isPointsMaterial) { refreshUniformsPoints(uniforms, material, pixelRatio, height); } else if (material.isSpriteMaterial) { refreshUniformsSprites(uniforms, material); } else if (material.isShadowMaterial) { uniforms.color.value.copy(material.color); uniforms.opacity.value = material.opacity; } else if (material.isShaderMaterial) { material.uniformsNeedUpdate = false; } } function refreshUniformsCommon(uniforms, material) { uniforms.opacity.value = material.opacity; if (material.color) { uniforms.diffuse.value.copy(material.color); } if (material.emissive) { uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity); } if (material.map) { uniforms.map.value = material.map; } if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; } if (material.specularMap) { uniforms.specularMap.value = material.specularMap; } if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; } const envMap = properties.get(material).envMap; if (envMap) { uniforms.envMap.value = envMap; uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1; uniforms.reflectivity.value = material.reflectivity; uniforms.ior.value = material.ior; uniforms.refractionRatio.value = material.refractionRatio; const maxMipLevel = properties.get(envMap).__maxMipLevel; if (maxMipLevel !== void 0) { uniforms.maxMipLevel.value = maxMipLevel; } } if (material.lightMap) { uniforms.lightMap.value = material.lightMap; uniforms.lightMapIntensity.value = material.lightMapIntensity; } if (material.aoMap) { uniforms.aoMap.value = material.aoMap; uniforms.aoMapIntensity.value = material.aoMapIntensity; } let uvScaleMap; if (material.map) { uvScaleMap = material.map; } else if (material.specularMap) { uvScaleMap = material.specularMap; } else if (material.displacementMap) { uvScaleMap = material.displacementMap; } else if (material.normalMap) { uvScaleMap = material.normalMap; } else if (material.bumpMap) { uvScaleMap = material.bumpMap; } else if (material.roughnessMap) { uvScaleMap = material.roughnessMap; } else if (material.metalnessMap) { uvScaleMap = material.metalnessMap; } else if (material.alphaMap) { uvScaleMap = material.alphaMap; } else if (material.emissiveMap) { uvScaleMap = material.emissiveMap; } else if (material.clearcoatMap) { uvScaleMap = material.clearcoatMap; } else if (material.clearcoatNormalMap) { uvScaleMap = material.clearcoatNormalMap; } else if (material.clearcoatRoughnessMap) { uvScaleMap = material.clearcoatRoughnessMap; } else if (material.specularIntensityMap) { uvScaleMap = material.specularIntensityMap; } else if (material.specularTintMap) { uvScaleMap = material.specularTintMap; } else if (material.transmissionMap) { uvScaleMap = material.transmissionMap; } else if (material.thicknessMap) { uvScaleMap = material.thicknessMap; } if (uvScaleMap !== void 0) { if (uvScaleMap.isWebGLRenderTarget) { uvScaleMap = uvScaleMap.texture; } if (uvScaleMap.matrixAutoUpdate === true) { uvScaleMap.updateMatrix(); } uniforms.uvTransform.value.copy(uvScaleMap.matrix); } let uv2ScaleMap; if (material.aoMap) { uv2ScaleMap = material.aoMap; } else if (material.lightMap) { uv2ScaleMap = material.lightMap; } if (uv2ScaleMap !== void 0) { if (uv2ScaleMap.isWebGLRenderTarget) { uv2ScaleMap = uv2ScaleMap.texture; } if (uv2ScaleMap.matrixAutoUpdate === true) { uv2ScaleMap.updateMatrix(); } uniforms.uv2Transform.value.copy(uv2ScaleMap.matrix); } } function refreshUniformsLine(uniforms, material) { uniforms.diffuse.value.copy(material.color); uniforms.opacity.value = material.opacity; } function refreshUniformsDash(uniforms, material) { uniforms.dashSize.value = material.dashSize; uniforms.totalSize.value = material.dashSize + material.gapSize; uniforms.scale.value = material.scale; } function refreshUniformsPoints(uniforms, material, pixelRatio, height) { uniforms.diffuse.value.copy(material.color); uniforms.opacity.value = material.opacity; uniforms.size.value = material.size * pixelRatio; uniforms.scale.value = height * 0.5; if (material.map) { uniforms.map.value = material.map; } if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; } if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; } let uvScaleMap; if (material.map) { uvScaleMap = material.map; } else if (material.alphaMap) { uvScaleMap = material.alphaMap; } if (uvScaleMap !== void 0) { if (uvScaleMap.matrixAutoUpdate === true) { uvScaleMap.updateMatrix(); } uniforms.uvTransform.value.copy(uvScaleMap.matrix); } } function refreshUniformsSprites(uniforms, material) { uniforms.diffuse.value.copy(material.color); uniforms.opacity.value = material.opacity; uniforms.rotation.value = material.rotation; if (material.map) { uniforms.map.value = material.map; } if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; } if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; } let uvScaleMap; if (material.map) { uvScaleMap = material.map; } else if (material.alphaMap) { uvScaleMap = material.alphaMap; } if (uvScaleMap !== void 0) { if (uvScaleMap.matrixAutoUpdate === true) { uvScaleMap.updateMatrix(); } uniforms.uvTransform.value.copy(uvScaleMap.matrix); } } function refreshUniformsLambert(uniforms, material) { if (material.emissiveMap) { uniforms.emissiveMap.value = material.emissiveMap; } } function refreshUniformsPhong(uniforms, material) { uniforms.specular.value.copy(material.specular); uniforms.shininess.value = Math.max(material.shininess, 1e-4); if (material.emissiveMap) { uniforms.emissiveMap.value = material.emissiveMap; } if (material.bumpMap) { uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; if (material.side === BackSide) uniforms.bumpScale.value *= -1; } if (material.normalMap) { uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy(material.normalScale); if (material.side === BackSide) uniforms.normalScale.value.negate(); } if (material.displacementMap) { uniforms.displacementMap.value = material.displacementMap; uniforms.displacementScale.value = material.displacementScale; uniforms.displacementBias.value = material.displacementBias; } } function refreshUniformsToon(uniforms, material) { if (material.gradientMap) { uniforms.gradientMap.value = material.gradientMap; } if (material.emissiveMap) { uniforms.emissiveMap.value = material.emissiveMap; } if (material.bumpMap) { uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; if (material.side === BackSide) uniforms.bumpScale.value *= -1; } if (material.normalMap) { uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy(material.normalScale); if (material.side === BackSide) uniforms.normalScale.value.negate(); } if (material.displacementMap) { uniforms.displacementMap.value = material.displacementMap; uniforms.displacementScale.value = material.displacementScale; uniforms.displacementBias.value = material.displacementBias; } } function refreshUniformsStandard(uniforms, material) { uniforms.roughness.value = material.roughness; uniforms.metalness.value = material.metalness; if (material.roughnessMap) { uniforms.roughnessMap.value = material.roughnessMap; } if (material.metalnessMap) { uniforms.metalnessMap.value = material.metalnessMap; } if (material.emissiveMap) { uniforms.emissiveMap.value = material.emissiveMap; } if (material.bumpMap) { uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; if (material.side === BackSide) uniforms.bumpScale.value *= -1; } if (material.normalMap) { uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy(material.normalScale); if (material.side === BackSide) uniforms.normalScale.value.negate(); } if (material.displacementMap) { uniforms.displacementMap.value = material.displacementMap; uniforms.displacementScale.value = material.displacementScale; uniforms.displacementBias.value = material.displacementBias; } const envMap = properties.get(material).envMap; if (envMap) { uniforms.envMapIntensity.value = material.envMapIntensity; } } function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) { refreshUniformsStandard(uniforms, material); uniforms.ior.value = material.ior; if (material.sheenTint) uniforms.sheenTint.value.copy(material.sheenTint); if (material.clearcoat > 0) { uniforms.clearcoat.value = material.clearcoat; uniforms.clearcoatRoughness.value = material.clearcoatRoughness; if (material.clearcoatMap) { uniforms.clearcoatMap.value = material.clearcoatMap; } if (material.clearcoatRoughnessMap) { uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; } if (material.clearcoatNormalMap) { uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale); uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; if (material.side === BackSide) { uniforms.clearcoatNormalScale.value.negate(); } } } if (material.transmission > 0) { uniforms.transmission.value = material.transmission; uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture; uniforms.transmissionSamplerSize.value.set(transmissionRenderTarget.width, transmissionRenderTarget.height); if (material.transmissionMap) { uniforms.transmissionMap.value = material.transmissionMap; } uniforms.thickness.value = material.thickness; if (material.thicknessMap) { uniforms.thicknessMap.value = material.thicknessMap; } uniforms.attenuationDistance.value = material.attenuationDistance; uniforms.attenuationTint.value.copy(material.attenuationTint); } uniforms.specularIntensity.value = material.specularIntensity; uniforms.specularTint.value.copy(material.specularTint); if (material.specularIntensityMap) { uniforms.specularIntensityMap.value = material.specularIntensityMap; } if (material.specularTintMap) { uniforms.specularTintMap.value = material.specularTintMap; } } function refreshUniformsMatcap(uniforms, material) { if (material.matcap) { uniforms.matcap.value = material.matcap; } if (material.bumpMap) { uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; if (material.side === BackSide) uniforms.bumpScale.value *= -1; } if (material.normalMap) { uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy(material.normalScale); if (material.side === BackSide) uniforms.normalScale.value.negate(); } if (material.displacementMap) { uniforms.displacementMap.value = material.displacementMap; uniforms.displacementScale.value = material.displacementScale; uniforms.displacementBias.value = material.displacementBias; } } function refreshUniformsDepth(uniforms, material) { if (material.displacementMap) { uniforms.displacementMap.value = material.displacementMap; uniforms.displacementScale.value = material.displacementScale; uniforms.displacementBias.value = material.displacementBias; } } function refreshUniformsDistance(uniforms, material) { if (material.displacementMap) { uniforms.displacementMap.value = material.displacementMap; uniforms.displacementScale.value = material.displacementScale; uniforms.displacementBias.value = material.displacementBias; } uniforms.referencePosition.value.copy(material.referencePosition); uniforms.nearDistance.value = material.nearDistance; uniforms.farDistance.value = material.farDistance; } function refreshUniformsNormal(uniforms, material) { if (material.bumpMap) { uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; if (material.side === BackSide) uniforms.bumpScale.value *= -1; } if (material.normalMap) { uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy(material.normalScale); if (material.side === BackSide) uniforms.normalScale.value.negate(); } if (material.displacementMap) { uniforms.displacementMap.value = material.displacementMap; uniforms.displacementScale.value = material.displacementScale; uniforms.displacementBias.value = material.displacementBias; } } return { refreshFogUniforms, refreshMaterialUniforms }; } function createCanvasElement() { const canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); canvas.style.display = "block"; return canvas; } function WebGLRenderer(parameters = {}) { const _canvas2 = parameters.canvas !== void 0 ? parameters.canvas : createCanvasElement(), _context2 = parameters.context !== void 0 ? parameters.context : null, _alpha = parameters.alpha !== void 0 ? parameters.alpha : false, _depth = parameters.depth !== void 0 ? parameters.depth : true, _stencil = parameters.stencil !== void 0 ? parameters.stencil : true, _antialias = parameters.antialias !== void 0 ? parameters.antialias : false, _premultipliedAlpha = parameters.premultipliedAlpha !== void 0 ? parameters.premultipliedAlpha : true, _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== void 0 ? parameters.preserveDrawingBuffer : false, _powerPreference = parameters.powerPreference !== void 0 ? parameters.powerPreference : "default", _failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== void 0 ? parameters.failIfMajorPerformanceCaveat : false; let currentRenderList = null; let currentRenderState = null; const renderListStack = []; const renderStateStack = []; this.domElement = _canvas2; this.debug = { checkShaderErrors: true }; this.autoClear = true; this.autoClearColor = true; this.autoClearDepth = true; this.autoClearStencil = true; this.sortObjects = true; this.clippingPlanes = []; this.localClippingEnabled = false; this.gammaFactor = 2; this.outputEncoding = LinearEncoding; this.physicallyCorrectLights = false; this.toneMapping = NoToneMapping; this.toneMappingExposure = 1; const _this = this; let _isContextLost = false; let _currentActiveCubeFace = 0; let _currentActiveMipmapLevel = 0; let _currentRenderTarget = null; let _currentMaterialId = -1; let _currentCamera = null; const _currentViewport = new Vector4(); const _currentScissor = new Vector4(); let _currentScissorTest = null; let _width = _canvas2.width; let _height = _canvas2.height; let _pixelRatio = 1; let _opaqueSort = null; let _transparentSort = null; const _viewport = new Vector4(0, 0, _width, _height); const _scissor = new Vector4(0, 0, _width, _height); let _scissorTest = false; const _currentDrawBuffers = []; const _frustum = new Frustum(); let _clippingEnabled = false; let _localClippingEnabled = false; let _transmissionRenderTarget = null; const _projScreenMatrix2 = new Matrix4(); const _vector3 = new Vector3(); const _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true }; function getTargetPixelRatio() { return _currentRenderTarget === null ? _pixelRatio : 1; } let _gl = _context2; function getContext(contextNames, contextAttributes) { for (let i = 0; i < contextNames.length; i++) { const contextName = contextNames[i]; const context = _canvas2.getContext(contextName, contextAttributes); if (context !== null) return context; } return null; } try { const contextAttributes = { alpha: _alpha, depth: _depth, stencil: _stencil, antialias: _antialias, premultipliedAlpha: _premultipliedAlpha, preserveDrawingBuffer: _preserveDrawingBuffer, powerPreference: _powerPreference, failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat }; _canvas2.addEventListener("webglcontextlost", onContextLost, false); _canvas2.addEventListener("webglcontextrestored", onContextRestore, false); if (_gl === null) { const contextNames = ["webgl2", "webgl", "experimental-webgl"]; if (_this.isWebGL1Renderer === true) { contextNames.shift(); } _gl = getContext(contextNames, contextAttributes); if (_gl === null) { if (getContext(contextNames)) { throw new Error("Error creating WebGL context with your selected attributes."); } else { throw new Error("Error creating WebGL context."); } } } if (_gl.getShaderPrecisionFormat === void 0) { _gl.getShaderPrecisionFormat = function() { return { "rangeMin": 1, "rangeMax": 1, "precision": 1 }; }; } } catch (error) { console.error("THREE.WebGLRenderer: " + error.message); throw error; } let extensions, capabilities, state, info; let properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects; let programCache, materials, renderLists, renderStates, clipping, shadowMap; let background, morphtargets, bufferRenderer, indexedBufferRenderer; let utils, bindingStates; function initGLContext() { extensions = new WebGLExtensions(_gl); capabilities = new WebGLCapabilities(_gl, extensions, parameters); extensions.init(capabilities); utils = new WebGLUtils(_gl, extensions, capabilities); state = new WebGLState(_gl, extensions, capabilities); _currentDrawBuffers[0] = 1029; info = new WebGLInfo(_gl); properties = new WebGLProperties(); textures = new WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info); cubemaps = new WebGLCubeMaps(_this); cubeuvmaps = new WebGLCubeUVMaps(_this); attributes = new WebGLAttributes(_gl, capabilities); bindingStates = new WebGLBindingStates(_gl, extensions, attributes, capabilities); geometries = new WebGLGeometries(_gl, attributes, info, bindingStates); objects = new WebGLObjects(_gl, geometries, attributes, info); morphtargets = new WebGLMorphtargets(_gl); clipping = new WebGLClipping(properties); programCache = new WebGLPrograms(_this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping); materials = new WebGLMaterials(properties); renderLists = new WebGLRenderLists(properties); renderStates = new WebGLRenderStates(extensions, capabilities); background = new WebGLBackground(_this, cubemaps, state, objects, _premultipliedAlpha); shadowMap = new WebGLShadowMap(_this, objects, capabilities); bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info, capabilities); indexedBufferRenderer = new WebGLIndexedBufferRenderer(_gl, extensions, info, capabilities); info.programs = programCache.programs; _this.capabilities = capabilities; _this.extensions = extensions; _this.properties = properties; _this.renderLists = renderLists; _this.shadowMap = shadowMap; _this.state = state; _this.info = info; } initGLContext(); const xr = new WebXRManager(_this, _gl); this.xr = xr; this.getContext = function() { return _gl; }; this.getContextAttributes = function() { return _gl.getContextAttributes(); }; this.forceContextLoss = function() { const extension = extensions.get("WEBGL_lose_context"); if (extension) extension.loseContext(); }; this.forceContextRestore = function() { const extension = extensions.get("WEBGL_lose_context"); if (extension) extension.restoreContext(); }; this.getPixelRatio = function() { return _pixelRatio; }; this.setPixelRatio = function(value) { if (value === void 0) return; _pixelRatio = value; this.setSize(_width, _height, false); }; this.getSize = function(target) { return target.set(_width, _height); }; this.setSize = function(width, height, updateStyle) { if (xr.isPresenting) { console.warn("THREE.WebGLRenderer: Can't change size while VR device is presenting."); return; } _width = width; _height = height; _canvas2.width = Math.floor(width * _pixelRatio); _canvas2.height = Math.floor(height * _pixelRatio); if (updateStyle !== false) { _canvas2.style.width = width + "px"; _canvas2.style.height = height + "px"; } this.setViewport(0, 0, width, height); }; this.getDrawingBufferSize = function(target) { return target.set(_width * _pixelRatio, _height * _pixelRatio).floor(); }; this.setDrawingBufferSize = function(width, height, pixelRatio) { _width = width; _height = height; _pixelRatio = pixelRatio; _canvas2.width = Math.floor(width * pixelRatio); _canvas2.height = Math.floor(height * pixelRatio); this.setViewport(0, 0, width, height); }; this.getCurrentViewport = function(target) { return target.copy(_currentViewport); }; this.getViewport = function(target) { return target.copy(_viewport); }; this.setViewport = function(x, y, width, height) { if (x.isVector4) { _viewport.set(x.x, x.y, x.z, x.w); } else { _viewport.set(x, y, width, height); } state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor()); }; this.getScissor = function(target) { return target.copy(_scissor); }; this.setScissor = function(x, y, width, height) { if (x.isVector4) { _scissor.set(x.x, x.y, x.z, x.w); } else { _scissor.set(x, y, width, height); } state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor()); }; this.getScissorTest = function() { return _scissorTest; }; this.setScissorTest = function(boolean) { state.setScissorTest(_scissorTest = boolean); }; this.setOpaqueSort = function(method) { _opaqueSort = method; }; this.setTransparentSort = function(method) { _transparentSort = method; }; this.getClearColor = function(target) { return target.copy(background.getClearColor()); }; this.setClearColor = function() { background.setClearColor.apply(background, arguments); }; this.getClearAlpha = function() { return background.getClearAlpha(); }; this.setClearAlpha = function() { background.setClearAlpha.apply(background, arguments); }; this.clear = function(color, depth, stencil) { let bits = 0; if (color === void 0 || color) bits |= 16384; if (depth === void 0 || depth) bits |= 256; if (stencil === void 0 || stencil) bits |= 1024; _gl.clear(bits); }; this.clearColor = function() { this.clear(true, false, false); }; this.clearDepth = function() { this.clear(false, true, false); }; this.clearStencil = function() { this.clear(false, false, true); }; this.dispose = function() { _canvas2.removeEventListener("webglcontextlost", onContextLost, false); _canvas2.removeEventListener("webglcontextrestored", onContextRestore, false); renderLists.dispose(); renderStates.dispose(); properties.dispose(); cubemaps.dispose(); cubeuvmaps.dispose(); objects.dispose(); bindingStates.dispose(); xr.dispose(); xr.removeEventListener("sessionstart", onXRSessionStart); xr.removeEventListener("sessionend", onXRSessionEnd); if (_transmissionRenderTarget) { _transmissionRenderTarget.dispose(); _transmissionRenderTarget = null; } animation.stop(); }; function onContextLost(event) { event.preventDefault(); console.log("THREE.WebGLRenderer: Context Lost."); _isContextLost = true; } function onContextRestore() { console.log("THREE.WebGLRenderer: Context Restored."); _isContextLost = false; const infoAutoReset = info.autoReset; const shadowMapEnabled = shadowMap.enabled; const shadowMapAutoUpdate = shadowMap.autoUpdate; const shadowMapNeedsUpdate = shadowMap.needsUpdate; const shadowMapType = shadowMap.type; initGLContext(); info.autoReset = infoAutoReset; shadowMap.enabled = shadowMapEnabled; shadowMap.autoUpdate = shadowMapAutoUpdate; shadowMap.needsUpdate = shadowMapNeedsUpdate; shadowMap.type = shadowMapType; } function onMaterialDispose(event) { const material = event.target; material.removeEventListener("dispose", onMaterialDispose); deallocateMaterial(material); } function deallocateMaterial(material) { releaseMaterialProgramReferences(material); properties.remove(material); } function releaseMaterialProgramReferences(material) { const programs = properties.get(material).programs; if (programs !== void 0) { programs.forEach(function(program) { programCache.releaseProgram(program); }); } } function renderObjectImmediate(object, program) { object.render(function(object2) { _this.renderBufferImmediate(object2, program); }); } this.renderBufferImmediate = function(object, program) { bindingStates.initAttributes(); const buffers = properties.get(object); if (object.hasPositions && !buffers.position) buffers.position = _gl.createBuffer(); if (object.hasNormals && !buffers.normal) buffers.normal = _gl.createBuffer(); if (object.hasUvs && !buffers.uv) buffers.uv = _gl.createBuffer(); if (object.hasColors && !buffers.color) buffers.color = _gl.createBuffer(); const programAttributes = program.getAttributes(); if (object.hasPositions) { _gl.bindBuffer(34962, buffers.position); _gl.bufferData(34962, object.positionArray, 35048); bindingStates.enableAttribute(programAttributes.position.location); _gl.vertexAttribPointer(programAttributes.position.location, 3, 5126, false, 0, 0); } if (object.hasNormals) { _gl.bindBuffer(34962, buffers.normal); _gl.bufferData(34962, object.normalArray, 35048); bindingStates.enableAttribute(programAttributes.normal.location); _gl.vertexAttribPointer(programAttributes.normal.location, 3, 5126, false, 0, 0); } if (object.hasUvs) { _gl.bindBuffer(34962, buffers.uv); _gl.bufferData(34962, object.uvArray, 35048); bindingStates.enableAttribute(programAttributes.uv.location); _gl.vertexAttribPointer(programAttributes.uv.location, 2, 5126, false, 0, 0); } if (object.hasColors) { _gl.bindBuffer(34962, buffers.color); _gl.bufferData(34962, object.colorArray, 35048); bindingStates.enableAttribute(programAttributes.color.location); _gl.vertexAttribPointer(programAttributes.color.location, 3, 5126, false, 0, 0); } bindingStates.disableUnusedAttributes(); _gl.drawArrays(4, 0, object.count); object.count = 0; }; this.renderBufferDirect = function(camera, scene, geometry, material, object, group) { if (scene === null) scene = _emptyScene; const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; const program = setProgram(camera, scene, material, object); state.setMaterial(material, frontFaceCW); let index = geometry.index; const position = geometry.attributes.position; if (index === null) { if (position === void 0 || position.count === 0) return; } else if (index.count === 0) { return; } let rangeFactor = 1; if (material.wireframe === true) { index = geometries.getWireframeAttribute(geometry); rangeFactor = 2; } if (geometry.morphAttributes.position !== void 0 || geometry.morphAttributes.normal !== void 0) { morphtargets.update(object, geometry, material, program); } bindingStates.setup(object, material, program, geometry, index); let attribute; let renderer = bufferRenderer; if (index !== null) { attribute = attributes.get(index); renderer = indexedBufferRenderer; renderer.setIndex(attribute); } const dataCount = index !== null ? index.count : position.count; const rangeStart = geometry.drawRange.start * rangeFactor; const rangeCount = geometry.drawRange.count * rangeFactor; const groupStart = group !== null ? group.start * rangeFactor : 0; const groupCount = group !== null ? group.count * rangeFactor : Infinity; const drawStart = Math.max(rangeStart, groupStart); const drawEnd = Math.min(dataCount, rangeStart + rangeCount, groupStart + groupCount) - 1; const drawCount = Math.max(0, drawEnd - drawStart + 1); if (drawCount === 0) return; if (object.isMesh) { if (material.wireframe === true) { state.setLineWidth(material.wireframeLinewidth * getTargetPixelRatio()); renderer.setMode(1); } else { renderer.setMode(4); } } else if (object.isLine) { let lineWidth = material.linewidth; if (lineWidth === void 0) lineWidth = 1; state.setLineWidth(lineWidth * getTargetPixelRatio()); if (object.isLineSegments) { renderer.setMode(1); } else if (object.isLineLoop) { renderer.setMode(2); } else { renderer.setMode(3); } } else if (object.isPoints) { renderer.setMode(0); } else if (object.isSprite) { renderer.setMode(4); } if (object.isInstancedMesh) { renderer.renderInstances(drawStart, drawCount, object.count); } else if (geometry.isInstancedBufferGeometry) { const instanceCount = Math.min(geometry.instanceCount, geometry._maxInstanceCount); renderer.renderInstances(drawStart, drawCount, instanceCount); } else { renderer.render(drawStart, drawCount); } }; this.compile = function(scene, camera) { currentRenderState = renderStates.get(scene); currentRenderState.init(); renderStateStack.push(currentRenderState); scene.traverseVisible(function(object) { if (object.isLight && object.layers.test(camera.layers)) { currentRenderState.pushLight(object); if (object.castShadow) { currentRenderState.pushShadow(object); } } }); currentRenderState.setupLights(_this.physicallyCorrectLights); scene.traverse(function(object) { const material = object.material; if (material) { if (Array.isArray(material)) { for (let i = 0; i < material.length; i++) { const material2 = material[i]; getProgram(material2, scene, object); } } else { getProgram(material, scene, object); } } }); renderStateStack.pop(); currentRenderState = null; }; let onAnimationFrameCallback = null; function onAnimationFrame(time) { if (onAnimationFrameCallback) onAnimationFrameCallback(time); } function onXRSessionStart() { animation.stop(); } function onXRSessionEnd() { animation.start(); } const animation = new WebGLAnimation(); animation.setAnimationLoop(onAnimationFrame); if (typeof window !== "undefined") animation.setContext(window); this.setAnimationLoop = function(callback) { onAnimationFrameCallback = callback; xr.setAnimationLoop(callback); callback === null ? animation.stop() : animation.start(); }; xr.addEventListener("sessionstart", onXRSessionStart); xr.addEventListener("sessionend", onXRSessionEnd); this.render = function(scene, camera) { if (camera !== void 0 && camera.isCamera !== true) { console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera."); return; } if (_isContextLost === true) return; if (scene.autoUpdate === true) scene.updateMatrixWorld(); if (camera.parent === null) camera.updateMatrixWorld(); if (xr.enabled === true && xr.isPresenting === true) { if (xr.cameraAutoUpdate === true) xr.updateCamera(camera); camera = xr.getCamera(); } if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, _currentRenderTarget); currentRenderState = renderStates.get(scene, renderStateStack.length); currentRenderState.init(); renderStateStack.push(currentRenderState); _projScreenMatrix2.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); _frustum.setFromProjectionMatrix(_projScreenMatrix2); _localClippingEnabled = this.localClippingEnabled; _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled, camera); currentRenderList = renderLists.get(scene, renderListStack.length); currentRenderList.init(); renderListStack.push(currentRenderList); projectObject(scene, camera, 0, _this.sortObjects); currentRenderList.finish(); if (_this.sortObjects === true) { currentRenderList.sort(_opaqueSort, _transparentSort); } if (_clippingEnabled === true) clipping.beginShadows(); const shadowsArray = currentRenderState.state.shadowsArray; shadowMap.render(shadowsArray, scene, camera); if (_clippingEnabled === true) clipping.endShadows(); if (this.info.autoReset === true) this.info.reset(); background.render(currentRenderList, scene); currentRenderState.setupLights(_this.physicallyCorrectLights); if (camera.isArrayCamera) { const cameras = camera.cameras; for (let i = 0, l = cameras.length; i < l; i++) { const camera2 = cameras[i]; renderScene(currentRenderList, scene, camera2, camera2.viewport); } } else { renderScene(currentRenderList, scene, camera); } if (_currentRenderTarget !== null) { textures.updateMultisampleRenderTarget(_currentRenderTarget); textures.updateRenderTargetMipmap(_currentRenderTarget); } if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); state.buffers.depth.setTest(true); state.buffers.depth.setMask(true); state.buffers.color.setMask(true); state.setPolygonOffset(false); bindingStates.resetDefaultState(); _currentMaterialId = -1; _currentCamera = null; renderStateStack.pop(); if (renderStateStack.length > 0) { currentRenderState = renderStateStack[renderStateStack.length - 1]; } else { currentRenderState = null; } renderListStack.pop(); if (renderListStack.length > 0) { currentRenderList = renderListStack[renderListStack.length - 1]; } else { currentRenderList = null; } }; function projectObject(object, camera, groupOrder, sortObjects) { if (object.visible === false) return; const visible = object.layers.test(camera.layers); if (visible) { if (object.isGroup) { groupOrder = object.renderOrder; } else if (object.isLOD) { if (object.autoUpdate === true) object.update(camera); } else if (object.isLight) { currentRenderState.pushLight(object); if (object.castShadow) { currentRenderState.pushShadow(object); } } else if (object.isSprite) { if (!object.frustumCulled || _frustum.intersectsSprite(object)) { if (sortObjects) { _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix2); } const geometry = objects.update(object); const material = object.material; if (material.visible) { currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); } } } else if (object.isImmediateRenderObject) { if (sortObjects) { _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix2); } currentRenderList.push(object, null, object.material, groupOrder, _vector3.z, null); } else if (object.isMesh || object.isLine || object.isPoints) { if (object.isSkinnedMesh) { if (object.skeleton.frame !== info.render.frame) { object.skeleton.update(); object.skeleton.frame = info.render.frame; } } if (!object.frustumCulled || _frustum.intersectsObject(object)) { if (sortObjects) { _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix2); } const geometry = objects.update(object); const material = object.material; if (Array.isArray(material)) { const groups = geometry.groups; for (let i = 0, l = groups.length; i < l; i++) { const group = groups[i]; const groupMaterial = material[group.materialIndex]; if (groupMaterial && groupMaterial.visible) { currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group); } } } else if (material.visible) { currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null); } } } } const children = object.children; for (let i = 0, l = children.length; i < l; i++) { projectObject(children[i], camera, groupOrder, sortObjects); } } function renderScene(currentRenderList2, scene, camera, viewport) { const opaqueObjects = currentRenderList2.opaque; const transmissiveObjects = currentRenderList2.transmissive; const transparentObjects = currentRenderList2.transparent; currentRenderState.setupLightsView(camera); if (transmissiveObjects.length > 0) renderTransmissionPass(opaqueObjects, scene, camera); if (viewport) state.viewport(_currentViewport.copy(viewport)); if (opaqueObjects.length > 0) renderObjects(opaqueObjects, scene, camera); if (transmissiveObjects.length > 0) renderObjects(transmissiveObjects, scene, camera); if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera); } function renderTransmissionPass(opaqueObjects, scene, camera) { if (_transmissionRenderTarget === null) { const needsAntialias = _antialias === true && capabilities.isWebGL2 === true; const renderTargetType = needsAntialias ? WebGLMultisampleRenderTarget : WebGLRenderTarget; _transmissionRenderTarget = new renderTargetType(1024, 1024, { generateMipmaps: true, type: utils.convert(HalfFloatType) !== null ? HalfFloatType : UnsignedByteType, minFilter: LinearMipmapLinearFilter, magFilter: NearestFilter, wrapS: ClampToEdgeWrapping, wrapT: ClampToEdgeWrapping }); } const currentRenderTarget = _this.getRenderTarget(); _this.setRenderTarget(_transmissionRenderTarget); _this.clear(); const currentToneMapping = _this.toneMapping; _this.toneMapping = NoToneMapping; renderObjects(opaqueObjects, scene, camera); _this.toneMapping = currentToneMapping; textures.updateMultisampleRenderTarget(_transmissionRenderTarget); textures.updateRenderTargetMipmap(_transmissionRenderTarget); _this.setRenderTarget(currentRenderTarget); } function renderObjects(renderList, scene, camera) { const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null; for (let i = 0, l = renderList.length; i < l; i++) { const renderItem = renderList[i]; const object = renderItem.object; const geometry = renderItem.geometry; const material = overrideMaterial === null ? renderItem.material : overrideMaterial; const group = renderItem.group; if (object.layers.test(camera.layers)) { renderObject(object, scene, camera, geometry, material, group); } } } function renderObject(object, scene, camera, geometry, material, group) { object.onBeforeRender(_this, scene, camera, geometry, material, group); object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld); object.normalMatrix.getNormalMatrix(object.modelViewMatrix); if (object.isImmediateRenderObject) { const program = setProgram(camera, scene, material, object); state.setMaterial(material); bindingStates.reset(); renderObjectImmediate(object, program); } else { if (material.transparent === true && material.side === DoubleSide) { material.side = BackSide; material.needsUpdate = true; _this.renderBufferDirect(camera, scene, geometry, material, object, group); material.side = FrontSide; material.needsUpdate = true; _this.renderBufferDirect(camera, scene, geometry, material, object, group); material.side = DoubleSide; } else { _this.renderBufferDirect(camera, scene, geometry, material, object, group); } } object.onAfterRender(_this, scene, camera, geometry, material, group); } function getProgram(material, scene, object) { if (scene.isScene !== true) scene = _emptyScene; const materialProperties = properties.get(material); const lights = currentRenderState.state.lights; const shadowsArray = currentRenderState.state.shadowsArray; const lightsStateVersion = lights.state.version; const parameters2 = programCache.getParameters(material, lights.state, shadowsArray, scene, object); const programCacheKey = programCache.getProgramCacheKey(parameters2); let programs = materialProperties.programs; materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null; materialProperties.fog = scene.fog; materialProperties.envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || materialProperties.environment); if (programs === void 0) { material.addEventListener("dispose", onMaterialDispose); programs = /* @__PURE__ */ new Map(); materialProperties.programs = programs; } let program = programs.get(programCacheKey); if (program !== void 0) { if (materialProperties.currentProgram === program && materialProperties.lightsStateVersion === lightsStateVersion) { updateCommonMaterialProperties(material, parameters2); return program; } } else { parameters2.uniforms = programCache.getUniforms(material); material.onBuild(parameters2, _this); material.onBeforeCompile(parameters2, _this); program = programCache.acquireProgram(parameters2, programCacheKey); programs.set(programCacheKey, program); materialProperties.uniforms = parameters2.uniforms; } const uniforms = materialProperties.uniforms; if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) { uniforms.clippingPlanes = clipping.uniform; } updateCommonMaterialProperties(material, parameters2); materialProperties.needsLights = materialNeedsLights(material); materialProperties.lightsStateVersion = lightsStateVersion; if (materialProperties.needsLights) { uniforms.ambientLightColor.value = lights.state.ambient; uniforms.lightProbe.value = lights.state.probe; uniforms.directionalLights.value = lights.state.directional; uniforms.directionalLightShadows.value = lights.state.directionalShadow; uniforms.spotLights.value = lights.state.spot; uniforms.spotLightShadows.value = lights.state.spotShadow; uniforms.rectAreaLights.value = lights.state.rectArea; uniforms.ltc_1.value = lights.state.rectAreaLTC1; uniforms.ltc_2.value = lights.state.rectAreaLTC2; uniforms.pointLights.value = lights.state.point; uniforms.pointLightShadows.value = lights.state.pointShadow; uniforms.hemisphereLights.value = lights.state.hemi; uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix; uniforms.spotShadowMap.value = lights.state.spotShadowMap; uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix; uniforms.pointShadowMap.value = lights.state.pointShadowMap; uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; } const progUniforms = program.getUniforms(); const uniformsList = WebGLUniforms.seqWithValue(progUniforms.seq, uniforms); materialProperties.currentProgram = program; materialProperties.uniformsList = uniformsList; return program; } function updateCommonMaterialProperties(material, parameters2) { const materialProperties = properties.get(material); materialProperties.outputEncoding = parameters2.outputEncoding; materialProperties.instancing = parameters2.instancing; materialProperties.skinning = parameters2.skinning; materialProperties.morphTargets = parameters2.morphTargets; materialProperties.morphNormals = parameters2.morphNormals; materialProperties.numClippingPlanes = parameters2.numClippingPlanes; materialProperties.numIntersection = parameters2.numClipIntersection; materialProperties.vertexAlphas = parameters2.vertexAlphas; materialProperties.vertexTangents = parameters2.vertexTangents; } function setProgram(camera, scene, material, object) { if (scene.isScene !== true) scene = _emptyScene; textures.resetTextureUnits(); const fog = scene.fog; const environment = material.isMeshStandardMaterial ? scene.environment : null; const encoding = _currentRenderTarget === null ? _this.outputEncoding : _currentRenderTarget.texture.encoding; const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment); const vertexAlphas = material.vertexColors === true && !!object.geometry && !!object.geometry.attributes.color && object.geometry.attributes.color.itemSize === 4; const vertexTangents = !!object.geometry && !!object.geometry.attributes.tangent; const morphTargets = !!object.geometry && !!object.geometry.morphAttributes.position; const morphNormals = !!object.geometry && !!object.geometry.morphAttributes.normal; const materialProperties = properties.get(material); const lights = currentRenderState.state.lights; if (_clippingEnabled === true) { if (_localClippingEnabled === true || camera !== _currentCamera) { const useCache = camera === _currentCamera && material.id === _currentMaterialId; clipping.setState(material, camera, useCache); } } let needsProgramChange = false; if (material.version === materialProperties.__version) { if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) { needsProgramChange = true; } else if (materialProperties.outputEncoding !== encoding) { needsProgramChange = true; } else if (object.isInstancedMesh && materialProperties.instancing === false) { needsProgramChange = true; } else if (!object.isInstancedMesh && materialProperties.instancing === true) { needsProgramChange = true; } else if (object.isSkinnedMesh && materialProperties.skinning === false) { needsProgramChange = true; } else if (!object.isSkinnedMesh && materialProperties.skinning === true) { needsProgramChange = true; } else if (materialProperties.envMap !== envMap) { needsProgramChange = true; } else if (material.fog && materialProperties.fog !== fog) { needsProgramChange = true; } else if (materialProperties.numClippingPlanes !== void 0 && (materialProperties.numClippingPlanes !== clipping.numPlanes || materialProperties.numIntersection !== clipping.numIntersection)) { needsProgramChange = true; } else if (materialProperties.vertexAlphas !== vertexAlphas) { needsProgramChange = true; } else if (materialProperties.vertexTangents !== vertexTangents) { needsProgramChange = true; } else if (materialProperties.morphTargets !== morphTargets) { needsProgramChange = true; } else if (materialProperties.morphNormals !== morphNormals) { needsProgramChange = true; } } else { needsProgramChange = true; materialProperties.__version = material.version; } let program = materialProperties.currentProgram; if (needsProgramChange === true) { program = getProgram(material, scene, object); } let refreshProgram = false; let refreshMaterial = false; let refreshLights = false; const p_uniforms = program.getUniforms(), m_uniforms = materialProperties.uniforms; if (state.useProgram(program.program)) { refreshProgram = true; refreshMaterial = true; refreshLights = true; } if (material.id !== _currentMaterialId) { _currentMaterialId = material.id; refreshMaterial = true; } if (refreshProgram || _currentCamera !== camera) { p_uniforms.setValue(_gl, "projectionMatrix", camera.projectionMatrix); if (capabilities.logarithmicDepthBuffer) { p_uniforms.setValue(_gl, "logDepthBufFC", 2 / (Math.log(camera.far + 1) / Math.LN2)); } if (_currentCamera !== camera) { _currentCamera = camera; refreshMaterial = true; refreshLights = true; } if (material.isShaderMaterial || material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap) { const uCamPos = p_uniforms.map.cameraPosition; if (uCamPos !== void 0) { uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld)); } } if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) { p_uniforms.setValue(_gl, "isOrthographic", camera.isOrthographicCamera === true); } if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial || material.isShadowMaterial || object.isSkinnedMesh) { p_uniforms.setValue(_gl, "viewMatrix", camera.matrixWorldInverse); } } if (object.isSkinnedMesh) { p_uniforms.setOptional(_gl, object, "bindMatrix"); p_uniforms.setOptional(_gl, object, "bindMatrixInverse"); const skeleton = object.skeleton; if (skeleton) { if (capabilities.floatVertexTextures) { if (skeleton.boneTexture === null) skeleton.computeBoneTexture(); p_uniforms.setValue(_gl, "boneTexture", skeleton.boneTexture, textures); p_uniforms.setValue(_gl, "boneTextureSize", skeleton.boneTextureSize); } else { p_uniforms.setOptional(_gl, skeleton, "boneMatrices"); } } } if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) { materialProperties.receiveShadow = object.receiveShadow; p_uniforms.setValue(_gl, "receiveShadow", object.receiveShadow); } if (refreshMaterial) { p_uniforms.setValue(_gl, "toneMappingExposure", _this.toneMappingExposure); if (materialProperties.needsLights) { markUniformsLightsNeedsUpdate(m_uniforms, refreshLights); } if (fog && material.fog) { materials.refreshFogUniforms(m_uniforms, fog); } materials.refreshMaterialUniforms(m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget); WebGLUniforms.upload(_gl, materialProperties.uniformsList, m_uniforms, textures); } if (material.isShaderMaterial && material.uniformsNeedUpdate === true) { WebGLUniforms.upload(_gl, materialProperties.uniformsList, m_uniforms, textures); material.uniformsNeedUpdate = false; } if (material.isSpriteMaterial) { p_uniforms.setValue(_gl, "center", object.center); } p_uniforms.setValue(_gl, "modelViewMatrix", object.modelViewMatrix); p_uniforms.setValue(_gl, "normalMatrix", object.normalMatrix); p_uniforms.setValue(_gl, "modelMatrix", object.matrixWorld); return program; } function markUniformsLightsNeedsUpdate(uniforms, value) { uniforms.ambientLightColor.needsUpdate = value; uniforms.lightProbe.needsUpdate = value; uniforms.directionalLights.needsUpdate = value; uniforms.directionalLightShadows.needsUpdate = value; uniforms.pointLights.needsUpdate = value; uniforms.pointLightShadows.needsUpdate = value; uniforms.spotLights.needsUpdate = value; uniforms.spotLightShadows.needsUpdate = value; uniforms.rectAreaLights.needsUpdate = value; uniforms.hemisphereLights.needsUpdate = value; } function materialNeedsLights(material) { return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isShadowMaterial || material.isShaderMaterial && material.lights === true; } this.getActiveCubeFace = function() { return _currentActiveCubeFace; }; this.getActiveMipmapLevel = function() { return _currentActiveMipmapLevel; }; this.getRenderTarget = function() { return _currentRenderTarget; }; this.setRenderTarget = function(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { _currentRenderTarget = renderTarget; _currentActiveCubeFace = activeCubeFace; _currentActiveMipmapLevel = activeMipmapLevel; if (renderTarget && properties.get(renderTarget).__webglFramebuffer === void 0) { textures.setupRenderTarget(renderTarget); } let framebuffer = null; let isCube = false; let isRenderTarget3D = false; if (renderTarget) { const texture = renderTarget.texture; if (texture.isDataTexture3D || texture.isDataTexture2DArray) { isRenderTarget3D = true; } const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer; if (renderTarget.isWebGLCubeRenderTarget) { framebuffer = __webglFramebuffer[activeCubeFace]; isCube = true; } else if (renderTarget.isWebGLMultisampleRenderTarget) { framebuffer = properties.get(renderTarget).__webglMultisampledFramebuffer; } else { framebuffer = __webglFramebuffer; } _currentViewport.copy(renderTarget.viewport); _currentScissor.copy(renderTarget.scissor); _currentScissorTest = renderTarget.scissorTest; } else { _currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor(); _currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor(); _currentScissorTest = _scissorTest; } const framebufferBound = state.bindFramebuffer(36160, framebuffer); if (framebufferBound && capabilities.drawBuffers) { let needsUpdate = false; if (renderTarget) { if (renderTarget.isWebGLMultipleRenderTargets) { const textures2 = renderTarget.texture; if (_currentDrawBuffers.length !== textures2.length || _currentDrawBuffers[0] !== 36064) { for (let i = 0, il = textures2.length; i < il; i++) { _currentDrawBuffers[i] = 36064 + i; } _currentDrawBuffers.length = textures2.length; needsUpdate = true; } } else { if (_currentDrawBuffers.length !== 1 || _currentDrawBuffers[0] !== 36064) { _currentDrawBuffers[0] = 36064; _currentDrawBuffers.length = 1; needsUpdate = true; } } } else { if (_currentDrawBuffers.length !== 1 || _currentDrawBuffers[0] !== 1029) { _currentDrawBuffers[0] = 1029; _currentDrawBuffers.length = 1; needsUpdate = true; } } if (needsUpdate) { if (capabilities.isWebGL2) { _gl.drawBuffers(_currentDrawBuffers); } else { extensions.get("WEBGL_draw_buffers").drawBuffersWEBGL(_currentDrawBuffers); } } } state.viewport(_currentViewport); state.scissor(_currentScissor); state.setScissorTest(_currentScissorTest); if (isCube) { const textureProperties = properties.get(renderTarget.texture); _gl.framebufferTexture2D(36160, 36064, 34069 + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel); } else if (isRenderTarget3D) { const textureProperties = properties.get(renderTarget.texture); const layer = activeCubeFace || 0; _gl.framebufferTextureLayer(36160, 36064, textureProperties.__webglTexture, activeMipmapLevel || 0, layer); } _currentMaterialId = -1; }; this.readRenderTargetPixels = function(renderTarget, x, y, width, height, buffer, activeCubeFaceIndex) { if (!(renderTarget && renderTarget.isWebGLRenderTarget)) { console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); return; } let framebuffer = properties.get(renderTarget).__webglFramebuffer; if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== void 0) { framebuffer = framebuffer[activeCubeFaceIndex]; } if (framebuffer) { state.bindFramebuffer(36160, framebuffer); try { const texture = renderTarget.texture; const textureFormat = texture.format; const textureType = texture.type; if (textureFormat !== RGBAFormat && utils.convert(textureFormat) !== _gl.getParameter(35739)) { console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."); return; } const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has("EXT_color_buffer_half_float") || capabilities.isWebGL2 && extensions.has("EXT_color_buffer_float")); if (textureType !== UnsignedByteType && utils.convert(textureType) !== _gl.getParameter(35738) && !(textureType === FloatType && (capabilities.isWebGL2 || extensions.has("OES_texture_float") || extensions.has("WEBGL_color_buffer_float"))) && !halfFloatSupportedByExt) { console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type."); return; } if (_gl.checkFramebufferStatus(36160) === 36053) { if (x >= 0 && x <= renderTarget.width - width && (y >= 0 && y <= renderTarget.height - height)) { _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), buffer); } } else { console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."); } } finally { const framebuffer2 = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null; state.bindFramebuffer(36160, framebuffer2); } } }; this.copyFramebufferToTexture = function(position, texture, level = 0) { const levelScale = Math.pow(2, -level); const width = Math.floor(texture.image.width * levelScale); const height = Math.floor(texture.image.height * levelScale); let glFormat = utils.convert(texture.format); if (capabilities.isWebGL2) { if (glFormat === 6407) glFormat = 32849; if (glFormat === 6408) glFormat = 32856; } textures.setTexture2D(texture, 0); _gl.copyTexImage2D(3553, level, glFormat, position.x, position.y, width, height, 0); state.unbindTexture(); }; this.copyTextureToTexture = function(position, srcTexture, dstTexture, level = 0) { const width = srcTexture.image.width; const height = srcTexture.image.height; const glFormat = utils.convert(dstTexture.format); const glType = utils.convert(dstTexture.type); textures.setTexture2D(dstTexture, 0); _gl.pixelStorei(37440, dstTexture.flipY); _gl.pixelStorei(37441, dstTexture.premultiplyAlpha); _gl.pixelStorei(3317, dstTexture.unpackAlignment); if (srcTexture.isDataTexture) { _gl.texSubImage2D(3553, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data); } else { if (srcTexture.isCompressedTexture) { _gl.compressedTexSubImage2D(3553, level, position.x, position.y, srcTexture.mipmaps[0].width, srcTexture.mipmaps[0].height, glFormat, srcTexture.mipmaps[0].data); } else { _gl.texSubImage2D(3553, level, position.x, position.y, glFormat, glType, srcTexture.image); } } if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(3553); state.unbindTexture(); }; this.copyTextureToTexture3D = function(sourceBox, position, srcTexture, dstTexture, level = 0) { if (_this.isWebGL1Renderer) { console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2."); return; } const width = sourceBox.max.x - sourceBox.min.x + 1; const height = sourceBox.max.y - sourceBox.min.y + 1; const depth = sourceBox.max.z - sourceBox.min.z + 1; const glFormat = utils.convert(dstTexture.format); const glType = utils.convert(dstTexture.type); let glTarget; if (dstTexture.isDataTexture3D) { textures.setTexture3D(dstTexture, 0); glTarget = 32879; } else if (dstTexture.isDataTexture2DArray) { textures.setTexture2DArray(dstTexture, 0); glTarget = 35866; } else { console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray."); return; } _gl.pixelStorei(37440, dstTexture.flipY); _gl.pixelStorei(37441, dstTexture.premultiplyAlpha); _gl.pixelStorei(3317, dstTexture.unpackAlignment); const unpackRowLen = _gl.getParameter(3314); const unpackImageHeight = _gl.getParameter(32878); const unpackSkipPixels = _gl.getParameter(3316); const unpackSkipRows = _gl.getParameter(3315); const unpackSkipImages = _gl.getParameter(32877); const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[0] : srcTexture.image; _gl.pixelStorei(3314, image.width); _gl.pixelStorei(32878, image.height); _gl.pixelStorei(3316, sourceBox.min.x); _gl.pixelStorei(3315, sourceBox.min.y); _gl.pixelStorei(32877, sourceBox.min.z); if (srcTexture.isDataTexture || srcTexture.isDataTexture3D) { _gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image.data); } else { if (srcTexture.isCompressedTexture) { console.warn("THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture."); _gl.compressedTexSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, image.data); } else { _gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image); } } _gl.pixelStorei(3314, unpackRowLen); _gl.pixelStorei(32878, unpackImageHeight); _gl.pixelStorei(3316, unpackSkipPixels); _gl.pixelStorei(3315, unpackSkipRows); _gl.pixelStorei(32877, unpackSkipImages); if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(glTarget); state.unbindTexture(); }; this.initTexture = function(texture) { textures.setTexture2D(texture, 0); state.unbindTexture(); }; this.resetState = function() { _currentActiveCubeFace = 0; _currentActiveMipmapLevel = 0; _currentRenderTarget = null; state.reset(); bindingStates.reset(); }; if (typeof __THREE_DEVTOOLS__ !== "undefined") { __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this })); } } var WebGL1Renderer = class extends WebGLRenderer { }; WebGL1Renderer.prototype.isWebGL1Renderer = true; var FogExp2 = class { constructor(color, density = 25e-5) { this.name = ""; this.color = new Color(color); this.density = density; } clone() { return new FogExp2(this.color, this.density); } toJSON() { return { type: "FogExp2", color: this.color.getHex(), density: this.density }; } }; FogExp2.prototype.isFogExp2 = true; var Fog = class { constructor(color, near = 1, far = 1e3) { this.name = ""; this.color = new Color(color); this.near = near; this.far = far; } clone() { return new Fog(this.color, this.near, this.far); } toJSON() { return { type: "Fog", color: this.color.getHex(), near: this.near, far: this.far }; } }; Fog.prototype.isFog = true; var Scene = class extends Object3D { constructor() { super(); this.type = "Scene"; this.background = null; this.environment = null; this.fog = null; this.overrideMaterial = null; this.autoUpdate = true; if (typeof __THREE_DEVTOOLS__ !== "undefined") { __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe", { detail: this })); } } copy(source, recursive) { super.copy(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(meta) { const data = super.toJSON(meta); if (this.fog !== null) data.object.fog = this.fog.toJSON(); return data; } }; Scene.prototype.isScene = true; var InterleavedBuffer = class { constructor(array, stride) { this.array = array; this.stride = stride; this.count = array !== void 0 ? array.length / stride : 0; this.usage = StaticDrawUsage; this.updateRange = { offset: 0, count: -1 }; this.version = 0; this.uuid = generateUUID(); } onUploadCallback() { } set needsUpdate(value) { if (value === true) this.version++; } setUsage(value) { this.usage = value; return this; } copy(source) { this.array = new source.array.constructor(source.array); this.count = source.count; this.stride = source.stride; this.usage = source.usage; return this; } copyAt(index1, attribute, index2) { index1 *= this.stride; index2 *= attribute.stride; for (let i = 0, l = this.stride; i < l; i++) { this.array[index1 + i] = attribute.array[index2 + i]; } return this; } set(value, offset = 0) { this.array.set(value, offset); return this; } clone(data) { if (data.arrayBuffers === void 0) { data.arrayBuffers = {}; } if (this.array.buffer._uuid === void 0) { this.array.buffer._uuid = generateUUID(); } if (data.arrayBuffers[this.array.buffer._uuid] === void 0) { data.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer; } const array = new this.array.constructor(data.arrayBuffers[this.array.buffer._uuid]); const ib = new this.constructor(array, this.stride); ib.setUsage(this.usage); return ib; } onUpload(callback) { this.onUploadCallback = callback; return this; } toJSON(data) { if (data.arrayBuffers === void 0) { data.arrayBuffers = {}; } if (this.array.buffer._uuid === void 0) { this.array.buffer._uuid = generateUUID(); } if (data.arrayBuffers[this.array.buffer._uuid] === void 0) { data.arrayBuffers[this.array.buffer._uuid] = Array.prototype.slice.call(new Uint32Array(this.array.buffer)); } return { uuid: this.uuid, buffer: this.array.buffer._uuid, type: this.array.constructor.name, stride: this.stride }; } }; InterleavedBuffer.prototype.isInterleavedBuffer = true; var _vector$6 = /* @__PURE__ */ new Vector3(); var InterleavedBufferAttribute = class { constructor(interleavedBuffer, itemSize, offset, normalized = false) { this.name = ""; this.data = interleavedBuffer; this.itemSize = itemSize; this.offset = offset; this.normalized = normalized === true; } get count() { return this.data.count; } get array() { return this.data.array; } set needsUpdate(value) { this.data.needsUpdate = value; } applyMatrix4(m) { for (let i = 0, l = this.data.count; i < l; i++) { _vector$6.x = this.getX(i); _vector$6.y = this.getY(i); _vector$6.z = this.getZ(i); _vector$6.applyMatrix4(m); this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); } return this; } applyNormalMatrix(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$6.x = this.getX(i); _vector$6.y = this.getY(i); _vector$6.z = this.getZ(i); _vector$6.applyNormalMatrix(m); this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); } return this; } transformDirection(m) { for (let i = 0, l = this.count; i < l; i++) { _vector$6.x = this.getX(i); _vector$6.y = this.getY(i); _vector$6.z = this.getZ(i); _vector$6.transformDirection(m); this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z); } return this; } setX(index, x) { this.data.array[index * this.data.stride + this.offset] = x; return this; } setY(index, y) { this.data.array[index * this.data.stride + this.offset + 1] = y; return this; } setZ(index, z) { this.data.array[index * this.data.stride + this.offset + 2] = z; return this; } setW(index, w2) { this.data.array[index * this.data.stride + this.offset + 3] = w2; return this; } getX(index) { return this.data.array[index * this.data.stride + this.offset]; } getY(index) { return this.data.array[index * this.data.stride + this.offset + 1]; } getZ(index) { return this.data.array[index * this.data.stride + this.offset + 2]; } getW(index) { return this.data.array[index * this.data.stride + this.offset + 3]; } setXY(index, x, y) { index = index * this.data.stride + this.offset; this.data.array[index + 0] = x; this.data.array[index + 1] = y; return this; } setXYZ(index, x, y, z) { index = index * this.data.stride + this.offset; this.data.array[index + 0] = x; this.data.array[index + 1] = y; this.data.array[index + 2] = z; return this; } setXYZW(index, x, y, z, w2) { index = index * this.data.stride + this.offset; this.data.array[index + 0] = x; this.data.array[index + 1] = y; this.data.array[index + 2] = z; this.data.array[index + 3] = w2; return this; } clone(data) { if (data === void 0) { console.log("THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data."); const array = []; for (let i = 0; i < this.count; i++) { const index = i * this.data.stride + this.offset; for (let j = 0; j < this.itemSize; j++) { array.push(this.data.array[index + j]); } } return new BufferAttribute(new this.array.constructor(array), this.itemSize, this.normalized); } else { if (data.interleavedBuffers === void 0) { data.interleavedBuffers = {}; } if (data.interleavedBuffers[this.data.uuid] === void 0) { data.interleavedBuffers[this.data.uuid] = this.data.clone(data); } return new InterleavedBufferAttribute(data.interleavedBuffers[this.data.uuid], this.itemSize, this.offset, this.normalized); } } toJSON(data) { if (data === void 0) { console.log("THREE.InterleavedBufferAttribute.toJSON(): Serializing an interlaved buffer attribute will deinterleave buffer data."); const array = []; for (let i = 0; i < this.count; i++) { const index = i * this.data.stride + this.offset; for (let j = 0; j < this.itemSize; j++) { array.push(this.data.array[index + j]); } } return { itemSize: this.itemSize, type: this.array.constructor.name, array, normalized: this.normalized }; } else { if (data.interleavedBuffers === void 0) { data.interleavedBuffers = {}; } if (data.interleavedBuffers[this.data.uuid] === void 0) { data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data); } return { isInterleavedBufferAttribute: true, itemSize: this.itemSize, data: this.data.uuid, offset: this.offset, normalized: this.normalized }; } } }; InterleavedBufferAttribute.prototype.isInterleavedBufferAttribute = true; var SpriteMaterial = class extends Material { constructor(parameters) { super(); this.type = "SpriteMaterial"; this.color = new Color(16777215); this.map = null; this.alphaMap = null; this.rotation = 0; this.sizeAttenuation = true; this.transparent = true; this.setValues(parameters); } copy(source) { super.copy(source); this.color.copy(source.color); this.map = source.map; this.alphaMap = source.alphaMap; this.rotation = source.rotation; this.sizeAttenuation = source.sizeAttenuation; return this; } }; SpriteMaterial.prototype.isSpriteMaterial = true; var _geometry; var _intersectPoint = /* @__PURE__ */ new Vector3(); var _worldScale = /* @__PURE__ */ new Vector3(); var _mvPosition = /* @__PURE__ */ new Vector3(); var _alignedPosition = /* @__PURE__ */ new Vector2(); var _rotatedPosition = /* @__PURE__ */ new Vector2(); var _viewWorldMatrix = /* @__PURE__ */ new Matrix4(); var _vA = /* @__PURE__ */ new Vector3(); var _vB = /* @__PURE__ */ new Vector3(); var _vC = /* @__PURE__ */ new Vector3(); var _uvA = /* @__PURE__ */ new Vector2(); var _uvB = /* @__PURE__ */ new Vector2(); var _uvC = /* @__PURE__ */ new Vector2(); var Sprite = class extends Object3D { constructor(material) { super(); this.type = "Sprite"; if (_geometry === void 0) { _geometry = new BufferGeometry(); const float32Array = new Float32Array([ -0.5, -0.5, 0, 0, 0, 0.5, -0.5, 0, 1, 0, 0.5, 0.5, 0, 1, 1, -0.5, 0.5, 0, 0, 1 ]); const interleavedBuffer = new InterleavedBuffer(float32Array, 5); _geometry.setIndex([0, 1, 2, 0, 2, 3]); _geometry.setAttribute("position", new InterleavedBufferAttribute(interleavedBuffer, 3, 0, false)); _geometry.setAttribute("uv", new InterleavedBufferAttribute(interleavedBuffer, 2, 3, false)); } this.geometry = _geometry; this.material = material !== void 0 ? material : new SpriteMaterial(); this.center = new Vector2(0.5, 0.5); } raycast(raycaster, intersects2) { if (raycaster.camera === null) { console.error('THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.'); } _worldScale.setFromMatrixScale(this.matrixWorld); _viewWorldMatrix.copy(raycaster.camera.matrixWorld); this.modelViewMatrix.multiplyMatrices(raycaster.camera.matrixWorldInverse, this.matrixWorld); _mvPosition.setFromMatrixPosition(this.modelViewMatrix); if (raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false) { _worldScale.multiplyScalar(-_mvPosition.z); } const rotation = this.material.rotation; let sin, cos; if (rotation !== 0) { cos = Math.cos(rotation); sin = Math.sin(rotation); } const center = this.center; transformVertex(_vA.set(-0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos); transformVertex(_vB.set(0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos); transformVertex(_vC.set(0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); _uvA.set(0, 0); _uvB.set(1, 0); _uvC.set(1, 1); let intersect2 = raycaster.ray.intersectTriangle(_vA, _vB, _vC, false, _intersectPoint); if (intersect2 === null) { transformVertex(_vB.set(-0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos); _uvB.set(0, 1); intersect2 = raycaster.ray.intersectTriangle(_vA, _vC, _vB, false, _intersectPoint); if (intersect2 === null) { return; } } const distance = raycaster.ray.origin.distanceTo(_intersectPoint); if (distance < raycaster.near || distance > raycaster.far) return; intersects2.push({ distance, point: _intersectPoint.clone(), uv: Triangle.getUV(_intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2()), face: null, object: this }); } copy(source) { super.copy(source); if (source.center !== void 0) this.center.copy(source.center); this.material = source.material; return this; } }; Sprite.prototype.isSprite = true; function transformVertex(vertexPosition, mvPosition, center, scale, sin, cos) { _alignedPosition.subVectors(vertexPosition, center).addScalar(0.5).multiply(scale); if (sin !== void 0) { _rotatedPosition.x = cos * _alignedPosition.x - sin * _alignedPosition.y; _rotatedPosition.y = sin * _alignedPosition.x + cos * _alignedPosition.y; } else { _rotatedPosition.copy(_alignedPosition); } vertexPosition.copy(mvPosition); vertexPosition.x += _rotatedPosition.x; vertexPosition.y += _rotatedPosition.y; vertexPosition.applyMatrix4(_viewWorldMatrix); } var _basePosition = /* @__PURE__ */ new Vector3(); var _skinIndex = /* @__PURE__ */ new Vector4(); var _skinWeight = /* @__PURE__ */ new Vector4(); var _vector$5 = /* @__PURE__ */ new Vector3(); var _matrix = /* @__PURE__ */ new Matrix4(); var SkinnedMesh = class extends Mesh { constructor(geometry, material) { super(geometry, material); this.type = "SkinnedMesh"; this.bindMode = "attached"; this.bindMatrix = new Matrix4(); this.bindMatrixInverse = new Matrix4(); } copy(source) { super.copy(source); this.bindMode = source.bindMode; this.bindMatrix.copy(source.bindMatrix); this.bindMatrixInverse.copy(source.bindMatrixInverse); this.skeleton = source.skeleton; return this; } bind(skeleton, bindMatrix) { this.skeleton = skeleton; if (bindMatrix === void 0) { this.updateMatrixWorld(true); this.skeleton.calculateInverses(); bindMatrix = this.matrixWorld; } this.bindMatrix.copy(bindMatrix); this.bindMatrixInverse.copy(bindMatrix).invert(); } pose() { this.skeleton.pose(); } normalizeSkinWeights() { const vector = new Vector4(); const skinWeight = this.geometry.attributes.skinWeight; for (let i = 0, l = skinWeight.count; i < l; i++) { vector.x = skinWeight.getX(i); vector.y = skinWeight.getY(i); vector.z = skinWeight.getZ(i); vector.w = skinWeight.getW(i); const scale = 1 / vector.manhattanLength(); if (scale !== Infinity) { vector.multiplyScalar(scale); } else { vector.set(1, 0, 0, 0); } skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w); } } updateMatrixWorld(force) { super.updateMatrixWorld(force); if (this.bindMode === "attached") { this.bindMatrixInverse.copy(this.matrixWorld).invert(); } else if (this.bindMode === "detached") { this.bindMatrixInverse.copy(this.bindMatrix).invert(); } else { console.warn("THREE.SkinnedMesh: Unrecognized bindMode: " + this.bindMode); } } boneTransform(index, target) { const skeleton = this.skeleton; const geometry = this.geometry; _skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index); _skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index); _basePosition.fromBufferAttribute(geometry.attributes.position, index).applyMatrix4(this.bindMatrix); target.set(0, 0, 0); for (let i = 0; i < 4; i++) { const weight = _skinWeight.getComponent(i); if (weight !== 0) { const boneIndex = _skinIndex.getComponent(i); _matrix.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]); target.addScaledVector(_vector$5.copy(_basePosition).applyMatrix4(_matrix), weight); } } return target.applyMatrix4(this.bindMatrixInverse); } }; SkinnedMesh.prototype.isSkinnedMesh = true; var Bone = class extends Object3D { constructor() { super(); this.type = "Bone"; } }; Bone.prototype.isBone = true; var DataTexture = class extends Texture { constructor(data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, encoding) { super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); this.image = { data, width, height }; this.magFilter = magFilter; this.minFilter = minFilter; this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; this.needsUpdate = true; } }; DataTexture.prototype.isDataTexture = true; var InstancedBufferAttribute = class extends BufferAttribute { constructor(array, itemSize, normalized, meshPerAttribute = 1) { if (typeof normalized === "number") { meshPerAttribute = normalized; normalized = false; console.error("THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument."); } super(array, itemSize, normalized); this.meshPerAttribute = meshPerAttribute; } copy(source) { super.copy(source); this.meshPerAttribute = source.meshPerAttribute; return this; } toJSON() { const data = super.toJSON(); data.meshPerAttribute = this.meshPerAttribute; data.isInstancedBufferAttribute = true; return data; } }; InstancedBufferAttribute.prototype.isInstancedBufferAttribute = true; var _instanceLocalMatrix = /* @__PURE__ */ new Matrix4(); var _instanceWorldMatrix = /* @__PURE__ */ new Matrix4(); var _instanceIntersects = []; var _mesh = /* @__PURE__ */ new Mesh(); var InstancedMesh = class extends Mesh { constructor(geometry, material, count) { super(geometry, material); this.instanceMatrix = new InstancedBufferAttribute(new Float32Array(count * 16), 16); this.instanceColor = null; this.count = count; this.frustumCulled = false; } copy(source) { super.copy(source); this.instanceMatrix.copy(source.instanceMatrix); if (source.instanceColor !== null) this.instanceColor = source.instanceColor.clone(); this.count = source.count; return this; } getColorAt(index, color) { color.fromArray(this.instanceColor.array, index * 3); } getMatrixAt(index, matrix) { matrix.fromArray(this.instanceMatrix.array, index * 16); } raycast(raycaster, intersects2) { const matrixWorld = this.matrixWorld; const raycastTimes = this.count; _mesh.geometry = this.geometry; _mesh.material = this.material; if (_mesh.material === void 0) return; for (let instanceId = 0; instanceId < raycastTimes; instanceId++) { this.getMatrixAt(instanceId, _instanceLocalMatrix); _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); _mesh.matrixWorld = _instanceWorldMatrix; _mesh.raycast(raycaster, _instanceIntersects); for (let i = 0, l = _instanceIntersects.length; i < l; i++) { const intersect2 = _instanceIntersects[i]; intersect2.instanceId = instanceId; intersect2.object = this; intersects2.push(intersect2); } _instanceIntersects.length = 0; } } setColorAt(index, color) { if (this.instanceColor === null) { this.instanceColor = new InstancedBufferAttribute(new Float32Array(this.instanceMatrix.count * 3), 3); } color.toArray(this.instanceColor.array, index * 3); } setMatrixAt(index, matrix) { matrix.toArray(this.instanceMatrix.array, index * 16); } updateMorphTargets() { } dispose() { this.dispatchEvent({ type: "dispose" }); } }; InstancedMesh.prototype.isInstancedMesh = true; var LineBasicMaterial = class extends Material { constructor(parameters) { super(); this.type = "LineBasicMaterial"; this.color = new Color(16777215); this.linewidth = 1; this.linecap = "round"; this.linejoin = "round"; this.setValues(parameters); } copy(source) { super.copy(source); this.color.copy(source.color); this.linewidth = source.linewidth; this.linecap = source.linecap; this.linejoin = source.linejoin; return this; } }; LineBasicMaterial.prototype.isLineBasicMaterial = true; var _start$1 = /* @__PURE__ */ new Vector3(); var _end$1 = /* @__PURE__ */ new Vector3(); var _inverseMatrix$1 = /* @__PURE__ */ new Matrix4(); var _ray$1 = /* @__PURE__ */ new Ray(); var _sphere$1 = /* @__PURE__ */ new Sphere(); var Line = class extends Object3D { constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()) { super(); this.type = "Line"; this.geometry = geometry; this.material = material; this.updateMorphTargets(); } copy(source) { super.copy(source); this.material = source.material; this.geometry = source.geometry; return this; } computeLineDistances() { const geometry = this.geometry; if (geometry.isBufferGeometry) { if (geometry.index === null) { const positionAttribute = geometry.attributes.position; const lineDistances = [0]; for (let i = 1, l = positionAttribute.count; i < l; i++) { _start$1.fromBufferAttribute(positionAttribute, i - 1); _end$1.fromBufferAttribute(positionAttribute, i); lineDistances[i] = lineDistances[i - 1]; lineDistances[i] += _start$1.distanceTo(_end$1); } geometry.setAttribute("lineDistance", new Float32BufferAttribute(lineDistances, 1)); } else { console.warn("THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry."); } } else if (geometry.isGeometry) { console.error("THREE.Line.computeLineDistances() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead."); } return this; } raycast(raycaster, intersects2) { const geometry = this.geometry; const matrixWorld = this.matrixWorld; const threshold = raycaster.params.Line.threshold; const drawRange = geometry.drawRange; if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$1.copy(geometry.boundingSphere); _sphere$1.applyMatrix4(matrixWorld); _sphere$1.radius += threshold; if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; _inverseMatrix$1.copy(matrixWorld).invert(); _ray$1.copy(raycaster.ray).applyMatrix4(_inverseMatrix$1); const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); const localThresholdSq = localThreshold * localThreshold; const vStart = new Vector3(); const vEnd = new Vector3(); const interSegment = new Vector3(); const interRay = new Vector3(); const step = this.isLineSegments ? 2 : 1; if (geometry.isBufferGeometry) { const index = geometry.index; const attributes = geometry.attributes; const positionAttribute = attributes.position; if (index !== null) { const start = Math.max(0, drawRange.start); const end = Math.min(index.count, drawRange.start + drawRange.count); for (let i = start, l = end - 1; i < l; i += step) { const a2 = index.getX(i); const b2 = index.getX(i + 1); vStart.fromBufferAttribute(positionAttribute, a2); vEnd.fromBufferAttribute(positionAttribute, b2); const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); if (distSq > localThresholdSq) continue; interRay.applyMatrix4(this.matrixWorld); const distance = raycaster.ray.origin.distanceTo(interRay); if (distance < raycaster.near || distance > raycaster.far) continue; intersects2.push({ distance, point: interSegment.clone().applyMatrix4(this.matrixWorld), index: i, face: null, faceIndex: null, object: this }); } } else { const start = Math.max(0, drawRange.start); const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); for (let i = start, l = end - 1; i < l; i += step) { vStart.fromBufferAttribute(positionAttribute, i); vEnd.fromBufferAttribute(positionAttribute, i + 1); const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment); if (distSq > localThresholdSq) continue; interRay.applyMatrix4(this.matrixWorld); const distance = raycaster.ray.origin.distanceTo(interRay); if (distance < raycaster.near || distance > raycaster.far) continue; intersects2.push({ distance, point: interSegment.clone().applyMatrix4(this.matrixWorld), index: i, face: null, faceIndex: null, object: this }); } } } else if (geometry.isGeometry) { console.error("THREE.Line.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead."); } } updateMorphTargets() { const geometry = this.geometry; if (geometry.isBufferGeometry) { const morphAttributes = geometry.morphAttributes; const keys = Object.keys(morphAttributes); if (keys.length > 0) { const morphAttribute = morphAttributes[keys[0]]; if (morphAttribute !== void 0) { this.morphTargetInfluences = []; this.morphTargetDictionary = {}; for (let m = 0, ml = morphAttribute.length; m < ml; m++) { const name = morphAttribute[m].name || String(m); this.morphTargetInfluences.push(0); this.morphTargetDictionary[name] = m; } } } } else { const morphTargets = geometry.morphTargets; if (morphTargets !== void 0 && morphTargets.length > 0) { console.error("THREE.Line.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead."); } } } }; Line.prototype.isLine = true; var _start = /* @__PURE__ */ new Vector3(); var _end = /* @__PURE__ */ new Vector3(); var LineSegments = class extends Line { constructor(geometry, material) { super(geometry, material); this.type = "LineSegments"; } computeLineDistances() { const geometry = this.geometry; if (geometry.isBufferGeometry) { if (geometry.index === null) { const positionAttribute = geometry.attributes.position; const lineDistances = []; for (let i = 0, l = positionAttribute.count; i < l; i += 2) { _start.fromBufferAttribute(positionAttribute, i); _end.fromBufferAttribute(positionAttribute, i + 1); lineDistances[i] = i === 0 ? 0 : lineDistances[i - 1]; lineDistances[i + 1] = lineDistances[i] + _start.distanceTo(_end); } geometry.setAttribute("lineDistance", new Float32BufferAttribute(lineDistances, 1)); } else { console.warn("THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry."); } } else if (geometry.isGeometry) { console.error("THREE.LineSegments.computeLineDistances() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead."); } return this; } }; LineSegments.prototype.isLineSegments = true; var LineLoop = class extends Line { constructor(geometry, material) { super(geometry, material); this.type = "LineLoop"; } }; LineLoop.prototype.isLineLoop = true; var PointsMaterial = class extends Material { constructor(parameters) { super(); this.type = "PointsMaterial"; this.color = new Color(16777215); this.map = null; this.alphaMap = null; this.size = 1; this.sizeAttenuation = true; this.setValues(parameters); } copy(source) { super.copy(source); this.color.copy(source.color); this.map = source.map; this.alphaMap = source.alphaMap; this.size = source.size; this.sizeAttenuation = source.sizeAttenuation; return this; } }; PointsMaterial.prototype.isPointsMaterial = true; var _inverseMatrix = /* @__PURE__ */ new Matrix4(); var _ray = /* @__PURE__ */ new Ray(); var _sphere = /* @__PURE__ */ new Sphere(); var _position$2 = /* @__PURE__ */ new Vector3(); var Points = class extends Object3D { constructor(geometry = new BufferGeometry(), material = new PointsMaterial()) { super(); this.type = "Points"; this.geometry = geometry; this.material = material; this.updateMorphTargets(); } copy(source) { super.copy(source); this.material = source.material; this.geometry = source.geometry; return this; } raycast(raycaster, intersects2) { const geometry = this.geometry; const matrixWorld = this.matrixWorld; const threshold = raycaster.params.Points.threshold; const drawRange = geometry.drawRange; if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere.copy(geometry.boundingSphere); _sphere.applyMatrix4(matrixWorld); _sphere.radius += threshold; if (raycaster.ray.intersectsSphere(_sphere) === false) return; _inverseMatrix.copy(matrixWorld).invert(); _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix); const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3); const localThresholdSq = localThreshold * localThreshold; if (geometry.isBufferGeometry) { const index = geometry.index; const attributes = geometry.attributes; const positionAttribute = attributes.position; if (index !== null) { const start = Math.max(0, drawRange.start); const end = Math.min(index.count, drawRange.start + drawRange.count); for (let i = start, il = end; i < il; i++) { const a2 = index.getX(i); _position$2.fromBufferAttribute(positionAttribute, a2); testPoint(_position$2, a2, localThresholdSq, matrixWorld, raycaster, intersects2, this); } } else { const start = Math.max(0, drawRange.start); const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count); for (let i = start, l = end; i < l; i++) { _position$2.fromBufferAttribute(positionAttribute, i); testPoint(_position$2, i, localThresholdSq, matrixWorld, raycaster, intersects2, this); } } } else { console.error("THREE.Points.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead."); } } updateMorphTargets() { const geometry = this.geometry; if (geometry.isBufferGeometry) { const morphAttributes = geometry.morphAttributes; const keys = Object.keys(morphAttributes); if (keys.length > 0) { const morphAttribute = morphAttributes[keys[0]]; if (morphAttribute !== void 0) { this.morphTargetInfluences = []; this.morphTargetDictionary = {}; for (let m = 0, ml = morphAttribute.length; m < ml; m++) { const name = morphAttribute[m].name || String(m); this.morphTargetInfluences.push(0); this.morphTargetDictionary[name] = m; } } } } else { const morphTargets = geometry.morphTargets; if (morphTargets !== void 0 && morphTargets.length > 0) { console.error("THREE.Points.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead."); } } } }; Points.prototype.isPoints = true; function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects2, object) { const rayPointDistanceSq = _ray.distanceSqToPoint(point); if (rayPointDistanceSq < localThresholdSq) { const intersectPoint2 = new Vector3(); _ray.closestPointToPoint(point, intersectPoint2); intersectPoint2.applyMatrix4(matrixWorld); const distance = raycaster.ray.origin.distanceTo(intersectPoint2); if (distance < raycaster.near || distance > raycaster.far) return; intersects2.push({ distance, distanceToRay: Math.sqrt(rayPointDistanceSq), point: intersectPoint2, index, face: null, object }); } } var VideoTexture = class extends Texture { constructor(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) { super(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); this.format = format !== void 0 ? format : RGBFormat; this.minFilter = minFilter !== void 0 ? minFilter : LinearFilter; this.magFilter = magFilter !== void 0 ? magFilter : LinearFilter; this.generateMipmaps = false; const scope = this; function updateVideo() { scope.needsUpdate = true; video.requestVideoFrameCallback(updateVideo); } if ("requestVideoFrameCallback" in video) { video.requestVideoFrameCallback(updateVideo); } } clone() { return new this.constructor(this.image).copy(this); } update() { const video = this.image; const hasVideoFrameCallback = "requestVideoFrameCallback" in video; if (hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA) { this.needsUpdate = true; } } }; VideoTexture.prototype.isVideoTexture = true; var CompressedTexture = class extends Texture { constructor(mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding) { super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding); this.image = { width, height }; this.mipmaps = mipmaps; this.flipY = false; this.generateMipmaps = false; } }; CompressedTexture.prototype.isCompressedTexture = true; var CanvasTexture = class extends Texture { constructor(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) { super(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); this.needsUpdate = true; } }; CanvasTexture.prototype.isCanvasTexture = true; var DepthTexture = class extends Texture { constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format) { format = format !== void 0 ? format : DepthFormat; if (format !== DepthFormat && format !== DepthStencilFormat) { throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat"); } if (type === void 0 && format === DepthFormat) type = UnsignedShortType; if (type === void 0 && format === DepthStencilFormat) type = UnsignedInt248Type; super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy); this.image = { width, height }; this.magFilter = magFilter !== void 0 ? magFilter : NearestFilter; this.minFilter = minFilter !== void 0 ? minFilter : NearestFilter; this.flipY = false; this.generateMipmaps = false; } }; DepthTexture.prototype.isDepthTexture = true; var _v0 = new Vector3(); var _v1$1 = new Vector3(); var _normal = new Vector3(); var _triangle = new Triangle(); var Curve = class { constructor() { this.type = "Curve"; this.arcLengthDivisions = 200; } getPoint() { console.warn("THREE.Curve: .getPoint() not implemented."); return null; } getPointAt(u, optionalTarget) { const t = this.getUtoTmapping(u); return this.getPoint(t, optionalTarget); } getPoints(divisions = 5) { const points = []; for (let d = 0; d <= divisions; d++) { points.push(this.getPoint(d / divisions)); } return points; } getSpacedPoints(divisions = 5) { const points = []; for (let d = 0; d <= divisions; d++) { points.push(this.getPointAt(d / divisions)); } return points; } getLength() { const lengths = this.getLengths(); return lengths[lengths.length - 1]; } getLengths(divisions = this.arcLengthDivisions) { if (this.cacheArcLengths && this.cacheArcLengths.length === divisions + 1 && !this.needsUpdate) { return this.cacheArcLengths; } this.needsUpdate = false; const cache = []; let current, last = this.getPoint(0); let sum = 0; cache.push(0); for (let p2 = 1; p2 <= divisions; p2++) { current = this.getPoint(p2 / divisions); sum += current.distanceTo(last); cache.push(sum); last = current; } this.cacheArcLengths = cache; return cache; } updateArcLengths() { this.needsUpdate = true; this.getLengths(); } getUtoTmapping(u, distance) { const arcLengths = this.getLengths(); let i = 0; const il = arcLengths.length; let targetArcLength; if (distance) { targetArcLength = distance; } else { targetArcLength = u * arcLengths[il - 1]; } let low = 0, high = il - 1, comparison; while (low <= high) { i = Math.floor(low + (high - low) / 2); comparison = arcLengths[i] - targetArcLength; if (comparison < 0) { low = i + 1; } else if (comparison > 0) { high = i - 1; } else { high = i; break; } } i = high; if (arcLengths[i] === targetArcLength) { return i / (il - 1); } const lengthBefore = arcLengths[i]; const lengthAfter = arcLengths[i + 1]; const segmentLength = lengthAfter - lengthBefore; const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; const t = (i + segmentFraction) / (il - 1); return t; } getTangent(t, optionalTarget) { const delta = 1e-4; let t1 = t - delta; let t2 = t + delta; if (t1 < 0) t1 = 0; if (t2 > 1) t2 = 1; const pt1 = this.getPoint(t1); const pt2 = this.getPoint(t2); const tangent = optionalTarget || (pt1.isVector2 ? new Vector2() : new Vector3()); tangent.copy(pt2).sub(pt1).normalize(); return tangent; } getTangentAt(u, optionalTarget) { const t = this.getUtoTmapping(u); return this.getTangent(t, optionalTarget); } computeFrenetFrames(segments, closed) { const normal = new Vector3(); const tangents = []; const normals = []; const binormals = []; const vec = new Vector3(); const mat = new Matrix4(); for (let i = 0; i <= segments; i++) { const u = i / segments; tangents[i] = this.getTangentAt(u, new Vector3()); tangents[i].normalize(); } normals[0] = new Vector3(); binormals[0] = new Vector3(); let min = Number.MAX_VALUE; const tx = Math.abs(tangents[0].x); const ty = Math.abs(tangents[0].y); const tz = Math.abs(tangents[0].z); if (tx <= min) { min = tx; normal.set(1, 0, 0); } if (ty <= min) { min = ty; normal.set(0, 1, 0); } if (tz <= min) { normal.set(0, 0, 1); } vec.crossVectors(tangents[0], normal).normalize(); normals[0].crossVectors(tangents[0], vec); binormals[0].crossVectors(tangents[0], normals[0]); for (let i = 1; i <= segments; i++) { normals[i] = normals[i - 1].clone(); binormals[i] = binormals[i - 1].clone(); vec.crossVectors(tangents[i - 1], tangents[i]); if (vec.length() > Number.EPSILON) { vec.normalize(); const theta = Math.acos(clamp(tangents[i - 1].dot(tangents[i]), -1, 1)); normals[i].applyMatrix4(mat.makeRotationAxis(vec, theta)); } binormals[i].crossVectors(tangents[i], normals[i]); } if (closed === true) { let theta = Math.acos(clamp(normals[0].dot(normals[segments]), -1, 1)); theta /= segments; if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) { theta = -theta; } for (let i = 1; i <= segments; i++) { normals[i].applyMatrix4(mat.makeRotationAxis(tangents[i], theta * i)); binormals[i].crossVectors(tangents[i], normals[i]); } } return { tangents, normals, binormals }; } clone() { return new this.constructor().copy(this); } copy(source) { this.arcLengthDivisions = source.arcLengthDivisions; return this; } toJSON() { const data = { metadata: { version: 4.5, type: "Curve", generator: "Curve.toJSON" } }; data.arcLengthDivisions = this.arcLengthDivisions; data.type = this.type; return data; } fromJSON(json) { this.arcLengthDivisions = json.arcLengthDivisions; return this; } }; var EllipseCurve = class extends Curve { constructor(aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0) { super(); this.type = "EllipseCurve"; this.aX = aX; this.aY = aY; this.xRadius = xRadius; this.yRadius = yRadius; this.aStartAngle = aStartAngle; this.aEndAngle = aEndAngle; this.aClockwise = aClockwise; this.aRotation = aRotation; } getPoint(t, optionalTarget) { const point = optionalTarget || new Vector2(); const twoPi = Math.PI * 2; let deltaAngle = this.aEndAngle - this.aStartAngle; const samePoints = Math.abs(deltaAngle) < Number.EPSILON; while (deltaAngle < 0) deltaAngle += twoPi; while (deltaAngle > twoPi) deltaAngle -= twoPi; if (deltaAngle < Number.EPSILON) { if (samePoints) { deltaAngle = 0; } else { deltaAngle = twoPi; } } if (this.aClockwise === true && !samePoints) { if (deltaAngle === twoPi) { deltaAngle = -twoPi; } else { deltaAngle = deltaAngle - twoPi; } } const angle = this.aStartAngle + t * deltaAngle; let x = this.aX + this.xRadius * Math.cos(angle); let y = this.aY + this.yRadius * Math.sin(angle); if (this.aRotation !== 0) { const cos = Math.cos(this.aRotation); const sin = Math.sin(this.aRotation); const tx = x - this.aX; const ty = y - this.aY; x = tx * cos - ty * sin + this.aX; y = tx * sin + ty * cos + this.aY; } return point.set(x, y); } copy(source) { super.copy(source); this.aX = source.aX; this.aY = source.aY; this.xRadius = source.xRadius; this.yRadius = source.yRadius; this.aStartAngle = source.aStartAngle; this.aEndAngle = source.aEndAngle; this.aClockwise = source.aClockwise; this.aRotation = source.aRotation; return this; } toJSON() { const data = super.toJSON(); data.aX = this.aX; data.aY = this.aY; data.xRadius = this.xRadius; data.yRadius = this.yRadius; data.aStartAngle = this.aStartAngle; data.aEndAngle = this.aEndAngle; data.aClockwise = this.aClockwise; data.aRotation = this.aRotation; return data; } fromJSON(json) { super.fromJSON(json); this.aX = json.aX; this.aY = json.aY; this.xRadius = json.xRadius; this.yRadius = json.yRadius; this.aStartAngle = json.aStartAngle; this.aEndAngle = json.aEndAngle; this.aClockwise = json.aClockwise; this.aRotation = json.aRotation; return this; } }; EllipseCurve.prototype.isEllipseCurve = true; var ArcCurve = class extends EllipseCurve { constructor(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { super(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); this.type = "ArcCurve"; } }; ArcCurve.prototype.isArcCurve = true; function CubicPoly() { let c0 = 0, c1 = 0, c2 = 0, c3 = 0; function init(x0, x1, t0, t1) { c0 = x0; c1 = t0; c2 = -3 * x0 + 3 * x1 - 2 * t0 - t1; c3 = 2 * x0 - 2 * x1 + t0 + t1; } return { initCatmullRom: function(x0, x1, x2, x3, tension) { init(x1, x2, tension * (x2 - x0), tension * (x3 - x1)); }, initNonuniformCatmullRom: function(x0, x1, x2, x3, dt0, dt1, dt2) { let t1 = (x1 - x0) / dt0 - (x2 - x0) / (dt0 + dt1) + (x2 - x1) / dt1; let t2 = (x2 - x1) / dt1 - (x3 - x1) / (dt1 + dt2) + (x3 - x2) / dt2; t1 *= dt1; t2 *= dt1; init(x1, x2, t1, t2); }, calc: function(t) { const t2 = t * t; const t3 = t2 * t; return c0 + c1 * t + c2 * t2 + c3 * t3; } }; } var tmp = new Vector3(); var px = new CubicPoly(); var py = new CubicPoly(); var pz = new CubicPoly(); var CatmullRomCurve3 = class extends Curve { constructor(points = [], closed = false, curveType = "centripetal", tension = 0.5) { super(); this.type = "CatmullRomCurve3"; this.points = points; this.closed = closed; this.curveType = curveType; this.tension = tension; } getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const points = this.points; const l = points.length; const p2 = (l - (this.closed ? 0 : 1)) * t; let intPoint = Math.floor(p2); let weight = p2 - intPoint; if (this.closed) { intPoint += intPoint > 0 ? 0 : (Math.floor(Math.abs(intPoint) / l) + 1) * l; } else if (weight === 0 && intPoint === l - 1) { intPoint = l - 2; weight = 1; } let p0, p3; if (this.closed || intPoint > 0) { p0 = points[(intPoint - 1) % l]; } else { tmp.subVectors(points[0], points[1]).add(points[0]); p0 = tmp; } const p1 = points[intPoint % l]; const p22 = points[(intPoint + 1) % l]; if (this.closed || intPoint + 2 < l) { p3 = points[(intPoint + 2) % l]; } else { tmp.subVectors(points[l - 1], points[l - 2]).add(points[l - 1]); p3 = tmp; } if (this.curveType === "centripetal" || this.curveType === "chordal") { const pow = this.curveType === "chordal" ? 0.5 : 0.25; let dt0 = Math.pow(p0.distanceToSquared(p1), pow); let dt1 = Math.pow(p1.distanceToSquared(p22), pow); let dt2 = Math.pow(p22.distanceToSquared(p3), pow); if (dt1 < 1e-4) dt1 = 1; if (dt0 < 1e-4) dt0 = dt1; if (dt2 < 1e-4) dt2 = dt1; px.initNonuniformCatmullRom(p0.x, p1.x, p22.x, p3.x, dt0, dt1, dt2); py.initNonuniformCatmullRom(p0.y, p1.y, p22.y, p3.y, dt0, dt1, dt2); pz.initNonuniformCatmullRom(p0.z, p1.z, p22.z, p3.z, dt0, dt1, dt2); } else if (this.curveType === "catmullrom") { px.initCatmullRom(p0.x, p1.x, p22.x, p3.x, this.tension); py.initCatmullRom(p0.y, p1.y, p22.y, p3.y, this.tension); pz.initCatmullRom(p0.z, p1.z, p22.z, p3.z, this.tension); } point.set(px.calc(weight), py.calc(weight), pz.calc(weight)); return point; } copy(source) { super.copy(source); this.points = []; for (let i = 0, l = source.points.length; i < l; i++) { const point = source.points[i]; this.points.push(point.clone()); } this.closed = source.closed; this.curveType = source.curveType; this.tension = source.tension; return this; } toJSON() { const data = super.toJSON(); data.points = []; for (let i = 0, l = this.points.length; i < l; i++) { const point = this.points[i]; data.points.push(point.toArray()); } data.closed = this.closed; data.curveType = this.curveType; data.tension = this.tension; return data; } fromJSON(json) { super.fromJSON(json); this.points = []; for (let i = 0, l = json.points.length; i < l; i++) { const point = json.points[i]; this.points.push(new Vector3().fromArray(point)); } this.closed = json.closed; this.curveType = json.curveType; this.tension = json.tension; return this; } }; CatmullRomCurve3.prototype.isCatmullRomCurve3 = true; function CatmullRom(t, p0, p1, p2, p3) { const v02 = (p2 - p0) * 0.5; const v12 = (p3 - p1) * 0.5; const t2 = t * t; const t3 = t * t2; return (2 * p1 - 2 * p2 + v02 + v12) * t3 + (-3 * p1 + 3 * p2 - 2 * v02 - v12) * t2 + v02 * t + p1; } function QuadraticBezierP0(t, p2) { const k = 1 - t; return k * k * p2; } function QuadraticBezierP1(t, p2) { return 2 * (1 - t) * t * p2; } function QuadraticBezierP2(t, p2) { return t * t * p2; } function QuadraticBezier(t, p0, p1, p2) { return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) + QuadraticBezierP2(t, p2); } function CubicBezierP0(t, p2) { const k = 1 - t; return k * k * k * p2; } function CubicBezierP1(t, p2) { const k = 1 - t; return 3 * k * k * t * p2; } function CubicBezierP2(t, p2) { return 3 * (1 - t) * t * t * p2; } function CubicBezierP3(t, p2) { return t * t * t * p2; } function CubicBezier(t, p0, p1, p2, p3) { return CubicBezierP0(t, p0) + CubicBezierP1(t, p1) + CubicBezierP2(t, p2) + CubicBezierP3(t, p3); } var CubicBezierCurve = class extends Curve { constructor(v02 = new Vector2(), v12 = new Vector2(), v22 = new Vector2(), v3 = new Vector2()) { super(); this.type = "CubicBezierCurve"; this.v0 = v02; this.v1 = v12; this.v2 = v22; this.v3 = v3; } getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const v02 = this.v0, v12 = this.v1, v22 = this.v2, v3 = this.v3; point.set(CubicBezier(t, v02.x, v12.x, v22.x, v3.x), CubicBezier(t, v02.y, v12.y, v22.y, v3.y)); return point; } copy(source) { super.copy(source); this.v0.copy(source.v0); this.v1.copy(source.v1); this.v2.copy(source.v2); this.v3.copy(source.v3); return this; } toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); data.v1 = this.v1.toArray(); data.v2 = this.v2.toArray(); data.v3 = this.v3.toArray(); return data; } fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); this.v1.fromArray(json.v1); this.v2.fromArray(json.v2); this.v3.fromArray(json.v3); return this; } }; CubicBezierCurve.prototype.isCubicBezierCurve = true; var CubicBezierCurve3 = class extends Curve { constructor(v02 = new Vector3(), v12 = new Vector3(), v22 = new Vector3(), v3 = new Vector3()) { super(); this.type = "CubicBezierCurve3"; this.v0 = v02; this.v1 = v12; this.v2 = v22; this.v3 = v3; } getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const v02 = this.v0, v12 = this.v1, v22 = this.v2, v3 = this.v3; point.set(CubicBezier(t, v02.x, v12.x, v22.x, v3.x), CubicBezier(t, v02.y, v12.y, v22.y, v3.y), CubicBezier(t, v02.z, v12.z, v22.z, v3.z)); return point; } copy(source) { super.copy(source); this.v0.copy(source.v0); this.v1.copy(source.v1); this.v2.copy(source.v2); this.v3.copy(source.v3); return this; } toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); data.v1 = this.v1.toArray(); data.v2 = this.v2.toArray(); data.v3 = this.v3.toArray(); return data; } fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); this.v1.fromArray(json.v1); this.v2.fromArray(json.v2); this.v3.fromArray(json.v3); return this; } }; CubicBezierCurve3.prototype.isCubicBezierCurve3 = true; var LineCurve = class extends Curve { constructor(v12 = new Vector2(), v22 = new Vector2()) { super(); this.type = "LineCurve"; this.v1 = v12; this.v2 = v22; } getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; if (t === 1) { point.copy(this.v2); } else { point.copy(this.v2).sub(this.v1); point.multiplyScalar(t).add(this.v1); } return point; } getPointAt(u, optionalTarget) { return this.getPoint(u, optionalTarget); } getTangent(t, optionalTarget) { const tangent = optionalTarget || new Vector2(); tangent.copy(this.v2).sub(this.v1).normalize(); return tangent; } copy(source) { super.copy(source); this.v1.copy(source.v1); this.v2.copy(source.v2); return this; } toJSON() { const data = super.toJSON(); data.v1 = this.v1.toArray(); data.v2 = this.v2.toArray(); return data; } fromJSON(json) { super.fromJSON(json); this.v1.fromArray(json.v1); this.v2.fromArray(json.v2); return this; } }; LineCurve.prototype.isLineCurve = true; var LineCurve3 = class extends Curve { constructor(v12 = new Vector3(), v22 = new Vector3()) { super(); this.type = "LineCurve3"; this.isLineCurve3 = true; this.v1 = v12; this.v2 = v22; } getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; if (t === 1) { point.copy(this.v2); } else { point.copy(this.v2).sub(this.v1); point.multiplyScalar(t).add(this.v1); } return point; } getPointAt(u, optionalTarget) { return this.getPoint(u, optionalTarget); } copy(source) { super.copy(source); this.v1.copy(source.v1); this.v2.copy(source.v2); return this; } toJSON() { const data = super.toJSON(); data.v1 = this.v1.toArray(); data.v2 = this.v2.toArray(); return data; } fromJSON(json) { super.fromJSON(json); this.v1.fromArray(json.v1); this.v2.fromArray(json.v2); return this; } }; var QuadraticBezierCurve = class extends Curve { constructor(v02 = new Vector2(), v12 = new Vector2(), v22 = new Vector2()) { super(); this.type = "QuadraticBezierCurve"; this.v0 = v02; this.v1 = v12; this.v2 = v22; } getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const v02 = this.v0, v12 = this.v1, v22 = this.v2; point.set(QuadraticBezier(t, v02.x, v12.x, v22.x), QuadraticBezier(t, v02.y, v12.y, v22.y)); return point; } copy(source) { super.copy(source); this.v0.copy(source.v0); this.v1.copy(source.v1); this.v2.copy(source.v2); return this; } toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); data.v1 = this.v1.toArray(); data.v2 = this.v2.toArray(); return data; } fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); this.v1.fromArray(json.v1); this.v2.fromArray(json.v2); return this; } }; QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true; var QuadraticBezierCurve3 = class extends Curve { constructor(v02 = new Vector3(), v12 = new Vector3(), v22 = new Vector3()) { super(); this.type = "QuadraticBezierCurve3"; this.v0 = v02; this.v1 = v12; this.v2 = v22; } getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const v02 = this.v0, v12 = this.v1, v22 = this.v2; point.set(QuadraticBezier(t, v02.x, v12.x, v22.x), QuadraticBezier(t, v02.y, v12.y, v22.y), QuadraticBezier(t, v02.z, v12.z, v22.z)); return point; } copy(source) { super.copy(source); this.v0.copy(source.v0); this.v1.copy(source.v1); this.v2.copy(source.v2); return this; } toJSON() { const data = super.toJSON(); data.v0 = this.v0.toArray(); data.v1 = this.v1.toArray(); data.v2 = this.v2.toArray(); return data; } fromJSON(json) { super.fromJSON(json); this.v0.fromArray(json.v0); this.v1.fromArray(json.v1); this.v2.fromArray(json.v2); return this; } }; QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true; var SplineCurve = class extends Curve { constructor(points = []) { super(); this.type = "SplineCurve"; this.points = points; } getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const points = this.points; const p2 = (points.length - 1) * t; const intPoint = Math.floor(p2); const weight = p2 - intPoint; const p0 = points[intPoint === 0 ? intPoint : intPoint - 1]; const p1 = points[intPoint]; const p22 = points[intPoint > points.length - 2 ? points.length - 1 : intPoint + 1]; const p3 = points[intPoint > points.length - 3 ? points.length - 1 : intPoint + 2]; point.set(CatmullRom(weight, p0.x, p1.x, p22.x, p3.x), CatmullRom(weight, p0.y, p1.y, p22.y, p3.y)); return point; } copy(source) { super.copy(source); this.points = []; for (let i = 0, l = source.points.length; i < l; i++) { const point = source.points[i]; this.points.push(point.clone()); } return this; } toJSON() { const data = super.toJSON(); data.points = []; for (let i = 0, l = this.points.length; i < l; i++) { const point = this.points[i]; data.points.push(point.toArray()); } return data; } fromJSON(json) { super.fromJSON(json); this.points = []; for (let i = 0, l = json.points.length; i < l; i++) { const point = json.points[i]; this.points.push(new Vector2().fromArray(point)); } return this; } }; SplineCurve.prototype.isSplineCurve = true; var Curves = /* @__PURE__ */ Object.freeze({ __proto__: null, ArcCurve, CatmullRomCurve3, CubicBezierCurve, CubicBezierCurve3, EllipseCurve, LineCurve, LineCurve3, QuadraticBezierCurve, QuadraticBezierCurve3, SplineCurve }); var Earcut = { triangulate: function(data, holeIndices, dim = 2) { const hasHoles = holeIndices && holeIndices.length; const outerLen = hasHoles ? holeIndices[0] * dim : data.length; let outerNode = linkedList(data, 0, outerLen, dim, true); const triangles = []; if (!outerNode || outerNode.next === outerNode.prev) return triangles; let minX, minY, maxX, maxY, x, y, invSize; if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); if (data.length > 80 * dim) { minX = maxX = data[0]; minY = maxY = data[1]; for (let i = dim; i < outerLen; i += dim) { x = data[i]; y = data[i + 1]; if (x < minX) minX = x; if (y < minY) minY = y; if (x > maxX) maxX = x; if (y > maxY) maxY = y; } invSize = Math.max(maxX - minX, maxY - minY); invSize = invSize !== 0 ? 1 / invSize : 0; } earcutLinked(outerNode, triangles, dim, minX, minY, invSize); return triangles; } }; function linkedList(data, start, end, dim, clockwise) { let i, last; if (clockwise === signedArea(data, start, end, dim) > 0) { for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); } else { for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); } if (last && equals(last, last.next)) { removeNode(last); last = last.next; } return last; } function filterPoints(start, end) { if (!start) return start; if (!end) end = start; let p2 = start, again; do { again = false; if (!p2.steiner && (equals(p2, p2.next) || area(p2.prev, p2, p2.next) === 0)) { removeNode(p2); p2 = end = p2.prev; if (p2 === p2.next) break; again = true; } else { p2 = p2.next; } } while (again || p2 !== end); return end; } function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) { if (!ear) return; if (!pass && invSize) indexCurve(ear, minX, minY, invSize); let stop = ear, prev, next; while (ear.prev !== ear.next) { prev = ear.prev; next = ear.next; if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) { triangles.push(prev.i / dim); triangles.push(ear.i / dim); triangles.push(next.i / dim); removeNode(ear); ear = next.next; stop = next.next; continue; } ear = next; if (ear === stop) { if (!pass) { earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); } else if (pass === 1) { ear = cureLocalIntersections(filterPoints(ear), triangles, dim); earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); } else if (pass === 2) { splitEarcut(ear, triangles, dim, minX, minY, invSize); } break; } } } function isEar(ear) { const a2 = ear.prev, b2 = ear, c2 = ear.next; if (area(a2, b2, c2) >= 0) return false; let p2 = ear.next.next; while (p2 !== ear.prev) { if (pointInTriangle(a2.x, a2.y, b2.x, b2.y, c2.x, c2.y, p2.x, p2.y) && area(p2.prev, p2, p2.next) >= 0) return false; p2 = p2.next; } return true; } function isEarHashed(ear, minX, minY, invSize) { const a2 = ear.prev, b2 = ear, c2 = ear.next; if (area(a2, b2, c2) >= 0) return false; const minTX = a2.x < b2.x ? a2.x < c2.x ? a2.x : c2.x : b2.x < c2.x ? b2.x : c2.x, minTY = a2.y < b2.y ? a2.y < c2.y ? a2.y : c2.y : b2.y < c2.y ? b2.y : c2.y, maxTX = a2.x > b2.x ? a2.x > c2.x ? a2.x : c2.x : b2.x > c2.x ? b2.x : c2.x, maxTY = a2.y > b2.y ? a2.y > c2.y ? a2.y : c2.y : b2.y > c2.y ? b2.y : c2.y; const minZ = zOrder(minTX, minTY, minX, minY, invSize), maxZ = zOrder(maxTX, maxTY, minX, minY, invSize); let p2 = ear.prevZ, n = ear.nextZ; while (p2 && p2.z >= minZ && n && n.z <= maxZ) { if (p2 !== ear.prev && p2 !== ear.next && pointInTriangle(a2.x, a2.y, b2.x, b2.y, c2.x, c2.y, p2.x, p2.y) && area(p2.prev, p2, p2.next) >= 0) return false; p2 = p2.prevZ; if (n !== ear.prev && n !== ear.next && pointInTriangle(a2.x, a2.y, b2.x, b2.y, c2.x, c2.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; n = n.nextZ; } while (p2 && p2.z >= minZ) { if (p2 !== ear.prev && p2 !== ear.next && pointInTriangle(a2.x, a2.y, b2.x, b2.y, c2.x, c2.y, p2.x, p2.y) && area(p2.prev, p2, p2.next) >= 0) return false; p2 = p2.prevZ; } while (n && n.z <= maxZ) { if (n !== ear.prev && n !== ear.next && pointInTriangle(a2.x, a2.y, b2.x, b2.y, c2.x, c2.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false; n = n.nextZ; } return true; } function cureLocalIntersections(start, triangles, dim) { let p2 = start; do { const a2 = p2.prev, b2 = p2.next.next; if (!equals(a2, b2) && intersects(a2, p2, p2.next, b2) && locallyInside(a2, b2) && locallyInside(b2, a2)) { triangles.push(a2.i / dim); triangles.push(p2.i / dim); triangles.push(b2.i / dim); removeNode(p2); removeNode(p2.next); p2 = start = b2; } p2 = p2.next; } while (p2 !== start); return filterPoints(p2); } function splitEarcut(start, triangles, dim, minX, minY, invSize) { let a2 = start; do { let b2 = a2.next.next; while (b2 !== a2.prev) { if (a2.i !== b2.i && isValidDiagonal(a2, b2)) { let c2 = splitPolygon(a2, b2); a2 = filterPoints(a2, a2.next); c2 = filterPoints(c2, c2.next); earcutLinked(a2, triangles, dim, minX, minY, invSize); earcutLinked(c2, triangles, dim, minX, minY, invSize); return; } b2 = b2.next; } a2 = a2.next; } while (a2 !== start); } function eliminateHoles(data, holeIndices, outerNode, dim) { const queue = []; let i, len, start, end, list; for (i = 0, len = holeIndices.length; i < len; i++) { start = holeIndices[i] * dim; end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; list = linkedList(data, start, end, dim, false); if (list === list.next) list.steiner = true; queue.push(getLeftmost(list)); } queue.sort(compareX); for (i = 0; i < queue.length; i++) { eliminateHole(queue[i], outerNode); outerNode = filterPoints(outerNode, outerNode.next); } return outerNode; } function compareX(a2, b2) { return a2.x - b2.x; } function eliminateHole(hole, outerNode) { outerNode = findHoleBridge(hole, outerNode); if (outerNode) { const b2 = splitPolygon(outerNode, hole); filterPoints(outerNode, outerNode.next); filterPoints(b2, b2.next); } } function findHoleBridge(hole, outerNode) { let p2 = outerNode; const hx = hole.x; const hy = hole.y; let qx = -Infinity, m; do { if (hy <= p2.y && hy >= p2.next.y && p2.next.y !== p2.y) { const x = p2.x + (hy - p2.y) * (p2.next.x - p2.x) / (p2.next.y - p2.y); if (x <= hx && x > qx) { qx = x; if (x === hx) { if (hy === p2.y) return p2; if (hy === p2.next.y) return p2.next; } m = p2.x < p2.next.x ? p2 : p2.next; } } p2 = p2.next; } while (p2 !== outerNode); if (!m) return null; if (hx === qx) return m; const stop = m, mx = m.x, my = m.y; let tanMin = Infinity, tan; p2 = m; do { if (hx >= p2.x && p2.x >= mx && hx !== p2.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p2.x, p2.y)) { tan = Math.abs(hy - p2.y) / (hx - p2.x); if (locallyInside(p2, hole) && (tan < tanMin || tan === tanMin && (p2.x > m.x || p2.x === m.x && sectorContainsSector(m, p2)))) { m = p2; tanMin = tan; } } p2 = p2.next; } while (p2 !== stop); return m; } function sectorContainsSector(m, p2) { return area(m.prev, m, p2.prev) < 0 && area(p2.next, m, m.next) < 0; } function indexCurve(start, minX, minY, invSize) { let p2 = start; do { if (p2.z === null) p2.z = zOrder(p2.x, p2.y, minX, minY, invSize); p2.prevZ = p2.prev; p2.nextZ = p2.next; p2 = p2.next; } while (p2 !== start); p2.prevZ.nextZ = null; p2.prevZ = null; sortLinked(p2); } function sortLinked(list) { let i, p2, q, e, tail, numMerges, pSize, qSize, inSize = 1; do { p2 = list; list = null; tail = null; numMerges = 0; while (p2) { numMerges++; q = p2; pSize = 0; for (i = 0; i < inSize; i++) { pSize++; q = q.nextZ; if (!q) break; } qSize = inSize; while (pSize > 0 || qSize > 0 && q) { if (pSize !== 0 && (qSize === 0 || !q || p2.z <= q.z)) { e = p2; p2 = p2.nextZ; pSize--; } else { e = q; q = q.nextZ; qSize--; } if (tail) tail.nextZ = e; else list = e; e.prevZ = tail; tail = e; } p2 = q; } tail.nextZ = null; inSize *= 2; } while (numMerges > 1); return list; } function zOrder(x, y, minX, minY, invSize) { x = 32767 * (x - minX) * invSize; y = 32767 * (y - minY) * invSize; x = (x | x << 8) & 16711935; x = (x | x << 4) & 252645135; x = (x | x << 2) & 858993459; x = (x | x << 1) & 1431655765; y = (y | y << 8) & 16711935; y = (y | y << 4) & 252645135; y = (y | y << 2) & 858993459; y = (y | y << 1) & 1431655765; return x | y << 1; } function getLeftmost(start) { let p2 = start, leftmost = start; do { if (p2.x < leftmost.x || p2.x === leftmost.x && p2.y < leftmost.y) leftmost = p2; p2 = p2.next; } while (p2 !== start); return leftmost; } function pointInTriangle(ax, ay, bx, by, cx, cy, px2, py2) { return (cx - px2) * (ay - py2) - (ax - px2) * (cy - py2) >= 0 && (ax - px2) * (by - py2) - (bx - px2) * (ay - py2) >= 0 && (bx - px2) * (cy - py2) - (cx - px2) * (by - py2) >= 0; } function isValidDiagonal(a2, b2) { return a2.next.i !== b2.i && a2.prev.i !== b2.i && !intersectsPolygon(a2, b2) && (locallyInside(a2, b2) && locallyInside(b2, a2) && middleInside(a2, b2) && (area(a2.prev, a2, b2.prev) || area(a2, b2.prev, b2)) || equals(a2, b2) && area(a2.prev, a2, a2.next) > 0 && area(b2.prev, b2, b2.next) > 0); } function area(p2, q, r) { return (q.y - p2.y) * (r.x - q.x) - (q.x - p2.x) * (r.y - q.y); } function equals(p1, p2) { return p1.x === p2.x && p1.y === p2.y; } function intersects(p1, q1, p2, q2) { const o1 = sign(area(p1, q1, p2)); const o2 = sign(area(p1, q1, q2)); const o3 = sign(area(p2, q2, p1)); const o4 = sign(area(p2, q2, q1)); if (o1 !== o2 && o3 !== o4) return true; if (o1 === 0 && onSegment(p1, p2, q1)) return true; if (o2 === 0 && onSegment(p1, q2, q1)) return true; if (o3 === 0 && onSegment(p2, p1, q2)) return true; if (o4 === 0 && onSegment(p2, q1, q2)) return true; return false; } function onSegment(p2, q, r) { return q.x <= Math.max(p2.x, r.x) && q.x >= Math.min(p2.x, r.x) && q.y <= Math.max(p2.y, r.y) && q.y >= Math.min(p2.y, r.y); } function sign(num) { return num > 0 ? 1 : num < 0 ? -1 : 0; } function intersectsPolygon(a2, b2) { let p2 = a2; do { if (p2.i !== a2.i && p2.next.i !== a2.i && p2.i !== b2.i && p2.next.i !== b2.i && intersects(p2, p2.next, a2, b2)) return true; p2 = p2.next; } while (p2 !== a2); return false; } function locallyInside(a2, b2) { return area(a2.prev, a2, a2.next) < 0 ? area(a2, b2, a2.next) >= 0 && area(a2, a2.prev, b2) >= 0 : area(a2, b2, a2.prev) < 0 || area(a2, a2.next, b2) < 0; } function middleInside(a2, b2) { let p2 = a2, inside = false; const px2 = (a2.x + b2.x) / 2, py2 = (a2.y + b2.y) / 2; do { if (p2.y > py2 !== p2.next.y > py2 && p2.next.y !== p2.y && px2 < (p2.next.x - p2.x) * (py2 - p2.y) / (p2.next.y - p2.y) + p2.x) inside = !inside; p2 = p2.next; } while (p2 !== a2); return inside; } function splitPolygon(a2, b2) { const a22 = new Node(a2.i, a2.x, a2.y), b22 = new Node(b2.i, b2.x, b2.y), an = a2.next, bp = b2.prev; a2.next = b2; b2.prev = a2; a22.next = an; an.prev = a22; b22.next = a22; a22.prev = b22; bp.next = b22; b22.prev = bp; return b22; } function insertNode(i, x, y, last) { const p2 = new Node(i, x, y); if (!last) { p2.prev = p2; p2.next = p2; } else { p2.next = last.next; p2.prev = last; last.next.prev = p2; last.next = p2; } return p2; } function removeNode(p2) { p2.next.prev = p2.prev; p2.prev.next = p2.next; if (p2.prevZ) p2.prevZ.nextZ = p2.nextZ; if (p2.nextZ) p2.nextZ.prevZ = p2.prevZ; } function Node(i, x, y) { this.i = i; this.x = x; this.y = y; this.prev = null; this.next = null; this.z = null; this.prevZ = null; this.nextZ = null; this.steiner = false; } function signedArea(data, start, end, dim) { let sum = 0; for (let i = start, j = end - dim; i < end; i += dim) { sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); j = i; } return sum; } var ShapeUtils = class { static area(contour) { const n = contour.length; let a2 = 0; for (let p2 = n - 1, q = 0; q < n; p2 = q++) { a2 += contour[p2].x * contour[q].y - contour[q].x * contour[p2].y; } return a2 * 0.5; } static isClockWise(pts) { return ShapeUtils.area(pts) < 0; } static triangulateShape(contour, holes) { const vertices = []; const holeIndices = []; const faces = []; removeDupEndPts(contour); addContour(vertices, contour); let holeIndex = contour.length; holes.forEach(removeDupEndPts); for (let i = 0; i < holes.length; i++) { holeIndices.push(holeIndex); holeIndex += holes[i].length; addContour(vertices, holes[i]); } const triangles = Earcut.triangulate(vertices, holeIndices); for (let i = 0; i < triangles.length; i += 3) { faces.push(triangles.slice(i, i + 3)); } return faces; } }; function removeDupEndPts(points) { const l = points.length; if (l > 2 && points[l - 1].equals(points[0])) { points.pop(); } } function addContour(vertices, contour) { for (let i = 0; i < contour.length; i++) { vertices.push(contour[i].x); vertices.push(contour[i].y); } } var ExtrudeGeometry = class extends BufferGeometry { constructor(shapes, options) { super(); this.type = "ExtrudeGeometry"; this.parameters = { shapes, options }; shapes = Array.isArray(shapes) ? shapes : [shapes]; const scope = this; const verticesArray = []; const uvArray = []; for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; addShape(shape); } this.setAttribute("position", new Float32BufferAttribute(verticesArray, 3)); this.setAttribute("uv", new Float32BufferAttribute(uvArray, 2)); this.computeVertexNormals(); function addShape(shape) { const placeholder = []; const curveSegments = options.curveSegments !== void 0 ? options.curveSegments : 12; const steps = options.steps !== void 0 ? options.steps : 1; let depth = options.depth !== void 0 ? options.depth : 100; let bevelEnabled = options.bevelEnabled !== void 0 ? options.bevelEnabled : true; let bevelThickness = options.bevelThickness !== void 0 ? options.bevelThickness : 6; let bevelSize = options.bevelSize !== void 0 ? options.bevelSize : bevelThickness - 2; let bevelOffset = options.bevelOffset !== void 0 ? options.bevelOffset : 0; let bevelSegments = options.bevelSegments !== void 0 ? options.bevelSegments : 3; const extrudePath = options.extrudePath; const uvgen = options.UVGenerator !== void 0 ? options.UVGenerator : WorldUVGenerator; if (options.amount !== void 0) { console.warn("THREE.ExtrudeBufferGeometry: amount has been renamed to depth."); depth = options.amount; } let extrudePts, extrudeByPath = false; let splineTube, binormal, normal, position2; if (extrudePath) { extrudePts = extrudePath.getSpacedPoints(steps); extrudeByPath = true; bevelEnabled = false; splineTube = extrudePath.computeFrenetFrames(steps, false); binormal = new Vector3(); normal = new Vector3(); position2 = new Vector3(); } if (!bevelEnabled) { bevelSegments = 0; bevelThickness = 0; bevelSize = 0; bevelOffset = 0; } const shapePoints = shape.extractPoints(curveSegments); let vertices = shapePoints.shape; const holes = shapePoints.holes; const reverse = !ShapeUtils.isClockWise(vertices); if (reverse) { vertices = vertices.reverse(); for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; if (ShapeUtils.isClockWise(ahole)) { holes[h] = ahole.reverse(); } } } const faces = ShapeUtils.triangulateShape(vertices, holes); const contour = vertices; for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; vertices = vertices.concat(ahole); } function scalePt2(pt, vec, size) { if (!vec) console.error("THREE.ExtrudeGeometry: vec does not exist"); return vec.clone().multiplyScalar(size).add(pt); } const vlen = vertices.length, flen = faces.length; function getBevelVec(inPt, inPrev, inNext) { let v_trans_x, v_trans_y, shrink_by; const v_prev_x = inPt.x - inPrev.x, v_prev_y = inPt.y - inPrev.y; const v_next_x = inNext.x - inPt.x, v_next_y = inNext.y - inPt.y; const v_prev_lensq = v_prev_x * v_prev_x + v_prev_y * v_prev_y; const collinear0 = v_prev_x * v_next_y - v_prev_y * v_next_x; if (Math.abs(collinear0) > Number.EPSILON) { const v_prev_len = Math.sqrt(v_prev_lensq); const v_next_len = Math.sqrt(v_next_x * v_next_x + v_next_y * v_next_y); const ptPrevShift_x = inPrev.x - v_prev_y / v_prev_len; const ptPrevShift_y = inPrev.y + v_prev_x / v_prev_len; const ptNextShift_x = inNext.x - v_next_y / v_next_len; const ptNextShift_y = inNext.y + v_next_x / v_next_len; const sf = ((ptNextShift_x - ptPrevShift_x) * v_next_y - (ptNextShift_y - ptPrevShift_y) * v_next_x) / (v_prev_x * v_next_y - v_prev_y * v_next_x); v_trans_x = ptPrevShift_x + v_prev_x * sf - inPt.x; v_trans_y = ptPrevShift_y + v_prev_y * sf - inPt.y; const v_trans_lensq = v_trans_x * v_trans_x + v_trans_y * v_trans_y; if (v_trans_lensq <= 2) { return new Vector2(v_trans_x, v_trans_y); } else { shrink_by = Math.sqrt(v_trans_lensq / 2); } } else { let direction_eq = false; if (v_prev_x > Number.EPSILON) { if (v_next_x > Number.EPSILON) { direction_eq = true; } } else { if (v_prev_x < -Number.EPSILON) { if (v_next_x < -Number.EPSILON) { direction_eq = true; } } else { if (Math.sign(v_prev_y) === Math.sign(v_next_y)) { direction_eq = true; } } } if (direction_eq) { v_trans_x = -v_prev_y; v_trans_y = v_prev_x; shrink_by = Math.sqrt(v_prev_lensq); } else { v_trans_x = v_prev_x; v_trans_y = v_prev_y; shrink_by = Math.sqrt(v_prev_lensq / 2); } } return new Vector2(v_trans_x / shrink_by, v_trans_y / shrink_by); } const contourMovements = []; for (let i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) { if (j === il) j = 0; if (k === il) k = 0; contourMovements[i] = getBevelVec(contour[i], contour[j], contour[k]); } const holesMovements = []; let oneHoleMovements, verticesMovements = contourMovements.concat(); for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; oneHoleMovements = []; for (let i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) { if (j === il) j = 0; if (k === il) k = 0; oneHoleMovements[i] = getBevelVec(ahole[i], ahole[j], ahole[k]); } holesMovements.push(oneHoleMovements); verticesMovements = verticesMovements.concat(oneHoleMovements); } for (let b2 = 0; b2 < bevelSegments; b2++) { const t = b2 / bevelSegments; const z = bevelThickness * Math.cos(t * Math.PI / 2); const bs2 = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; for (let i = 0, il = contour.length; i < il; i++) { const vert = scalePt2(contour[i], contourMovements[i], bs2); v(vert.x, vert.y, -z); } for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; oneHoleMovements = holesMovements[h]; for (let i = 0, il = ahole.length; i < il; i++) { const vert = scalePt2(ahole[i], oneHoleMovements[i], bs2); v(vert.x, vert.y, -z); } } } const bs = bevelSize + bevelOffset; for (let i = 0; i < vlen; i++) { const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i]; if (!extrudeByPath) { v(vert.x, vert.y, 0); } else { normal.copy(splineTube.normals[0]).multiplyScalar(vert.x); binormal.copy(splineTube.binormals[0]).multiplyScalar(vert.y); position2.copy(extrudePts[0]).add(normal).add(binormal); v(position2.x, position2.y, position2.z); } } for (let s = 1; s <= steps; s++) { for (let i = 0; i < vlen; i++) { const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i]; if (!extrudeByPath) { v(vert.x, vert.y, depth / steps * s); } else { normal.copy(splineTube.normals[s]).multiplyScalar(vert.x); binormal.copy(splineTube.binormals[s]).multiplyScalar(vert.y); position2.copy(extrudePts[s]).add(normal).add(binormal); v(position2.x, position2.y, position2.z); } } } for (let b2 = bevelSegments - 1; b2 >= 0; b2--) { const t = b2 / bevelSegments; const z = bevelThickness * Math.cos(t * Math.PI / 2); const bs2 = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; for (let i = 0, il = contour.length; i < il; i++) { const vert = scalePt2(contour[i], contourMovements[i], bs2); v(vert.x, vert.y, depth + z); } for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; oneHoleMovements = holesMovements[h]; for (let i = 0, il = ahole.length; i < il; i++) { const vert = scalePt2(ahole[i], oneHoleMovements[i], bs2); if (!extrudeByPath) { v(vert.x, vert.y, depth + z); } else { v(vert.x, vert.y + extrudePts[steps - 1].y, extrudePts[steps - 1].x + z); } } } } buildLidFaces(); buildSideFaces(); function buildLidFaces() { const start = verticesArray.length / 3; if (bevelEnabled) { let layer = 0; let offset = vlen * layer; for (let i = 0; i < flen; i++) { const face = faces[i]; f3(face[2] + offset, face[1] + offset, face[0] + offset); } layer = steps + bevelSegments * 2; offset = vlen * layer; for (let i = 0; i < flen; i++) { const face = faces[i]; f3(face[0] + offset, face[1] + offset, face[2] + offset); } } else { for (let i = 0; i < flen; i++) { const face = faces[i]; f3(face[2], face[1], face[0]); } for (let i = 0; i < flen; i++) { const face = faces[i]; f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps); } } scope.addGroup(start, verticesArray.length / 3 - start, 0); } function buildSideFaces() { const start = verticesArray.length / 3; let layeroffset = 0; sidewalls(contour, layeroffset); layeroffset += contour.length; for (let h = 0, hl = holes.length; h < hl; h++) { const ahole = holes[h]; sidewalls(ahole, layeroffset); layeroffset += ahole.length; } scope.addGroup(start, verticesArray.length / 3 - start, 1); } function sidewalls(contour2, layeroffset) { let i = contour2.length; while (--i >= 0) { const j = i; let k = i - 1; if (k < 0) k = contour2.length - 1; for (let s = 0, sl = steps + bevelSegments * 2; s < sl; s++) { const slen1 = vlen * s; const slen2 = vlen * (s + 1); const a2 = layeroffset + j + slen1, b2 = layeroffset + k + slen1, c2 = layeroffset + k + slen2, d = layeroffset + j + slen2; f4(a2, b2, c2, d); } } } function v(x, y, z) { placeholder.push(x); placeholder.push(y); placeholder.push(z); } function f3(a2, b2, c2) { addVertex(a2); addVertex(b2); addVertex(c2); const nextIndex = verticesArray.length / 3; const uvs = uvgen.generateTopUV(scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1); addUV(uvs[0]); addUV(uvs[1]); addUV(uvs[2]); } function f4(a2, b2, c2, d) { addVertex(a2); addVertex(b2); addVertex(d); addVertex(b2); addVertex(c2); addVertex(d); const nextIndex = verticesArray.length / 3; const uvs = uvgen.generateSideWallUV(scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1); addUV(uvs[0]); addUV(uvs[1]); addUV(uvs[3]); addUV(uvs[1]); addUV(uvs[2]); addUV(uvs[3]); } function addVertex(index) { verticesArray.push(placeholder[index * 3 + 0]); verticesArray.push(placeholder[index * 3 + 1]); verticesArray.push(placeholder[index * 3 + 2]); } function addUV(vector2) { uvArray.push(vector2.x); uvArray.push(vector2.y); } } } toJSON() { const data = super.toJSON(); const shapes = this.parameters.shapes; const options = this.parameters.options; return toJSON$1(shapes, options, data); } static fromJSON(data, shapes) { const geometryShapes = []; for (let j = 0, jl = data.shapes.length; j < jl; j++) { const shape = shapes[data.shapes[j]]; geometryShapes.push(shape); } const extrudePath = data.options.extrudePath; if (extrudePath !== void 0) { data.options.extrudePath = new Curves[extrudePath.type]().fromJSON(extrudePath); } return new ExtrudeGeometry(geometryShapes, data.options); } }; var WorldUVGenerator = { generateTopUV: function(geometry, vertices, indexA, indexB, indexC) { const a_x = vertices[indexA * 3]; const a_y = vertices[indexA * 3 + 1]; const b_x = vertices[indexB * 3]; const b_y = vertices[indexB * 3 + 1]; const c_x = vertices[indexC * 3]; const c_y = vertices[indexC * 3 + 1]; return [ new Vector2(a_x, a_y), new Vector2(b_x, b_y), new Vector2(c_x, c_y) ]; }, generateSideWallUV: function(geometry, vertices, indexA, indexB, indexC, indexD) { const a_x = vertices[indexA * 3]; const a_y = vertices[indexA * 3 + 1]; const a_z = vertices[indexA * 3 + 2]; const b_x = vertices[indexB * 3]; const b_y = vertices[indexB * 3 + 1]; const b_z = vertices[indexB * 3 + 2]; const c_x = vertices[indexC * 3]; const c_y = vertices[indexC * 3 + 1]; const c_z = vertices[indexC * 3 + 2]; const d_x = vertices[indexD * 3]; const d_y = vertices[indexD * 3 + 1]; const d_z = vertices[indexD * 3 + 2]; if (Math.abs(a_y - b_y) < Math.abs(a_x - b_x)) { return [ new Vector2(a_x, 1 - a_z), new Vector2(b_x, 1 - b_z), new Vector2(c_x, 1 - c_z), new Vector2(d_x, 1 - d_z) ]; } else { return [ new Vector2(a_y, 1 - a_z), new Vector2(b_y, 1 - b_z), new Vector2(c_y, 1 - c_z), new Vector2(d_y, 1 - d_z) ]; } } }; function toJSON$1(shapes, options, data) { data.shapes = []; if (Array.isArray(shapes)) { for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; data.shapes.push(shape.uuid); } } else { data.shapes.push(shapes.uuid); } if (options.extrudePath !== void 0) data.options.extrudePath = options.extrudePath.toJSON(); return data; } var ShapeGeometry = class extends BufferGeometry { constructor(shapes, curveSegments = 12) { super(); this.type = "ShapeGeometry"; this.parameters = { shapes, curveSegments }; const indices = []; const vertices = []; const normals = []; const uvs = []; let groupStart = 0; let groupCount = 0; if (Array.isArray(shapes) === false) { addShape(shapes); } else { for (let i = 0; i < shapes.length; i++) { addShape(shapes[i]); this.addGroup(groupStart, groupCount, i); groupStart += groupCount; groupCount = 0; } } 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 addShape(shape) { const indexOffset = vertices.length / 3; const points = shape.extractPoints(curveSegments); let shapeVertices = points.shape; const shapeHoles = points.holes; if (ShapeUtils.isClockWise(shapeVertices) === false) { shapeVertices = shapeVertices.reverse(); } for (let i = 0, l = shapeHoles.length; i < l; i++) { const shapeHole = shapeHoles[i]; if (ShapeUtils.isClockWise(shapeHole) === true) { shapeHoles[i] = shapeHole.reverse(); } } const faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); for (let i = 0, l = shapeHoles.length; i < l; i++) { const shapeHole = shapeHoles[i]; shapeVertices = shapeVertices.concat(shapeHole); } for (let i = 0, l = shapeVertices.length; i < l; i++) { const vertex = shapeVertices[i]; vertices.push(vertex.x, vertex.y, 0); normals.push(0, 0, 1); uvs.push(vertex.x, vertex.y); } for (let i = 0, l = faces.length; i < l; i++) { const face = faces[i]; const a2 = face[0] + indexOffset; const b2 = face[1] + indexOffset; const c2 = face[2] + indexOffset; indices.push(a2, b2, c2); groupCount += 3; } } } toJSON() { const data = super.toJSON(); const shapes = this.parameters.shapes; return toJSON(shapes, data); } static fromJSON(data, shapes) { const geometryShapes = []; for (let j = 0, jl = data.shapes.length; j < jl; j++) { const shape = shapes[data.shapes[j]]; geometryShapes.push(shape); } return new ShapeGeometry(geometryShapes, data.curveSegments); } }; function toJSON(shapes, data) { data.shapes = []; if (Array.isArray(shapes)) { for (let i = 0, l = shapes.length; i < l; i++) { const shape = shapes[i]; data.shapes.push(shape.uuid); } } else { data.shapes.push(shapes.uuid); } return data; } var ShadowMaterial = class extends Material { constructor(parameters) { super(); this.type = "ShadowMaterial"; this.color = new Color(0); this.transparent = true; this.setValues(parameters); } copy(source) { super.copy(source); this.color.copy(source.color); return this; } }; ShadowMaterial.prototype.isShadowMaterial = true; var MeshStandardMaterial = class extends Material { constructor(parameters) { super(); this.defines = { "STANDARD": "" }; this.type = "MeshStandardMaterial"; this.color = new Color(16777215); this.roughness = 1; this.metalness = 0; this.map = null; this.lightMap = null; this.lightMapIntensity = 1; this.aoMap = null; this.aoMapIntensity = 1; this.emissive = new Color(0); this.emissiveIntensity = 1; this.emissiveMap = null; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap; this.normalScale = new Vector2(1, 1); this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.roughnessMap = null; this.metalnessMap = null; this.alphaMap = null; this.envMap = null; this.envMapIntensity = 1; this.refractionRatio = 0.98; this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = "round"; this.wireframeLinejoin = "round"; this.flatShading = false; this.setValues(parameters); } copy(source) { super.copy(source); this.defines = { "STANDARD": "" }; this.color.copy(source.color); this.roughness = source.roughness; this.metalness = source.metalness; this.map = source.map; this.lightMap = source.lightMap; this.lightMapIntensity = source.lightMapIntensity; this.aoMap = source.aoMap; this.aoMapIntensity = source.aoMapIntensity; this.emissive.copy(source.emissive); this.emissiveMap = source.emissiveMap; this.emissiveIntensity = source.emissiveIntensity; this.bumpMap = source.bumpMap; this.bumpScale = source.bumpScale; this.normalMap = source.normalMap; this.normalMapType = source.normalMapType; this.normalScale.copy(source.normalScale); this.displacementMap = source.displacementMap; this.displacementScale = source.displacementScale; this.displacementBias = source.displacementBias; this.roughnessMap = source.roughnessMap; this.metalnessMap = source.metalnessMap; this.alphaMap = source.alphaMap; this.envMap = source.envMap; this.envMapIntensity = source.envMapIntensity; this.refractionRatio = source.refractionRatio; this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; this.flatShading = source.flatShading; return this; } }; MeshStandardMaterial.prototype.isMeshStandardMaterial = true; var MeshPhysicalMaterial = class extends MeshStandardMaterial { constructor(parameters) { super(); this.defines = { "STANDARD": "", "PHYSICAL": "" }; this.type = "MeshPhysicalMaterial"; this.clearcoatMap = null; this.clearcoatRoughness = 0; this.clearcoatRoughnessMap = null; this.clearcoatNormalScale = new Vector2(1, 1); this.clearcoatNormalMap = null; this.ior = 1.5; Object.defineProperty(this, "reflectivity", { get: function() { return clamp(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1); }, set: function(reflectivity) { this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity); } }); this.sheenTint = new Color(0); this.transmission = 0; this.transmissionMap = null; this.thickness = 0.01; this.thicknessMap = null; this.attenuationDistance = 0; this.attenuationTint = new Color(1, 1, 1); this.specularIntensity = 1; this.specularIntensityMap = null; this.specularTint = new Color(1, 1, 1); this.specularTintMap = null; this._clearcoat = 0; this._transmission = 0; this.setValues(parameters); } get clearcoat() { return this._clearcoat; } set clearcoat(value) { if (this._clearcoat > 0 !== value > 0) { this.version++; } this._clearcoat = value; } get transmission() { return this._transmission; } set transmission(value) { if (this._transmission > 0 !== value > 0) { this.version++; } this._transmission = value; } copy(source) { super.copy(source); this.defines = { "STANDARD": "", "PHYSICAL": "" }; this.clearcoat = source.clearcoat; this.clearcoatMap = source.clearcoatMap; this.clearcoatRoughness = source.clearcoatRoughness; this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; this.clearcoatNormalMap = source.clearcoatNormalMap; this.clearcoatNormalScale.copy(source.clearcoatNormalScale); this.ior = source.ior; this.sheenTint.copy(source.sheenTint); this.transmission = source.transmission; this.transmissionMap = source.transmissionMap; this.thickness = source.thickness; this.thicknessMap = source.thicknessMap; this.attenuationDistance = source.attenuationDistance; this.attenuationTint.copy(source.attenuationTint); this.specularIntensity = source.specularIntensity; this.specularIntensityMap = source.specularIntensityMap; this.specularTint.copy(source.specularTint); this.specularTintMap = source.specularTintMap; return this; } }; MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true; var MeshPhongMaterial = class extends Material { constructor(parameters) { super(); this.type = "MeshPhongMaterial"; this.color = new Color(16777215); this.specular = new Color(1118481); this.shininess = 30; this.map = null; this.lightMap = null; this.lightMapIntensity = 1; this.aoMap = null; this.aoMapIntensity = 1; this.emissive = new Color(0); this.emissiveIntensity = 1; this.emissiveMap = null; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap; this.normalScale = new Vector2(1, 1); this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 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.flatShading = false; this.setValues(parameters); } copy(source) { super.copy(source); this.color.copy(source.color); this.specular.copy(source.specular); this.shininess = source.shininess; this.map = source.map; this.lightMap = source.lightMap; this.lightMapIntensity = source.lightMapIntensity; this.aoMap = source.aoMap; this.aoMapIntensity = source.aoMapIntensity; this.emissive.copy(source.emissive); this.emissiveMap = source.emissiveMap; this.emissiveIntensity = source.emissiveIntensity; this.bumpMap = source.bumpMap; this.bumpScale = source.bumpScale; this.normalMap = source.normalMap; this.normalMapType = source.normalMapType; this.normalScale.copy(source.normalScale); this.displacementMap = source.displacementMap; this.displacementScale = source.displacementScale; this.displacementBias = source.displacementBias; 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.flatShading = source.flatShading; return this; } }; MeshPhongMaterial.prototype.isMeshPhongMaterial = true; var MeshToonMaterial = class extends Material { constructor(parameters) { super(); this.defines = { "TOON": "" }; this.type = "MeshToonMaterial"; this.color = new Color(16777215); this.map = null; this.gradientMap = null; this.lightMap = null; this.lightMapIntensity = 1; this.aoMap = null; this.aoMapIntensity = 1; this.emissive = new Color(0); this.emissiveIntensity = 1; this.emissiveMap = null; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap; this.normalScale = new Vector2(1, 1); this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.alphaMap = null; this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = "round"; this.wireframeLinejoin = "round"; this.setValues(parameters); } copy(source) { super.copy(source); this.color.copy(source.color); this.map = source.map; this.gradientMap = source.gradientMap; this.lightMap = source.lightMap; this.lightMapIntensity = source.lightMapIntensity; this.aoMap = source.aoMap; this.aoMapIntensity = source.aoMapIntensity; this.emissive.copy(source.emissive); this.emissiveMap = source.emissiveMap; this.emissiveIntensity = source.emissiveIntensity; this.bumpMap = source.bumpMap; this.bumpScale = source.bumpScale; this.normalMap = source.normalMap; this.normalMapType = source.normalMapType; this.normalScale.copy(source.normalScale); this.displacementMap = source.displacementMap; this.displacementScale = source.displacementScale; this.displacementBias = source.displacementBias; this.alphaMap = source.alphaMap; this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; return this; } }; MeshToonMaterial.prototype.isMeshToonMaterial = true; var MeshNormalMaterial = class extends Material { constructor(parameters) { super(); this.type = "MeshNormalMaterial"; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap; this.normalScale = new Vector2(1, 1); this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.wireframe = false; this.wireframeLinewidth = 1; this.fog = false; this.flatShading = false; this.setValues(parameters); } copy(source) { super.copy(source); this.bumpMap = source.bumpMap; this.bumpScale = source.bumpScale; this.normalMap = source.normalMap; this.normalMapType = source.normalMapType; this.normalScale.copy(source.normalScale); this.displacementMap = source.displacementMap; this.displacementScale = source.displacementScale; this.displacementBias = source.displacementBias; this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; this.flatShading = source.flatShading; return this; } }; MeshNormalMaterial.prototype.isMeshNormalMaterial = true; var MeshLambertMaterial = class extends Material { constructor(parameters) { super(); this.type = "MeshLambertMaterial"; this.color = new Color(16777215); this.map = null; this.lightMap = null; this.lightMapIntensity = 1; this.aoMap = null; this.aoMapIntensity = 1; this.emissive = new Color(0); this.emissiveIntensity = 1; this.emissiveMap = null; 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.setValues(parameters); } copy(source) { super.copy(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.emissive.copy(source.emissive); this.emissiveMap = source.emissiveMap; this.emissiveIntensity = source.emissiveIntensity; 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; return this; } }; MeshLambertMaterial.prototype.isMeshLambertMaterial = true; var MeshMatcapMaterial = class extends Material { constructor(parameters) { super(); this.defines = { "MATCAP": "" }; this.type = "MeshMatcapMaterial"; this.color = new Color(16777215); this.matcap = null; this.map = null; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap; this.normalScale = new Vector2(1, 1); this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.alphaMap = null; this.flatShading = false; this.setValues(parameters); } copy(source) { super.copy(source); this.defines = { "MATCAP": "" }; this.color.copy(source.color); this.matcap = source.matcap; this.map = source.map; this.bumpMap = source.bumpMap; this.bumpScale = source.bumpScale; this.normalMap = source.normalMap; this.normalMapType = source.normalMapType; this.normalScale.copy(source.normalScale); this.displacementMap = source.displacementMap; this.displacementScale = source.displacementScale; this.displacementBias = source.displacementBias; this.alphaMap = source.alphaMap; this.flatShading = source.flatShading; return this; } }; MeshMatcapMaterial.prototype.isMeshMatcapMaterial = true; var LineDashedMaterial = class extends LineBasicMaterial { constructor(parameters) { super(); this.type = "LineDashedMaterial"; this.scale = 1; this.dashSize = 3; this.gapSize = 1; this.setValues(parameters); } copy(source) { super.copy(source); this.scale = source.scale; this.dashSize = source.dashSize; this.gapSize = source.gapSize; return this; } }; LineDashedMaterial.prototype.isLineDashedMaterial = true; var AnimationUtils = { arraySlice: function(array, from, to) { if (AnimationUtils.isTypedArray(array)) { return new array.constructor(array.subarray(from, to !== void 0 ? to : array.length)); } return array.slice(from, to); }, convertArray: function(array, type, forceClone) { if (!array || !forceClone && array.constructor === type) return array; if (typeof type.BYTES_PER_ELEMENT === "number") { return new type(array); } return Array.prototype.slice.call(array); }, isTypedArray: function(object) { return ArrayBuffer.isView(object) && !(object instanceof DataView); }, getKeyframeOrder: function(times) { function compareTime(i, j) { return times[i] - times[j]; } const n = times.length; const result = new Array(n); for (let i = 0; i !== n; ++i) result[i] = i; result.sort(compareTime); return result; }, sortedArray: function(values, stride, order) { const nValues = values.length; const result = new values.constructor(nValues); for (let i = 0, dstOffset = 0; dstOffset !== nValues; ++i) { const srcOffset = order[i] * stride; for (let j = 0; j !== stride; ++j) { result[dstOffset++] = values[srcOffset + j]; } } return result; }, flattenJSON: function(jsonKeys, times, values, valuePropertyName) { let i = 1, key = jsonKeys[0]; while (key !== void 0 && key[valuePropertyName] === void 0) { key = jsonKeys[i++]; } if (key === void 0) return; let value = key[valuePropertyName]; if (value === void 0) return; if (Array.isArray(value)) { do { value = key[valuePropertyName]; if (value !== void 0) { times.push(key.time); values.push.apply(values, value); } key = jsonKeys[i++]; } while (key !== void 0); } else if (value.toArray !== void 0) { do { value = key[valuePropertyName]; if (value !== void 0) { times.push(key.time); value.toArray(values, values.length); } key = jsonKeys[i++]; } while (key !== void 0); } else { do { value = key[valuePropertyName]; if (value !== void 0) { times.push(key.time); values.push(value); } key = jsonKeys[i++]; } while (key !== void 0); } }, subclip: function(sourceClip, name, startFrame, endFrame, fps = 30) { const clip = sourceClip.clone(); clip.name = name; const tracks = []; for (let i = 0; i < clip.tracks.length; ++i) { const track = clip.tracks[i]; const valueSize = track.getValueSize(); const times = []; const values = []; for (let j = 0; j < track.times.length; ++j) { const frame = track.times[j] * fps; if (frame < startFrame || frame >= endFrame) continue; times.push(track.times[j]); for (let k = 0; k < valueSize; ++k) { values.push(track.values[j * valueSize + k]); } } if (times.length === 0) continue; track.times = AnimationUtils.convertArray(times, track.times.constructor); track.values = AnimationUtils.convertArray(values, track.values.constructor); tracks.push(track); } clip.tracks = tracks; let minStartTime = Infinity; for (let i = 0; i < clip.tracks.length; ++i) { if (minStartTime > clip.tracks[i].times[0]) { minStartTime = clip.tracks[i].times[0]; } } for (let i = 0; i < clip.tracks.length; ++i) { clip.tracks[i].shift(-1 * minStartTime); } clip.resetDuration(); return clip; }, makeClipAdditive: function(targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30) { if (fps <= 0) fps = 30; const numTracks = referenceClip.tracks.length; const referenceTime = referenceFrame / fps; for (let i = 0; i < numTracks; ++i) { const referenceTrack = referenceClip.tracks[i]; const referenceTrackType = referenceTrack.ValueTypeName; if (referenceTrackType === "bool" || referenceTrackType === "string") continue; const targetTrack = targetClip.tracks.find(function(track) { return track.name === referenceTrack.name && track.ValueTypeName === referenceTrackType; }); if (targetTrack === void 0) continue; let referenceOffset = 0; const referenceValueSize = referenceTrack.getValueSize(); if (referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { referenceOffset = referenceValueSize / 3; } let targetOffset = 0; const targetValueSize = targetTrack.getValueSize(); if (targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) { targetOffset = targetValueSize / 3; } const lastIndex = referenceTrack.times.length - 1; let referenceValue; if (referenceTime <= referenceTrack.times[0]) { const startIndex = referenceOffset; const endIndex = referenceValueSize - referenceOffset; referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex); } else if (referenceTime >= referenceTrack.times[lastIndex]) { const startIndex = lastIndex * referenceValueSize + referenceOffset; const endIndex = startIndex + referenceValueSize - referenceOffset; referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex); } else { const interpolant = referenceTrack.createInterpolant(); const startIndex = referenceOffset; const endIndex = referenceValueSize - referenceOffset; interpolant.evaluate(referenceTime); referenceValue = AnimationUtils.arraySlice(interpolant.resultBuffer, startIndex, endIndex); } if (referenceTrackType === "quaternion") { const referenceQuat = new Quaternion().fromArray(referenceValue).normalize().conjugate(); referenceQuat.toArray(referenceValue); } const numTimes = targetTrack.times.length; for (let j = 0; j < numTimes; ++j) { const valueStart = j * targetValueSize + targetOffset; if (referenceTrackType === "quaternion") { Quaternion.multiplyQuaternionsFlat(targetTrack.values, valueStart, referenceValue, 0, targetTrack.values, valueStart); } else { const valueEnd = targetValueSize - targetOffset * 2; for (let k = 0; k < valueEnd; ++k) { targetTrack.values[valueStart + k] -= referenceValue[k]; } } } } targetClip.blendMode = AdditiveAnimationBlendMode; return targetClip; } }; var Interpolant = class { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { this.parameterPositions = parameterPositions; this._cachedIndex = 0; this.resultBuffer = resultBuffer !== void 0 ? resultBuffer : new sampleValues.constructor(sampleSize); this.sampleValues = sampleValues; this.valueSize = sampleSize; this.settings = null; this.DefaultSettings_ = {}; } evaluate(t) { const pp = this.parameterPositions; let i1 = this._cachedIndex, t1 = pp[i1], t0 = pp[i1 - 1]; validate_interval: { seek: { let right; linear_scan: { forward_scan: if (!(t < t1)) { for (let giveUpAt = i1 + 2; ; ) { if (t1 === void 0) { if (t < t0) break forward_scan; i1 = pp.length; this._cachedIndex = i1; return this.afterEnd_(i1 - 1, t, t0); } if (i1 === giveUpAt) break; t0 = t1; t1 = pp[++i1]; if (t < t1) { break seek; } } right = pp.length; break linear_scan; } if (!(t >= t0)) { const t1global = pp[1]; if (t < t1global) { i1 = 2; t0 = t1global; } for (let giveUpAt = i1 - 2; ; ) { if (t0 === void 0) { this._cachedIndex = 0; return this.beforeStart_(0, t, t1); } if (i1 === giveUpAt) break; t1 = t0; t0 = pp[--i1 - 1]; if (t >= t0) { break seek; } } right = i1; i1 = 0; break linear_scan; } break validate_interval; } while (i1 < right) { const mid = i1 + right >>> 1; if (t < pp[mid]) { right = mid; } else { i1 = mid + 1; } } t1 = pp[i1]; t0 = pp[i1 - 1]; if (t0 === void 0) { this._cachedIndex = 0; return this.beforeStart_(0, t, t1); } if (t1 === void 0) { i1 = pp.length; this._cachedIndex = i1; return this.afterEnd_(i1 - 1, t0, t); } } this._cachedIndex = i1; this.intervalChanged_(i1, t0, t1); } return this.interpolate_(i1, t0, t, t1); } getSettings_() { return this.settings || this.DefaultSettings_; } copySampleValue_(index) { const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, offset = index * stride; for (let i = 0; i !== stride; ++i) { result[i] = values[offset + i]; } return result; } interpolate_() { throw new Error("call to abstract method"); } intervalChanged_() { } }; Interpolant.prototype.beforeStart_ = Interpolant.prototype.copySampleValue_; Interpolant.prototype.afterEnd_ = Interpolant.prototype.copySampleValue_; var CubicInterpolant = class extends Interpolant { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); this._weightPrev = -0; this._offsetPrev = -0; this._weightNext = -0; this._offsetNext = -0; this.DefaultSettings_ = { endingStart: ZeroCurvatureEnding, endingEnd: ZeroCurvatureEnding }; } intervalChanged_(i1, t0, t1) { const pp = this.parameterPositions; let iPrev = i1 - 2, iNext = i1 + 1, tPrev = pp[iPrev], tNext = pp[iNext]; if (tPrev === void 0) { switch (this.getSettings_().endingStart) { case ZeroSlopeEnding: iPrev = i1; tPrev = 2 * t0 - t1; break; case WrapAroundEnding: iPrev = pp.length - 2; tPrev = t0 + pp[iPrev] - pp[iPrev + 1]; break; default: iPrev = i1; tPrev = t1; } } if (tNext === void 0) { switch (this.getSettings_().endingEnd) { case ZeroSlopeEnding: iNext = i1; tNext = 2 * t1 - t0; break; case WrapAroundEnding: iNext = 1; tNext = t1 + pp[1] - pp[0]; break; default: iNext = i1 - 1; tNext = t0; } } const halfDt = (t1 - t0) * 0.5, stride = this.valueSize; this._weightPrev = halfDt / (t0 - tPrev); this._weightNext = halfDt / (tNext - t1); this._offsetPrev = iPrev * stride; this._offsetNext = iNext * stride; } interpolate_(i1, t0, t, t1) { const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, o1 = i1 * stride, o0 = o1 - stride, oP = this._offsetPrev, oN = this._offsetNext, wP = this._weightPrev, wN = this._weightNext, p2 = (t - t0) / (t1 - t0), pp = p2 * p2, ppp = pp * p2; const sP = -wP * ppp + 2 * wP * pp - wP * p2; const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p2 + 1; const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p2; const sN = wN * ppp - wN * pp; for (let i = 0; i !== stride; ++i) { result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i]; } return result; } }; var LinearInterpolant = class extends Interpolant { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); } interpolate_(i1, t0, t, t1) { const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, offset1 = i1 * stride, offset0 = offset1 - stride, weight1 = (t - t0) / (t1 - t0), weight0 = 1 - weight1; for (let i = 0; i !== stride; ++i) { result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1; } return result; } }; var DiscreteInterpolant = class extends Interpolant { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); } interpolate_(i1) { return this.copySampleValue_(i1 - 1); } }; var KeyframeTrack = class { constructor(name, times, values, interpolation) { if (name === void 0) throw new Error("THREE.KeyframeTrack: track name is undefined"); if (times === void 0 || times.length === 0) throw new Error("THREE.KeyframeTrack: no keyframes in track named " + name); this.name = name; this.times = AnimationUtils.convertArray(times, this.TimeBufferType); this.values = AnimationUtils.convertArray(values, this.ValueBufferType); this.setInterpolation(interpolation || this.DefaultInterpolation); } static toJSON(track) { const trackType = track.constructor; let json; if (trackType.toJSON !== this.toJSON) { json = trackType.toJSON(track); } else { json = { "name": track.name, "times": AnimationUtils.convertArray(track.times, Array), "values": AnimationUtils.convertArray(track.values, Array) }; const interpolation = track.getInterpolation(); if (interpolation !== track.DefaultInterpolation) { json.interpolation = interpolation; } } json.type = track.ValueTypeName; return json; } InterpolantFactoryMethodDiscrete(result) { return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result); } InterpolantFactoryMethodLinear(result) { return new LinearInterpolant(this.times, this.values, this.getValueSize(), result); } InterpolantFactoryMethodSmooth(result) { return new CubicInterpolant(this.times, this.values, this.getValueSize(), result); } setInterpolation(interpolation) { let factoryMethod; switch (interpolation) { case InterpolateDiscrete: factoryMethod = this.InterpolantFactoryMethodDiscrete; break; case InterpolateLinear: factoryMethod = this.InterpolantFactoryMethodLinear; break; case InterpolateSmooth: factoryMethod = this.InterpolantFactoryMethodSmooth; break; } if (factoryMethod === void 0) { const message = "unsupported interpolation for " + this.ValueTypeName + " keyframe track named " + this.name; if (this.createInterpolant === void 0) { if (interpolation !== this.DefaultInterpolation) { this.setInterpolation(this.DefaultInterpolation); } else { throw new Error(message); } } console.warn("THREE.KeyframeTrack:", message); return this; } this.createInterpolant = factoryMethod; return this; } getInterpolation() { switch (this.createInterpolant) { case this.InterpolantFactoryMethodDiscrete: return InterpolateDiscrete; case this.InterpolantFactoryMethodLinear: return InterpolateLinear; case this.InterpolantFactoryMethodSmooth: return InterpolateSmooth; } } getValueSize() { return this.values.length / this.times.length; } shift(timeOffset) { if (timeOffset !== 0) { const times = this.times; for (let i = 0, n = times.length; i !== n; ++i) { times[i] += timeOffset; } } return this; } scale(timeScale) { if (timeScale !== 1) { const times = this.times; for (let i = 0, n = times.length; i !== n; ++i) { times[i] *= timeScale; } } return this; } trim(startTime, endTime) { const times = this.times, nKeys = times.length; let from = 0, to = nKeys - 1; while (from !== nKeys && times[from] < startTime) { ++from; } while (to !== -1 && times[to] > endTime) { --to; } ++to; if (from !== 0 || to !== nKeys) { if (from >= to) { to = Math.max(to, 1); from = to - 1; } const stride = this.getValueSize(); this.times = AnimationUtils.arraySlice(times, from, to); this.values = AnimationUtils.arraySlice(this.values, from * stride, to * stride); } return this; } validate() { let valid = true; const valueSize = this.getValueSize(); if (valueSize - Math.floor(valueSize) !== 0) { console.error("THREE.KeyframeTrack: Invalid value size in track.", this); valid = false; } const times = this.times, values = this.values, nKeys = times.length; if (nKeys === 0) { console.error("THREE.KeyframeTrack: Track is empty.", this); valid = false; } let prevTime = null; for (let i = 0; i !== nKeys; i++) { const currTime = times[i]; if (typeof currTime === "number" && isNaN(currTime)) { console.error("THREE.KeyframeTrack: Time is not a valid number.", this, i, currTime); valid = false; break; } if (prevTime !== null && prevTime > currTime) { console.error("THREE.KeyframeTrack: Out of order keys.", this, i, currTime, prevTime); valid = false; break; } prevTime = currTime; } if (values !== void 0) { if (AnimationUtils.isTypedArray(values)) { for (let i = 0, n = values.length; i !== n; ++i) { const value = values[i]; if (isNaN(value)) { console.error("THREE.KeyframeTrack: Value is not a valid number.", this, i, value); valid = false; break; } } } } return valid; } optimize() { const times = AnimationUtils.arraySlice(this.times), values = AnimationUtils.arraySlice(this.values), stride = this.getValueSize(), smoothInterpolation = this.getInterpolation() === InterpolateSmooth, lastIndex = times.length - 1; let writeIndex = 1; for (let i = 1; i < lastIndex; ++i) { let keep = false; const time = times[i]; const timeNext = times[i + 1]; if (time !== timeNext && (i !== 1 || time !== times[0])) { if (!smoothInterpolation) { const offset = i * stride, offsetP = offset - stride, offsetN = offset + stride; for (let j = 0; j !== stride; ++j) { const value = values[offset + j]; if (value !== values[offsetP + j] || value !== values[offsetN + j]) { keep = true; break; } } } else { keep = true; } } if (keep) { if (i !== writeIndex) { times[writeIndex] = times[i]; const readOffset = i * stride, writeOffset = writeIndex * stride; for (let j = 0; j !== stride; ++j) { values[writeOffset + j] = values[readOffset + j]; } } ++writeIndex; } } if (lastIndex > 0) { times[writeIndex] = times[lastIndex]; for (let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++j) { values[writeOffset + j] = values[readOffset + j]; } ++writeIndex; } if (writeIndex !== times.length) { this.times = AnimationUtils.arraySlice(times, 0, writeIndex); this.values = AnimationUtils.arraySlice(values, 0, writeIndex * stride); } else { this.times = times; this.values = values; } return this; } clone() { const times = AnimationUtils.arraySlice(this.times, 0); const values = AnimationUtils.arraySlice(this.values, 0); const TypedKeyframeTrack = this.constructor; const track = new TypedKeyframeTrack(this.name, times, values); track.createInterpolant = this.createInterpolant; return track; } }; KeyframeTrack.prototype.TimeBufferType = Float32Array; KeyframeTrack.prototype.ValueBufferType = Float32Array; KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; var BooleanKeyframeTrack = class extends KeyframeTrack { }; BooleanKeyframeTrack.prototype.ValueTypeName = "bool"; BooleanKeyframeTrack.prototype.ValueBufferType = Array; BooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; BooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = void 0; BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = void 0; var ColorKeyframeTrack = class extends KeyframeTrack { }; ColorKeyframeTrack.prototype.ValueTypeName = "color"; var NumberKeyframeTrack = class extends KeyframeTrack { }; NumberKeyframeTrack.prototype.ValueTypeName = "number"; var QuaternionLinearInterpolant = class extends Interpolant { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); } interpolate_(i1, t0, t, t1) { const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, alpha = (t - t0) / (t1 - t0); let offset = i1 * stride; for (let end = offset + stride; offset !== end; offset += 4) { Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha); } return result; } }; var QuaternionKeyframeTrack = class extends KeyframeTrack { InterpolantFactoryMethodLinear(result) { return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result); } }; QuaternionKeyframeTrack.prototype.ValueTypeName = "quaternion"; QuaternionKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear; QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = void 0; var StringKeyframeTrack = class extends KeyframeTrack { }; StringKeyframeTrack.prototype.ValueTypeName = "string"; StringKeyframeTrack.prototype.ValueBufferType = Array; StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete; StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = void 0; StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = void 0; var VectorKeyframeTrack = class extends KeyframeTrack { }; VectorKeyframeTrack.prototype.ValueTypeName = "vector"; var AnimationClip = class { constructor(name, duration = -1, tracks, blendMode = NormalAnimationBlendMode) { this.name = name; this.tracks = tracks; this.duration = duration; this.blendMode = blendMode; this.uuid = generateUUID(); if (this.duration < 0) { this.resetDuration(); } } static parse(json) { const tracks = [], jsonTracks = json.tracks, frameTime = 1 / (json.fps || 1); for (let i = 0, n = jsonTracks.length; i !== n; ++i) { tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime)); } const clip = new this(json.name, json.duration, tracks, json.blendMode); clip.uuid = json.uuid; return clip; } static toJSON(clip) { const tracks = [], clipTracks = clip.tracks; const json = { "name": clip.name, "duration": clip.duration, "tracks": tracks, "uuid": clip.uuid, "blendMode": clip.blendMode }; for (let i = 0, n = clipTracks.length; i !== n; ++i) { tracks.push(KeyframeTrack.toJSON(clipTracks[i])); } return json; } static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) { const numMorphTargets = morphTargetSequence.length; const tracks = []; for (let i = 0; i < numMorphTargets; i++) { let times = []; let values = []; times.push((i + numMorphTargets - 1) % numMorphTargets, i, (i + 1) % numMorphTargets); values.push(0, 1, 0); const order = AnimationUtils.getKeyframeOrder(times); times = AnimationUtils.sortedArray(times, 1, order); values = AnimationUtils.sortedArray(values, 1, order); if (!noLoop && times[0] === 0) { times.push(numMorphTargets); values.push(values[0]); } tracks.push(new NumberKeyframeTrack(".morphTargetInfluences[" + morphTargetSequence[i].name + "]", times, values).scale(1 / fps)); } return new this(name, -1, tracks); } static findByName(objectOrClipArray, name) { let clipArray = objectOrClipArray; if (!Array.isArray(objectOrClipArray)) { const o = objectOrClipArray; clipArray = o.geometry && o.geometry.animations || o.animations; } for (let i = 0; i < clipArray.length; i++) { if (clipArray[i].name === name) { return clipArray[i]; } } return null; } static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) { const animationToMorphTargets = {}; const pattern = /^([\w-]*?)([\d]+)$/; for (let i = 0, il = morphTargets.length; i < il; i++) { const morphTarget = morphTargets[i]; const parts = morphTarget.name.match(pattern); if (parts && parts.length > 1) { const name = parts[1]; let animationMorphTargets = animationToMorphTargets[name]; if (!animationMorphTargets) { animationToMorphTargets[name] = animationMorphTargets = []; } animationMorphTargets.push(morphTarget); } } const clips = []; for (const name in animationToMorphTargets) { clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop)); } return clips; } static parseAnimation(animation, bones) { if (!animation) { console.error("THREE.AnimationClip: No animation in JSONLoader data."); return null; } const addNonemptyTrack = function(trackType, trackName, animationKeys, propertyName, destTracks) { if (animationKeys.length !== 0) { const times = []; const values = []; AnimationUtils.flattenJSON(animationKeys, times, values, propertyName); if (times.length !== 0) { destTracks.push(new trackType(trackName, times, values)); } } }; const tracks = []; const clipName = animation.name || "default"; const fps = animation.fps || 30; const blendMode = animation.blendMode; let duration = animation.length || -1; const hierarchyTracks = animation.hierarchy || []; for (let h = 0; h < hierarchyTracks.length; h++) { const animationKeys = hierarchyTracks[h].keys; if (!animationKeys || animationKeys.length === 0) continue; if (animationKeys[0].morphTargets) { const morphTargetNames = {}; let k; for (k = 0; k < animationKeys.length; k++) { if (animationKeys[k].morphTargets) { for (let m = 0; m < animationKeys[k].morphTargets.length; m++) { morphTargetNames[animationKeys[k].morphTargets[m]] = -1; } } } for (const morphTargetName in morphTargetNames) { const times = []; const values = []; for (let m = 0; m !== animationKeys[k].morphTargets.length; ++m) { const animationKey = animationKeys[k]; times.push(animationKey.time); values.push(animationKey.morphTarget === morphTargetName ? 1 : 0); } tracks.push(new NumberKeyframeTrack(".morphTargetInfluence[" + morphTargetName + "]", times, values)); } duration = morphTargetNames.length * (fps || 1); } else { const boneName = ".bones[" + bones[h].name + "]"; addNonemptyTrack(VectorKeyframeTrack, boneName + ".position", animationKeys, "pos", tracks); addNonemptyTrack(QuaternionKeyframeTrack, boneName + ".quaternion", animationKeys, "rot", tracks); addNonemptyTrack(VectorKeyframeTrack, boneName + ".scale", animationKeys, "scl", tracks); } } if (tracks.length === 0) { return null; } const clip = new this(clipName, duration, tracks, blendMode); return clip; } resetDuration() { const tracks = this.tracks; let duration = 0; for (let i = 0, n = tracks.length; i !== n; ++i) { const track = this.tracks[i]; duration = Math.max(duration, track.times[track.times.length - 1]); } this.duration = duration; return this; } trim() { for (let i = 0; i < this.tracks.length; i++) { this.tracks[i].trim(0, this.duration); } return this; } validate() { let valid = true; for (let i = 0; i < this.tracks.length; i++) { valid = valid && this.tracks[i].validate(); } return valid; } optimize() { for (let i = 0; i < this.tracks.length; i++) { this.tracks[i].optimize(); } return this; } clone() { const tracks = []; for (let i = 0; i < this.tracks.length; i++) { tracks.push(this.tracks[i].clone()); } return new this.constructor(this.name, this.duration, tracks, this.blendMode); } toJSON() { return this.constructor.toJSON(this); } }; function getTrackTypeForValueTypeName(typeName) { switch (typeName.toLowerCase()) { case "scalar": case "double": case "float": case "number": case "integer": return NumberKeyframeTrack; case "vector": case "vector2": case "vector3": case "vector4": return VectorKeyframeTrack; case "color": return ColorKeyframeTrack; case "quaternion": return QuaternionKeyframeTrack; case "bool": case "boolean": return BooleanKeyframeTrack; case "string": return StringKeyframeTrack; } throw new Error("THREE.KeyframeTrack: Unsupported typeName: " + typeName); } function parseKeyframeTrack(json) { if (json.type === void 0) { throw new Error("THREE.KeyframeTrack: track type undefined, can not parse"); } const trackType = getTrackTypeForValueTypeName(json.type); if (json.times === void 0) { const times = [], values = []; AnimationUtils.flattenJSON(json.keys, times, values, "value"); json.times = times; json.values = values; } if (trackType.parse !== void 0) { return trackType.parse(json); } else { return new trackType(json.name, json.times, json.values, json.interpolation); } } var Cache = { enabled: false, files: {}, add: function(key, file) { if (this.enabled === false) return; this.files[key] = file; }, get: function(key) { if (this.enabled === false) return; return this.files[key]; }, remove: function(key) { delete this.files[key]; }, clear: function() { this.files = {}; } }; var LoadingManager = class { constructor(onLoad, onProgress, onError) { const scope = this; let isLoading = false; let itemsLoaded = 0; let itemsTotal = 0; let urlModifier = void 0; const handlers = []; this.onStart = void 0; this.onLoad = onLoad; this.onProgress = onProgress; this.onError = onError; this.itemStart = function(url) { itemsTotal++; if (isLoading === false) { if (scope.onStart !== void 0) { scope.onStart(url, itemsLoaded, itemsTotal); } } isLoading = true; }; this.itemEnd = function(url) { itemsLoaded++; if (scope.onProgress !== void 0) { scope.onProgress(url, itemsLoaded, itemsTotal); } if (itemsLoaded === itemsTotal) { isLoading = false; if (scope.onLoad !== void 0) { scope.onLoad(); } } }; this.itemError = function(url) { if (scope.onError !== void 0) { scope.onError(url); } }; this.resolveURL = function(url) { if (urlModifier) { return urlModifier(url); } return url; }; this.setURLModifier = function(transform) { urlModifier = transform; return this; }; this.addHandler = function(regex, loader) { handlers.push(regex, loader); return this; }; this.removeHandler = function(regex) { const index = handlers.indexOf(regex); if (index !== -1) { handlers.splice(index, 2); } return this; }; this.getHandler = function(file) { for (let i = 0, l = handlers.length; i < l; i += 2) { const regex = handlers[i]; const loader = handlers[i + 1]; if (regex.global) regex.lastIndex = 0; if (regex.test(file)) { return loader; } } return null; }; } }; var DefaultLoadingManager = new LoadingManager(); var Loader = class { constructor(manager) { this.manager = manager !== void 0 ? manager : DefaultLoadingManager; this.crossOrigin = "anonymous"; this.withCredentials = false; this.path = ""; this.resourcePath = ""; this.requestHeader = {}; } load() { } loadAsync(url, onProgress) { const scope = this; return new Promise(function(resolve2, reject2) { scope.load(url, resolve2, onProgress, reject2); }); } parse() { } setCrossOrigin(crossOrigin) { this.crossOrigin = crossOrigin; return this; } setWithCredentials(value) { this.withCredentials = value; return this; } setPath(path) { this.path = path; return this; } setResourcePath(resourcePath) { this.resourcePath = resourcePath; return this; } setRequestHeader(requestHeader) { this.requestHeader = requestHeader; return this; } }; var loading = {}; var FileLoader = class extends Loader { constructor(manager) { super(manager); } load(url, onLoad, onProgress, onError) { if (url === void 0) url = ""; if (this.path !== void 0) url = this.path + url; url = this.manager.resolveURL(url); const scope = this; const cached = Cache.get(url); if (cached !== void 0) { scope.manager.itemStart(url); setTimeout(function() { if (onLoad) onLoad(cached); scope.manager.itemEnd(url); }, 0); return cached; } if (loading[url] !== void 0) { loading[url].push({ onLoad, onProgress, onError }); return; } const dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/; const dataUriRegexResult = url.match(dataUriRegex); let request; if (dataUriRegexResult) { const mimeType = dataUriRegexResult[1]; const isBase64 = !!dataUriRegexResult[2]; let data = dataUriRegexResult[3]; data = decodeURIComponent(data); if (isBase64) data = atob(data); try { let response; const responseType = (this.responseType || "").toLowerCase(); switch (responseType) { case "arraybuffer": case "blob": const view = new Uint8Array(data.length); for (let i = 0; i < data.length; i++) { view[i] = data.charCodeAt(i); } if (responseType === "blob") { response = new Blob([view.buffer], { type: mimeType }); } else { response = view.buffer; } break; case "document": const parser = new DOMParser(); response = parser.parseFromString(data, mimeType); break; case "json": response = JSON.parse(data); break; default: response = data; break; } setTimeout(function() { if (onLoad) onLoad(response); scope.manager.itemEnd(url); }, 0); } catch (error) { setTimeout(function() { if (onError) onError(error); scope.manager.itemError(url); scope.manager.itemEnd(url); }, 0); } } else { loading[url] = []; loading[url].push({ onLoad, onProgress, onError }); request = new XMLHttpRequest(); request.open("GET", url, true); request.addEventListener("load", function(event) { const response = this.response; const callbacks = loading[url]; delete loading[url]; if (this.status === 200 || this.status === 0) { if (this.status === 0) console.warn("THREE.FileLoader: HTTP Status 0 received."); Cache.add(url, response); for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onLoad) callback.onLoad(response); } scope.manager.itemEnd(url); } else { for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onError) callback.onError(event); } scope.manager.itemError(url); scope.manager.itemEnd(url); } }, false); request.addEventListener("progress", function(event) { const callbacks = loading[url]; for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onProgress) callback.onProgress(event); } }, false); request.addEventListener("error", function(event) { const callbacks = loading[url]; delete loading[url]; for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onError) callback.onError(event); } scope.manager.itemError(url); scope.manager.itemEnd(url); }, false); request.addEventListener("abort", function(event) { const callbacks = loading[url]; delete loading[url]; for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onError) callback.onError(event); } scope.manager.itemError(url); scope.manager.itemEnd(url); }, false); if (this.responseType !== void 0) request.responseType = this.responseType; if (this.withCredentials !== void 0) request.withCredentials = this.withCredentials; if (request.overrideMimeType) request.overrideMimeType(this.mimeType !== void 0 ? this.mimeType : "text/plain"); for (const header in this.requestHeader) { request.setRequestHeader(header, this.requestHeader[header]); } request.send(null); } scope.manager.itemStart(url); return request; } setResponseType(value) { this.responseType = value; return this; } setMimeType(value) { this.mimeType = value; return this; } }; var ImageLoader = class extends Loader { constructor(manager) { super(manager); } load(url, onLoad, onProgress, onError) { if (this.path !== void 0) url = this.path + url; url = this.manager.resolveURL(url); const scope = this; const cached = Cache.get(url); if (cached !== void 0) { scope.manager.itemStart(url); setTimeout(function() { if (onLoad) onLoad(cached); scope.manager.itemEnd(url); }, 0); return cached; } const image = document.createElementNS("http://www.w3.org/1999/xhtml", "img"); function onImageLoad() { image.removeEventListener("load", onImageLoad, false); image.removeEventListener("error", onImageError, false); Cache.add(url, this); if (onLoad) onLoad(this); scope.manager.itemEnd(url); } function onImageError(event) { image.removeEventListener("load", onImageLoad, false); image.removeEventListener("error", onImageError, false); if (onError) onError(event); scope.manager.itemError(url); scope.manager.itemEnd(url); } image.addEventListener("load", onImageLoad, false); image.addEventListener("error", onImageError, false); if (url.substr(0, 5) !== "data:") { if (this.crossOrigin !== void 0) image.crossOrigin = this.crossOrigin; } scope.manager.itemStart(url); image.src = url; return image; } }; var CubeTextureLoader = class extends Loader { constructor(manager) { super(manager); } load(urls, onLoad, onProgress, onError) { const texture = new CubeTexture(); const loader = new ImageLoader(this.manager); loader.setCrossOrigin(this.crossOrigin); loader.setPath(this.path); let loaded2 = 0; function loadTexture(i) { loader.load(urls[i], function(image) { texture.images[i] = image; loaded2++; if (loaded2 === 6) { texture.needsUpdate = true; if (onLoad) onLoad(texture); } }, void 0, onError); } for (let i = 0; i < urls.length; ++i) { loadTexture(i); } return texture; } }; var TextureLoader = class extends Loader { constructor(manager) { super(manager); } load(url, onLoad, onProgress, onError) { const texture = new Texture(); const loader = new ImageLoader(this.manager); loader.setCrossOrigin(this.crossOrigin); loader.setPath(this.path); loader.load(url, function(image) { texture.image = image; const isJPEG = url.search(/\.jpe?g($|\?)/i) > 0 || url.search(/^data\:image\/jpeg/) === 0; texture.format = isJPEG ? RGBFormat : RGBAFormat; texture.needsUpdate = true; if (onLoad !== void 0) { onLoad(texture); } }, onProgress, onError); return texture; } }; var CurvePath = class extends Curve { constructor() { super(); this.type = "CurvePath"; this.curves = []; this.autoClose = false; } add(curve) { this.curves.push(curve); } closePath() { const startPoint = this.curves[0].getPoint(0); const endPoint = this.curves[this.curves.length - 1].getPoint(1); if (!startPoint.equals(endPoint)) { this.curves.push(new LineCurve(endPoint, startPoint)); } } getPoint(t) { const d = t * this.getLength(); const curveLengths = this.getCurveLengths(); let i = 0; while (i < curveLengths.length) { if (curveLengths[i] >= d) { const diff = curveLengths[i] - d; const curve = this.curves[i]; const segmentLength = curve.getLength(); const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength; return curve.getPointAt(u); } i++; } return null; } getLength() { const lens = this.getCurveLengths(); return lens[lens.length - 1]; } updateArcLengths() { this.needsUpdate = true; this.cacheLengths = null; this.getCurveLengths(); } getCurveLengths() { if (this.cacheLengths && this.cacheLengths.length === this.curves.length) { return this.cacheLengths; } const lengths = []; let sums = 0; for (let i = 0, l = this.curves.length; i < l; i++) { sums += this.curves[i].getLength(); lengths.push(sums); } this.cacheLengths = lengths; return lengths; } getSpacedPoints(divisions = 40) { const points = []; for (let i = 0; i <= divisions; i++) { points.push(this.getPoint(i / divisions)); } if (this.autoClose) { points.push(points[0]); } return points; } getPoints(divisions = 12) { const points = []; let last; for (let i = 0, curves = this.curves; i < curves.length; i++) { const curve = curves[i]; const resolution = curve && curve.isEllipseCurve ? divisions * 2 : curve && (curve.isLineCurve || curve.isLineCurve3) ? 1 : curve && curve.isSplineCurve ? divisions * curve.points.length : divisions; const pts = curve.getPoints(resolution); for (let j = 0; j < pts.length; j++) { const point = pts[j]; if (last && last.equals(point)) continue; points.push(point); last = point; } } if (this.autoClose && points.length > 1 && !points[points.length - 1].equals(points[0])) { points.push(points[0]); } return points; } copy(source) { super.copy(source); this.curves = []; for (let i = 0, l = source.curves.length; i < l; i++) { const curve = source.curves[i]; this.curves.push(curve.clone()); } this.autoClose = source.autoClose; return this; } toJSON() { const data = super.toJSON(); data.autoClose = this.autoClose; data.curves = []; for (let i = 0, l = this.curves.length; i < l; i++) { const curve = this.curves[i]; data.curves.push(curve.toJSON()); } return data; } fromJSON(json) { super.fromJSON(json); this.autoClose = json.autoClose; this.curves = []; for (let i = 0, l = json.curves.length; i < l; i++) { const curve = json.curves[i]; this.curves.push(new Curves[curve.type]().fromJSON(curve)); } return this; } }; var Path = class extends CurvePath { constructor(points) { super(); this.type = "Path"; this.currentPoint = new Vector2(); if (points) { this.setFromPoints(points); } } setFromPoints(points) { this.moveTo(points[0].x, points[0].y); for (let i = 1, l = points.length; i < l; i++) { this.lineTo(points[i].x, points[i].y); } return this; } moveTo(x, y) { this.currentPoint.set(x, y); return this; } lineTo(x, y) { const curve = new LineCurve(this.currentPoint.clone(), new Vector2(x, y)); this.curves.push(curve); this.currentPoint.set(x, y); return this; } quadraticCurveTo(aCPx, aCPy, aX, aY) { const curve = new QuadraticBezierCurve(this.currentPoint.clone(), new Vector2(aCPx, aCPy), new Vector2(aX, aY)); this.curves.push(curve); this.currentPoint.set(aX, aY); return this; } bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { const curve = new CubicBezierCurve(this.currentPoint.clone(), new Vector2(aCP1x, aCP1y), new Vector2(aCP2x, aCP2y), new Vector2(aX, aY)); this.curves.push(curve); this.currentPoint.set(aX, aY); return this; } splineThru(pts) { const npts = [this.currentPoint.clone()].concat(pts); const curve = new SplineCurve(npts); this.curves.push(curve); this.currentPoint.copy(pts[pts.length - 1]); return this; } arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { const x0 = this.currentPoint.x; const y0 = this.currentPoint.y; this.absarc(aX + x0, aY + y0, aRadius, aStartAngle, aEndAngle, aClockwise); return this; } absarc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); return this; } ellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { const x0 = this.currentPoint.x; const y0 = this.currentPoint.y; this.absellipse(aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); return this; } absellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) { const curve = new EllipseCurve(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation); if (this.curves.length > 0) { const firstPoint = curve.getPoint(0); if (!firstPoint.equals(this.currentPoint)) { this.lineTo(firstPoint.x, firstPoint.y); } } this.curves.push(curve); const lastPoint = curve.getPoint(1); this.currentPoint.copy(lastPoint); return this; } copy(source) { super.copy(source); this.currentPoint.copy(source.currentPoint); return this; } toJSON() { const data = super.toJSON(); data.currentPoint = this.currentPoint.toArray(); return data; } fromJSON(json) { super.fromJSON(json); this.currentPoint.fromArray(json.currentPoint); return this; } }; var Shape = class extends Path { constructor(points) { super(points); this.uuid = generateUUID(); this.type = "Shape"; this.holes = []; } getPointsHoles(divisions) { const holesPts = []; for (let i = 0, l = this.holes.length; i < l; i++) { holesPts[i] = this.holes[i].getPoints(divisions); } return holesPts; } extractPoints(divisions) { return { shape: this.getPoints(divisions), holes: this.getPointsHoles(divisions) }; } copy(source) { super.copy(source); this.holes = []; for (let i = 0, l = source.holes.length; i < l; i++) { const hole = source.holes[i]; this.holes.push(hole.clone()); } return this; } toJSON() { const data = super.toJSON(); data.uuid = this.uuid; data.holes = []; for (let i = 0, l = this.holes.length; i < l; i++) { const hole = this.holes[i]; data.holes.push(hole.toJSON()); } return data; } fromJSON(json) { super.fromJSON(json); this.uuid = json.uuid; this.holes = []; for (let i = 0, l = json.holes.length; i < l; i++) { const hole = json.holes[i]; this.holes.push(new Path().fromJSON(hole)); } return this; } }; var Light = class extends Object3D { constructor(color, intensity = 1) { super(); this.type = "Light"; this.color = new Color(color); this.intensity = intensity; } dispose() { } copy(source) { super.copy(source); this.color.copy(source.color); this.intensity = source.intensity; return this; } toJSON(meta) { const data = super.toJSON(meta); data.object.color = this.color.getHex(); data.object.intensity = this.intensity; if (this.groundColor !== void 0) data.object.groundColor = this.groundColor.getHex(); if (this.distance !== void 0) data.object.distance = this.distance; if (this.angle !== void 0) data.object.angle = this.angle; if (this.decay !== void 0) data.object.decay = this.decay; if (this.penumbra !== void 0) data.object.penumbra = this.penumbra; if (this.shadow !== void 0) data.object.shadow = this.shadow.toJSON(); return data; } }; Light.prototype.isLight = true; var HemisphereLight = class extends Light { constructor(skyColor, groundColor, intensity) { super(skyColor, intensity); this.type = "HemisphereLight"; this.position.copy(Object3D.DefaultUp); this.updateMatrix(); this.groundColor = new Color(groundColor); } copy(source) { Light.prototype.copy.call(this, source); this.groundColor.copy(source.groundColor); return this; } }; HemisphereLight.prototype.isHemisphereLight = true; var _projScreenMatrix$1 = /* @__PURE__ */ new Matrix4(); var _lightPositionWorld$1 = /* @__PURE__ */ new Vector3(); var _lookTarget$1 = /* @__PURE__ */ new Vector3(); var LightShadow = class { constructor(camera) { this.camera = camera; this.bias = 0; this.normalBias = 0; this.radius = 1; this.blurSamples = 8; this.mapSize = new Vector2(512, 512); this.map = null; this.mapPass = null; this.matrix = new Matrix4(); this.autoUpdate = true; this.needsUpdate = false; this._frustum = new Frustum(); this._frameExtents = new Vector2(1, 1); this._viewportCount = 1; this._viewports = [ new Vector4(0, 0, 1, 1) ]; } getViewportCount() { return this._viewportCount; } getFrustum() { return this._frustum; } updateMatrices(light) { const shadowCamera = this.camera; const shadowMatrix = this.matrix; _lightPositionWorld$1.setFromMatrixPosition(light.matrixWorld); shadowCamera.position.copy(_lightPositionWorld$1); _lookTarget$1.setFromMatrixPosition(light.target.matrixWorld); shadowCamera.lookAt(_lookTarget$1); shadowCamera.updateMatrixWorld(); _projScreenMatrix$1.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); this._frustum.setFromProjectionMatrix(_projScreenMatrix$1); shadowMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1); shadowMatrix.multiply(shadowCamera.projectionMatrix); shadowMatrix.multiply(shadowCamera.matrixWorldInverse); } getViewport(viewportIndex) { return this._viewports[viewportIndex]; } getFrameExtents() { return this._frameExtents; } dispose() { if (this.map) { this.map.dispose(); } if (this.mapPass) { this.mapPass.dispose(); } } copy(source) { this.camera = source.camera.clone(); this.bias = source.bias; this.radius = source.radius; this.mapSize.copy(source.mapSize); return this; } clone() { return new this.constructor().copy(this); } toJSON() { const object = {}; if (this.bias !== 0) object.bias = this.bias; if (this.normalBias !== 0) object.normalBias = this.normalBias; if (this.radius !== 1) object.radius = this.radius; if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray(); object.camera = this.camera.toJSON(false).object; delete object.camera.matrix; return object; } }; var SpotLightShadow = class extends LightShadow { constructor() { super(new PerspectiveCamera(50, 1, 0.5, 500)); this.focus = 1; } updateMatrices(light) { const camera = this.camera; const fov2 = RAD2DEG * 2 * light.angle * this.focus; const aspect2 = this.mapSize.width / this.mapSize.height; const far = light.distance || camera.far; if (fov2 !== camera.fov || aspect2 !== camera.aspect || far !== camera.far) { camera.fov = fov2; camera.aspect = aspect2; camera.far = far; camera.updateProjectionMatrix(); } super.updateMatrices(light); } copy(source) { super.copy(source); this.focus = source.focus; return this; } }; SpotLightShadow.prototype.isSpotLightShadow = true; var SpotLight = class extends Light { constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1) { super(color, intensity); this.type = "SpotLight"; this.position.copy(Object3D.DefaultUp); this.updateMatrix(); this.target = new Object3D(); this.distance = distance; this.angle = angle; this.penumbra = penumbra; this.decay = decay; this.shadow = new SpotLightShadow(); } get power() { return this.intensity * Math.PI; } set power(power) { this.intensity = power / Math.PI; } dispose() { this.shadow.dispose(); } copy(source) { super.copy(source); this.distance = source.distance; this.angle = source.angle; this.penumbra = source.penumbra; this.decay = source.decay; this.target = source.target.clone(); this.shadow = source.shadow.clone(); return this; } }; SpotLight.prototype.isSpotLight = true; var _projScreenMatrix = /* @__PURE__ */ new Matrix4(); var _lightPositionWorld = /* @__PURE__ */ new Vector3(); var _lookTarget = /* @__PURE__ */ new Vector3(); var PointLightShadow = class extends LightShadow { constructor() { super(new PerspectiveCamera(90, 1, 0.5, 500)); this._frameExtents = new Vector2(4, 2); this._viewportCount = 6; this._viewports = [ new Vector4(2, 1, 1, 1), new Vector4(0, 1, 1, 1), new Vector4(3, 1, 1, 1), new Vector4(1, 1, 1, 1), new Vector4(3, 0, 1, 1), new Vector4(1, 0, 1, 1) ]; this._cubeDirections = [ new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1), new Vector3(0, 1, 0), new Vector3(0, -1, 0) ]; this._cubeUps = [ new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1) ]; } updateMatrices(light, viewportIndex = 0) { const camera = this.camera; const shadowMatrix = this.matrix; const far = light.distance || camera.far; if (far !== camera.far) { camera.far = far; camera.updateProjectionMatrix(); } _lightPositionWorld.setFromMatrixPosition(light.matrixWorld); camera.position.copy(_lightPositionWorld); _lookTarget.copy(camera.position); _lookTarget.add(this._cubeDirections[viewportIndex]); camera.up.copy(this._cubeUps[viewportIndex]); camera.lookAt(_lookTarget); camera.updateMatrixWorld(); shadowMatrix.makeTranslation(-_lightPositionWorld.x, -_lightPositionWorld.y, -_lightPositionWorld.z); _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); this._frustum.setFromProjectionMatrix(_projScreenMatrix); } }; PointLightShadow.prototype.isPointLightShadow = true; var PointLight = class extends Light { constructor(color, intensity, distance = 0, decay = 1) { super(color, intensity); this.type = "PointLight"; this.distance = distance; this.decay = decay; this.shadow = new PointLightShadow(); } get power() { return this.intensity * 4 * Math.PI; } set power(power) { this.intensity = power / (4 * Math.PI); } dispose() { this.shadow.dispose(); } copy(source) { super.copy(source); this.distance = source.distance; this.decay = source.decay; this.shadow = source.shadow.clone(); return this; } }; PointLight.prototype.isPointLight = true; var DirectionalLightShadow = class extends LightShadow { constructor() { super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500)); } }; DirectionalLightShadow.prototype.isDirectionalLightShadow = true; var DirectionalLight = class extends Light { constructor(color, intensity) { super(color, intensity); this.type = "DirectionalLight"; this.position.copy(Object3D.DefaultUp); this.updateMatrix(); this.target = new Object3D(); this.shadow = new DirectionalLightShadow(); } dispose() { this.shadow.dispose(); } copy(source) { super.copy(source); this.target = source.target.clone(); this.shadow = source.shadow.clone(); return this; } }; DirectionalLight.prototype.isDirectionalLight = true; var AmbientLight = class extends Light { constructor(color, intensity) { super(color, intensity); this.type = "AmbientLight"; } }; AmbientLight.prototype.isAmbientLight = true; var RectAreaLight = class extends Light { constructor(color, intensity, width = 10, height = 10) { super(color, intensity); this.type = "RectAreaLight"; this.width = width; this.height = height; } get power() { return this.intensity * this.width * this.height * Math.PI; } set power(power) { this.intensity = power / (this.width * this.height * Math.PI); } copy(source) { super.copy(source); this.width = source.width; this.height = source.height; return this; } toJSON(meta) { const data = super.toJSON(meta); data.object.width = this.width; data.object.height = this.height; return data; } }; RectAreaLight.prototype.isRectAreaLight = true; var SphericalHarmonics3 = class { constructor() { this.coefficients = []; for (let i = 0; i < 9; i++) { this.coefficients.push(new Vector3()); } } set(coefficients) { for (let i = 0; i < 9; i++) { this.coefficients[i].copy(coefficients[i]); } return this; } zero() { for (let i = 0; i < 9; i++) { this.coefficients[i].set(0, 0, 0); } return this; } getAt(normal, target) { const x = normal.x, y = normal.y, z = normal.z; const coeff = this.coefficients; target.copy(coeff[0]).multiplyScalar(0.282095); target.addScaledVector(coeff[1], 0.488603 * y); target.addScaledVector(coeff[2], 0.488603 * z); target.addScaledVector(coeff[3], 0.488603 * x); target.addScaledVector(coeff[4], 1.092548 * (x * y)); target.addScaledVector(coeff[5], 1.092548 * (y * z)); target.addScaledVector(coeff[6], 0.315392 * (3 * z * z - 1)); target.addScaledVector(coeff[7], 1.092548 * (x * z)); target.addScaledVector(coeff[8], 0.546274 * (x * x - y * y)); return target; } getIrradianceAt(normal, target) { const x = normal.x, y = normal.y, z = normal.z; const coeff = this.coefficients; target.copy(coeff[0]).multiplyScalar(0.886227); target.addScaledVector(coeff[1], 2 * 0.511664 * y); target.addScaledVector(coeff[2], 2 * 0.511664 * z); target.addScaledVector(coeff[3], 2 * 0.511664 * x); target.addScaledVector(coeff[4], 2 * 0.429043 * x * y); target.addScaledVector(coeff[5], 2 * 0.429043 * y * z); target.addScaledVector(coeff[6], 0.743125 * z * z - 0.247708); target.addScaledVector(coeff[7], 2 * 0.429043 * x * z); target.addScaledVector(coeff[8], 0.429043 * (x * x - y * y)); return target; } add(sh) { for (let i = 0; i < 9; i++) { this.coefficients[i].add(sh.coefficients[i]); } return this; } addScaledSH(sh, s) { for (let i = 0; i < 9; i++) { this.coefficients[i].addScaledVector(sh.coefficients[i], s); } return this; } scale(s) { for (let i = 0; i < 9; i++) { this.coefficients[i].multiplyScalar(s); } return this; } lerp(sh, alpha) { for (let i = 0; i < 9; i++) { this.coefficients[i].lerp(sh.coefficients[i], alpha); } return this; } equals(sh) { for (let i = 0; i < 9; i++) { if (!this.coefficients[i].equals(sh.coefficients[i])) { return false; } } return true; } copy(sh) { return this.set(sh.coefficients); } clone() { return new this.constructor().copy(this); } fromArray(array, offset = 0) { const coefficients = this.coefficients; for (let i = 0; i < 9; i++) { coefficients[i].fromArray(array, offset + i * 3); } return this; } toArray(array = [], offset = 0) { const coefficients = this.coefficients; for (let i = 0; i < 9; i++) { coefficients[i].toArray(array, offset + i * 3); } return array; } static getBasisAt(normal, shBasis) { const x = normal.x, y = normal.y, z = normal.z; shBasis[0] = 0.282095; shBasis[1] = 0.488603 * y; shBasis[2] = 0.488603 * z; shBasis[3] = 0.488603 * x; shBasis[4] = 1.092548 * x * y; shBasis[5] = 1.092548 * y * z; shBasis[6] = 0.315392 * (3 * z * z - 1); shBasis[7] = 1.092548 * x * z; shBasis[8] = 0.546274 * (x * x - y * y); } }; SphericalHarmonics3.prototype.isSphericalHarmonics3 = true; var LightProbe = class extends Light { constructor(sh = new SphericalHarmonics3(), intensity = 1) { super(void 0, intensity); this.sh = sh; } copy(source) { super.copy(source); this.sh.copy(source.sh); return this; } fromJSON(json) { this.intensity = json.intensity; this.sh.fromArray(json.sh); return this; } toJSON(meta) { const data = super.toJSON(meta); data.object.sh = this.sh.toArray(); return data; } }; LightProbe.prototype.isLightProbe = true; var LoaderUtils = class { static decodeText(array) { if (typeof TextDecoder !== "undefined") { return new TextDecoder().decode(array); } let s = ""; for (let i = 0, il = array.length; i < il; i++) { s += String.fromCharCode(array[i]); } try { return decodeURIComponent(escape(s)); } catch (e) { return s; } } static extractUrlBase(url) { const index = url.lastIndexOf("/"); if (index === -1) return "./"; return url.substr(0, index + 1); } }; var InstancedBufferGeometry = class extends BufferGeometry { constructor() { super(); this.type = "InstancedBufferGeometry"; this.instanceCount = Infinity; } copy(source) { super.copy(source); this.instanceCount = source.instanceCount; return this; } clone() { return new this.constructor().copy(this); } toJSON() { const data = super.toJSON(this); data.instanceCount = this.instanceCount; data.isInstancedBufferGeometry = true; return data; } }; InstancedBufferGeometry.prototype.isInstancedBufferGeometry = true; var ImageBitmapLoader = class extends Loader { constructor(manager) { super(manager); if (typeof createImageBitmap === "undefined") { console.warn("THREE.ImageBitmapLoader: createImageBitmap() not supported."); } if (typeof fetch === "undefined") { console.warn("THREE.ImageBitmapLoader: fetch() not supported."); } this.options = { premultiplyAlpha: "none" }; } setOptions(options) { this.options = options; return this; } load(url, onLoad, onProgress, onError) { if (url === void 0) url = ""; if (this.path !== void 0) url = this.path + url; url = this.manager.resolveURL(url); const scope = this; const cached = Cache.get(url); if (cached !== void 0) { scope.manager.itemStart(url); setTimeout(function() { if (onLoad) onLoad(cached); scope.manager.itemEnd(url); }, 0); return cached; } const fetchOptions = {}; fetchOptions.credentials = this.crossOrigin === "anonymous" ? "same-origin" : "include"; fetchOptions.headers = this.requestHeader; fetch(url, fetchOptions).then(function(res) { return res.blob(); }).then(function(blob) { return createImageBitmap(blob, Object.assign(scope.options, { colorSpaceConversion: "none" })); }).then(function(imageBitmap) { Cache.add(url, imageBitmap); if (onLoad) onLoad(imageBitmap); scope.manager.itemEnd(url); }).catch(function(e) { if (onError) onError(e); scope.manager.itemError(url); scope.manager.itemEnd(url); }); scope.manager.itemStart(url); } }; ImageBitmapLoader.prototype.isImageBitmapLoader = true; var ShapePath = class { constructor() { this.type = "ShapePath"; this.color = new Color(); this.subPaths = []; this.currentPath = null; } moveTo(x, y) { this.currentPath = new Path(); this.subPaths.push(this.currentPath); this.currentPath.moveTo(x, y); return this; } lineTo(x, y) { this.currentPath.lineTo(x, y); return this; } quadraticCurveTo(aCPx, aCPy, aX, aY) { this.currentPath.quadraticCurveTo(aCPx, aCPy, aX, aY); return this; } bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { this.currentPath.bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY); return this; } splineThru(pts) { this.currentPath.splineThru(pts); return this; } toShapes(isCCW, noHoles) { function toShapesNoHoles(inSubpaths) { const shapes2 = []; for (let i = 0, l = inSubpaths.length; i < l; i++) { const tmpPath2 = inSubpaths[i]; const tmpShape2 = new Shape(); tmpShape2.curves = tmpPath2.curves; shapes2.push(tmpShape2); } return shapes2; } function isPointInsidePolygon(inPt, inPolygon) { const polyLen = inPolygon.length; let inside = false; for (let p2 = polyLen - 1, q = 0; q < polyLen; p2 = q++) { let edgeLowPt = inPolygon[p2]; let edgeHighPt = inPolygon[q]; let edgeDx = edgeHighPt.x - edgeLowPt.x; let edgeDy = edgeHighPt.y - edgeLowPt.y; if (Math.abs(edgeDy) > Number.EPSILON) { if (edgeDy < 0) { edgeLowPt = inPolygon[q]; edgeDx = -edgeDx; edgeHighPt = inPolygon[p2]; edgeDy = -edgeDy; } if (inPt.y < edgeLowPt.y || inPt.y > edgeHighPt.y) continue; if (inPt.y === edgeLowPt.y) { if (inPt.x === edgeLowPt.x) return true; } else { const perpEdge = edgeDy * (inPt.x - edgeLowPt.x) - edgeDx * (inPt.y - edgeLowPt.y); if (perpEdge === 0) return true; if (perpEdge < 0) continue; inside = !inside; } } else { if (inPt.y !== edgeLowPt.y) continue; if (edgeHighPt.x <= inPt.x && inPt.x <= edgeLowPt.x || edgeLowPt.x <= inPt.x && inPt.x <= edgeHighPt.x) return true; } } return inside; } const isClockWise = ShapeUtils.isClockWise; const subPaths = this.subPaths; if (subPaths.length === 0) return []; if (noHoles === true) return toShapesNoHoles(subPaths); let solid, tmpPath, tmpShape; const shapes = []; if (subPaths.length === 1) { tmpPath = subPaths[0]; tmpShape = new Shape(); tmpShape.curves = tmpPath.curves; shapes.push(tmpShape); return shapes; } let holesFirst = !isClockWise(subPaths[0].getPoints()); holesFirst = isCCW ? !holesFirst : holesFirst; const betterShapeHoles = []; const newShapes = []; let newShapeHoles = []; let mainIdx = 0; let tmpPoints; newShapes[mainIdx] = void 0; newShapeHoles[mainIdx] = []; for (let i = 0, l = subPaths.length; i < l; i++) { tmpPath = subPaths[i]; tmpPoints = tmpPath.getPoints(); solid = isClockWise(tmpPoints); solid = isCCW ? !solid : solid; if (solid) { if (!holesFirst && newShapes[mainIdx]) mainIdx++; newShapes[mainIdx] = { s: new Shape(), p: tmpPoints }; newShapes[mainIdx].s.curves = tmpPath.curves; if (holesFirst) mainIdx++; newShapeHoles[mainIdx] = []; } else { newShapeHoles[mainIdx].push({ h: tmpPath, p: tmpPoints[0] }); } } if (!newShapes[0]) return toShapesNoHoles(subPaths); if (newShapes.length > 1) { let ambiguous = false; const toChange = []; for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { betterShapeHoles[sIdx] = []; } for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) { const sho = newShapeHoles[sIdx]; for (let hIdx = 0; hIdx < sho.length; hIdx++) { const ho = sho[hIdx]; let hole_unassigned = true; for (let s2Idx = 0; s2Idx < newShapes.length; s2Idx++) { if (isPointInsidePolygon(ho.p, newShapes[s2Idx].p)) { if (sIdx !== s2Idx) toChange.push({ froms: sIdx, tos: s2Idx, hole: hIdx }); if (hole_unassigned) { hole_unassigned = false; betterShapeHoles[s2Idx].push(ho); } else { ambiguous = true; } } } if (hole_unassigned) { betterShapeHoles[sIdx].push(ho); } } } if (toChange.length > 0) { if (!ambiguous) newShapeHoles = betterShapeHoles; } } let tmpHoles; for (let i = 0, il = newShapes.length; i < il; i++) { tmpShape = newShapes[i].s; shapes.push(tmpShape); tmpHoles = newShapeHoles[i]; for (let j = 0, jl = tmpHoles.length; j < jl; j++) { tmpShape.holes.push(tmpHoles[j].h); } } return shapes; } }; var Font = class { constructor(data) { this.type = "Font"; this.data = data; } generateShapes(text, size = 100) { const shapes = []; const paths = createPaths(text, size, this.data); for (let p2 = 0, pl = paths.length; p2 < pl; p2++) { Array.prototype.push.apply(shapes, paths[p2].toShapes()); } return shapes; } }; function createPaths(text, size, data) { const chars = Array.from(text); const scale = size / data.resolution; const line_height = (data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness) * scale; const paths = []; let offsetX = 0, offsetY = 0; for (let i = 0; i < chars.length; i++) { const char = chars[i]; if (char === "\n") { offsetX = 0; offsetY -= line_height; } else { const ret = createPath(char, scale, offsetX, offsetY, data); offsetX += ret.offsetX; paths.push(ret.path); } } return paths; } function createPath(char, scale, offsetX, offsetY, data) { const glyph = data.glyphs[char] || data.glyphs["?"]; if (!glyph) { console.error('THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + "."); return; } const path = new ShapePath(); let x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2; if (glyph.o) { const outline = glyph._cachedOutline || (glyph._cachedOutline = glyph.o.split(" ")); for (let i = 0, l = outline.length; i < l; ) { const action = outline[i++]; switch (action) { case "m": x = outline[i++] * scale + offsetX; y = outline[i++] * scale + offsetY; path.moveTo(x, y); break; case "l": x = outline[i++] * scale + offsetX; y = outline[i++] * scale + offsetY; path.lineTo(x, y); break; case "q": cpx = outline[i++] * scale + offsetX; cpy = outline[i++] * scale + offsetY; cpx1 = outline[i++] * scale + offsetX; cpy1 = outline[i++] * scale + offsetY; path.quadraticCurveTo(cpx1, cpy1, cpx, cpy); break; case "b": cpx = outline[i++] * scale + offsetX; cpy = outline[i++] * scale + offsetY; cpx1 = outline[i++] * scale + offsetX; cpy1 = outline[i++] * scale + offsetY; cpx2 = outline[i++] * scale + offsetX; cpy2 = outline[i++] * scale + offsetY; path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, cpx, cpy); break; } } } return { offsetX: glyph.ha * scale, path }; } Font.prototype.isFont = true; var _context; var AudioContext = { getContext: function() { if (_context === void 0) { _context = new (window.AudioContext || window.webkitAudioContext)(); } return _context; }, setContext: function(value) { _context = value; } }; var AudioLoader = class extends Loader { constructor(manager) { super(manager); } load(url, onLoad, onProgress, onError) { const scope = this; const loader = new FileLoader(this.manager); loader.setResponseType("arraybuffer"); loader.setPath(this.path); loader.setRequestHeader(this.requestHeader); loader.setWithCredentials(this.withCredentials); loader.load(url, function(buffer) { try { const bufferCopy = buffer.slice(0); const context = AudioContext.getContext(); context.decodeAudioData(bufferCopy, function(audioBuffer) { onLoad(audioBuffer); }); } catch (e) { if (onError) { onError(e); } else { console.error(e); } scope.manager.itemError(url); } }, onProgress, onError); } }; var HemisphereLightProbe = class extends LightProbe { constructor(skyColor, groundColor, intensity = 1) { super(void 0, intensity); const color1 = new Color().set(skyColor); const color2 = new Color().set(groundColor); const sky = new Vector3(color1.r, color1.g, color1.b); const ground = new Vector3(color2.r, color2.g, color2.b); const c0 = Math.sqrt(Math.PI); const c1 = c0 * Math.sqrt(0.75); this.sh.coefficients[0].copy(sky).add(ground).multiplyScalar(c0); this.sh.coefficients[1].copy(sky).sub(ground).multiplyScalar(c1); } }; HemisphereLightProbe.prototype.isHemisphereLightProbe = true; var AmbientLightProbe = class extends LightProbe { constructor(color, intensity = 1) { super(void 0, intensity); const color1 = new Color().set(color); this.sh.coefficients[0].set(color1.r, color1.g, color1.b).multiplyScalar(2 * Math.sqrt(Math.PI)); } }; AmbientLightProbe.prototype.isAmbientLightProbe = true; var Audio = class extends Object3D { constructor(listener3) { super(); this.type = "Audio"; this.listener = listener3; this.context = listener3.context; this.gain = this.context.createGain(); this.gain.connect(listener3.getInput()); this.autoplay = false; this.buffer = null; this.detune = 0; this.loop = false; this.loopStart = 0; this.loopEnd = 0; this.offset = 0; this.duration = void 0; this.playbackRate = 1; this.isPlaying = false; this.hasPlaybackControl = true; this.source = null; this.sourceType = "empty"; this._startedAt = 0; this._progress = 0; this._connected = false; this.filters = []; } getOutput() { return this.gain; } setNodeSource(audioNode) { this.hasPlaybackControl = false; this.sourceType = "audioNode"; this.source = audioNode; this.connect(); return this; } setMediaElementSource(mediaElement) { this.hasPlaybackControl = false; this.sourceType = "mediaNode"; this.source = this.context.createMediaElementSource(mediaElement); this.connect(); return this; } setMediaStreamSource(mediaStream) { this.hasPlaybackControl = false; this.sourceType = "mediaStreamNode"; this.source = this.context.createMediaStreamSource(mediaStream); this.connect(); return this; } setBuffer(audioBuffer) { this.buffer = audioBuffer; this.sourceType = "buffer"; if (this.autoplay) this.play(); return this; } play(delay = 0) { if (this.isPlaying === true) { console.warn("THREE.Audio: Audio is already playing."); return; } if (this.hasPlaybackControl === false) { console.warn("THREE.Audio: this Audio has no playback control."); return; } this._startedAt = this.context.currentTime + delay; const source = this.context.createBufferSource(); source.buffer = this.buffer; source.loop = this.loop; source.loopStart = this.loopStart; source.loopEnd = this.loopEnd; source.onended = this.onEnded.bind(this); source.start(this._startedAt, this._progress + this.offset, this.duration); this.isPlaying = true; this.source = source; this.setDetune(this.detune); this.setPlaybackRate(this.playbackRate); return this.connect(); } pause() { if (this.hasPlaybackControl === false) { console.warn("THREE.Audio: this Audio has no playback control."); return; } if (this.isPlaying === true) { this._progress += Math.max(this.context.currentTime - this._startedAt, 0) * this.playbackRate; if (this.loop === true) { this._progress = this._progress % (this.duration || this.buffer.duration); } this.source.stop(); this.source.onended = null; this.isPlaying = false; } return this; } stop() { if (this.hasPlaybackControl === false) { console.warn("THREE.Audio: this Audio has no playback control."); return; } this._progress = 0; this.source.stop(); this.source.onended = null; this.isPlaying = false; return this; } connect() { if (this.filters.length > 0) { this.source.connect(this.filters[0]); for (let i = 1, l = this.filters.length; i < l; i++) { this.filters[i - 1].connect(this.filters[i]); } this.filters[this.filters.length - 1].connect(this.getOutput()); } else { this.source.connect(this.getOutput()); } this._connected = true; return this; } disconnect() { if (this.filters.length > 0) { this.source.disconnect(this.filters[0]); for (let i = 1, l = this.filters.length; i < l; i++) { this.filters[i - 1].disconnect(this.filters[i]); } this.filters[this.filters.length - 1].disconnect(this.getOutput()); } else { this.source.disconnect(this.getOutput()); } this._connected = false; return this; } getFilters() { return this.filters; } setFilters(value) { if (!value) value = []; if (this._connected === true) { this.disconnect(); this.filters = value.slice(); this.connect(); } else { this.filters = value.slice(); } return this; } setDetune(value) { this.detune = value; if (this.source.detune === void 0) return; if (this.isPlaying === true) { this.source.detune.setTargetAtTime(this.detune, this.context.currentTime, 0.01); } return this; } getDetune() { return this.detune; } getFilter() { return this.getFilters()[0]; } setFilter(filter) { return this.setFilters(filter ? [filter] : []); } setPlaybackRate(value) { if (this.hasPlaybackControl === false) { console.warn("THREE.Audio: this Audio has no playback control."); return; } this.playbackRate = value; if (this.isPlaying === true) { this.source.playbackRate.setTargetAtTime(this.playbackRate, this.context.currentTime, 0.01); } return this; } getPlaybackRate() { return this.playbackRate; } onEnded() { this.isPlaying = false; } getLoop() { if (this.hasPlaybackControl === false) { console.warn("THREE.Audio: this Audio has no playback control."); return false; } return this.loop; } setLoop(value) { if (this.hasPlaybackControl === false) { console.warn("THREE.Audio: this Audio has no playback control."); return; } this.loop = value; if (this.isPlaying === true) { this.source.loop = this.loop; } return this; } setLoopStart(value) { this.loopStart = value; return this; } setLoopEnd(value) { this.loopEnd = value; return this; } getVolume() { return this.gain.gain.value; } setVolume(value) { this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01); return this; } }; var AudioAnalyser = class { constructor(audio, fftSize = 2048) { this.analyser = audio.context.createAnalyser(); this.analyser.fftSize = fftSize; this.data = new Uint8Array(this.analyser.frequencyBinCount); audio.getOutput().connect(this.analyser); } getFrequencyData() { this.analyser.getByteFrequencyData(this.data); return this.data; } getAverageFrequency() { let value = 0; const data = this.getFrequencyData(); for (let i = 0; i < data.length; i++) { value += data[i]; } return value / data.length; } }; var PropertyMixer = class { constructor(binding, typeName, valueSize) { this.binding = binding; this.valueSize = valueSize; let mixFunction, mixFunctionAdditive, setIdentity; switch (typeName) { case "quaternion": mixFunction = this._slerp; mixFunctionAdditive = this._slerpAdditive; setIdentity = this._setAdditiveIdentityQuaternion; this.buffer = new Float64Array(valueSize * 6); this._workIndex = 5; break; case "string": case "bool": mixFunction = this._select; mixFunctionAdditive = this._select; setIdentity = this._setAdditiveIdentityOther; this.buffer = new Array(valueSize * 5); break; default: mixFunction = this._lerp; mixFunctionAdditive = this._lerpAdditive; setIdentity = this._setAdditiveIdentityNumeric; this.buffer = new Float64Array(valueSize * 5); } this._mixBufferRegion = mixFunction; this._mixBufferRegionAdditive = mixFunctionAdditive; this._setIdentity = setIdentity; this._origIndex = 3; this._addIndex = 4; this.cumulativeWeight = 0; this.cumulativeWeightAdditive = 0; this.useCount = 0; this.referenceCount = 0; } accumulate(accuIndex, weight) { const buffer = this.buffer, stride = this.valueSize, offset = accuIndex * stride + stride; let currentWeight = this.cumulativeWeight; if (currentWeight === 0) { for (let i = 0; i !== stride; ++i) { buffer[offset + i] = buffer[i]; } currentWeight = weight; } else { currentWeight += weight; const mix = weight / currentWeight; this._mixBufferRegion(buffer, offset, 0, mix, stride); } this.cumulativeWeight = currentWeight; } accumulateAdditive(weight) { const buffer = this.buffer, stride = this.valueSize, offset = stride * this._addIndex; if (this.cumulativeWeightAdditive === 0) { this._setIdentity(); } this._mixBufferRegionAdditive(buffer, offset, 0, weight, stride); this.cumulativeWeightAdditive += weight; } apply(accuIndex) { const stride = this.valueSize, buffer = this.buffer, offset = accuIndex * stride + stride, weight = this.cumulativeWeight, weightAdditive = this.cumulativeWeightAdditive, binding = this.binding; this.cumulativeWeight = 0; this.cumulativeWeightAdditive = 0; if (weight < 1) { const originalValueOffset = stride * this._origIndex; this._mixBufferRegion(buffer, offset, originalValueOffset, 1 - weight, stride); } if (weightAdditive > 0) { this._mixBufferRegionAdditive(buffer, offset, this._addIndex * stride, 1, stride); } for (let i = stride, e = stride + stride; i !== e; ++i) { if (buffer[i] !== buffer[i + stride]) { binding.setValue(buffer, offset); break; } } } saveOriginalState() { const binding = this.binding; const buffer = this.buffer, stride = this.valueSize, originalValueOffset = stride * this._origIndex; binding.getValue(buffer, originalValueOffset); for (let i = stride, e = originalValueOffset; i !== e; ++i) { buffer[i] = buffer[originalValueOffset + i % stride]; } this._setIdentity(); this.cumulativeWeight = 0; this.cumulativeWeightAdditive = 0; } restoreOriginalState() { const originalValueOffset = this.valueSize * 3; this.binding.setValue(this.buffer, originalValueOffset); } _setAdditiveIdentityNumeric() { const startIndex = this._addIndex * this.valueSize; const endIndex = startIndex + this.valueSize; for (let i = startIndex; i < endIndex; i++) { this.buffer[i] = 0; } } _setAdditiveIdentityQuaternion() { this._setAdditiveIdentityNumeric(); this.buffer[this._addIndex * this.valueSize + 3] = 1; } _setAdditiveIdentityOther() { const startIndex = this._origIndex * this.valueSize; const targetIndex = this._addIndex * this.valueSize; for (let i = 0; i < this.valueSize; i++) { this.buffer[targetIndex + i] = this.buffer[startIndex + i]; } } _select(buffer, dstOffset, srcOffset, t, stride) { if (t >= 0.5) { for (let i = 0; i !== stride; ++i) { buffer[dstOffset + i] = buffer[srcOffset + i]; } } } _slerp(buffer, dstOffset, srcOffset, t) { Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t); } _slerpAdditive(buffer, dstOffset, srcOffset, t, stride) { const workOffset = this._workIndex * stride; Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t); } _lerp(buffer, dstOffset, srcOffset, t, stride) { const s = 1 - t; for (let i = 0; i !== stride; ++i) { const j = dstOffset + i; buffer[j] = buffer[j] * s + buffer[srcOffset + i] * t; } } _lerpAdditive(buffer, dstOffset, srcOffset, t, stride) { for (let i = 0; i !== stride; ++i) { const j = dstOffset + i; buffer[j] = buffer[j] + buffer[srcOffset + i] * t; } } }; var _RESERVED_CHARS_RE = "\\[\\]\\.:\\/"; var _reservedRe = new RegExp("[" + _RESERVED_CHARS_RE + "]", "g"); var _wordChar = "[^" + _RESERVED_CHARS_RE + "]"; var _wordCharOrDot = "[^" + _RESERVED_CHARS_RE.replace("\\.", "") + "]"; var _directoryRe = /((?:WC+[\/:])*)/.source.replace("WC", _wordChar); var _nodeRe = /(WCOD+)?/.source.replace("WCOD", _wordCharOrDot); var _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC", _wordChar); var _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace("WC", _wordChar); var _trackRe = new RegExp("^" + _directoryRe + _nodeRe + _objectRe + _propertyRe + "$"); var _supportedObjectNames = ["material", "materials", "bones"]; var Composite = class { constructor(targetGroup, path, optionalParsedPath) { const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path); this._targetGroup = targetGroup; this._bindings = targetGroup.subscribe_(path, parsedPath); } getValue(array, offset) { this.bind(); const firstValidIndex = this._targetGroup.nCachedObjects_, binding = this._bindings[firstValidIndex]; if (binding !== void 0) binding.getValue(array, offset); } setValue(array, offset) { const bindings = this._bindings; for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { bindings[i].setValue(array, offset); } } bind() { const bindings = this._bindings; for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { bindings[i].bind(); } } unbind() { const bindings = this._bindings; for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) { bindings[i].unbind(); } } }; var PropertyBinding = class { constructor(rootNode, path, parsedPath) { this.path = path; this.parsedPath = parsedPath || PropertyBinding.parseTrackName(path); this.node = PropertyBinding.findNode(rootNode, this.parsedPath.nodeName) || rootNode; this.rootNode = rootNode; this.getValue = this._getValue_unbound; this.setValue = this._setValue_unbound; } static create(root, path, parsedPath) { if (!(root && root.isAnimationObjectGroup)) { return new PropertyBinding(root, path, parsedPath); } else { return new PropertyBinding.Composite(root, path, parsedPath); } } static sanitizeNodeName(name) { return name.replace(/\s/g, "_").replace(_reservedRe, ""); } static parseTrackName(trackName) { const matches = _trackRe.exec(trackName); if (!matches) { throw new Error("PropertyBinding: Cannot parse trackName: " + trackName); } const results = { nodeName: matches[2], objectName: matches[3], objectIndex: matches[4], propertyName: matches[5], propertyIndex: matches[6] }; const lastDot = results.nodeName && results.nodeName.lastIndexOf("."); if (lastDot !== void 0 && lastDot !== -1) { const objectName = results.nodeName.substring(lastDot + 1); if (_supportedObjectNames.indexOf(objectName) !== -1) { results.nodeName = results.nodeName.substring(0, lastDot); results.objectName = objectName; } } if (results.propertyName === null || results.propertyName.length === 0) { throw new Error("PropertyBinding: can not parse propertyName from trackName: " + trackName); } return results; } static findNode(root, nodeName) { if (!nodeName || nodeName === "" || nodeName === "." || nodeName === -1 || nodeName === root.name || nodeName === root.uuid) { return root; } if (root.skeleton) { const bone = root.skeleton.getBoneByName(nodeName); if (bone !== void 0) { return bone; } } if (root.children) { const searchNodeSubtree = function(children) { for (let i = 0; i < children.length; i++) { const childNode = children[i]; if (childNode.name === nodeName || childNode.uuid === nodeName) { return childNode; } const result = searchNodeSubtree(childNode.children); if (result) return result; } return null; }; const subTreeNode = searchNodeSubtree(root.children); if (subTreeNode) { return subTreeNode; } } return null; } _getValue_unavailable() { } _setValue_unavailable() { } _getValue_direct(buffer, offset) { buffer[offset] = this.targetObject[this.propertyName]; } _getValue_array(buffer, offset) { const source = this.resolvedProperty; for (let i = 0, n = source.length; i !== n; ++i) { buffer[offset++] = source[i]; } } _getValue_arrayElement(buffer, offset) { buffer[offset] = this.resolvedProperty[this.propertyIndex]; } _getValue_toArray(buffer, offset) { this.resolvedProperty.toArray(buffer, offset); } _setValue_direct(buffer, offset) { this.targetObject[this.propertyName] = buffer[offset]; } _setValue_direct_setNeedsUpdate(buffer, offset) { this.targetObject[this.propertyName] = buffer[offset]; this.targetObject.needsUpdate = true; } _setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) { this.targetObject[this.propertyName] = buffer[offset]; this.targetObject.matrixWorldNeedsUpdate = true; } _setValue_array(buffer, offset) { const dest = this.resolvedProperty; for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer[offset++]; } } _setValue_array_setNeedsUpdate(buffer, offset) { const dest = this.resolvedProperty; for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer[offset++]; } this.targetObject.needsUpdate = true; } _setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) { const dest = this.resolvedProperty; for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer[offset++]; } this.targetObject.matrixWorldNeedsUpdate = true; } _setValue_arrayElement(buffer, offset) { this.resolvedProperty[this.propertyIndex] = buffer[offset]; } _setValue_arrayElement_setNeedsUpdate(buffer, offset) { this.resolvedProperty[this.propertyIndex] = buffer[offset]; this.targetObject.needsUpdate = true; } _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) { this.resolvedProperty[this.propertyIndex] = buffer[offset]; this.targetObject.matrixWorldNeedsUpdate = true; } _setValue_fromArray(buffer, offset) { this.resolvedProperty.fromArray(buffer, offset); } _setValue_fromArray_setNeedsUpdate(buffer, offset) { this.resolvedProperty.fromArray(buffer, offset); this.targetObject.needsUpdate = true; } _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) { this.resolvedProperty.fromArray(buffer, offset); this.targetObject.matrixWorldNeedsUpdate = true; } _getValue_unbound(targetArray, offset) { this.bind(); this.getValue(targetArray, offset); } _setValue_unbound(sourceArray, offset) { this.bind(); this.setValue(sourceArray, offset); } bind() { let targetObject = this.node; const parsedPath = this.parsedPath; const objectName = parsedPath.objectName; const propertyName = parsedPath.propertyName; let propertyIndex = parsedPath.propertyIndex; if (!targetObject) { targetObject = PropertyBinding.findNode(this.rootNode, parsedPath.nodeName) || this.rootNode; this.node = targetObject; } this.getValue = this._getValue_unavailable; this.setValue = this._setValue_unavailable; if (!targetObject) { console.error("THREE.PropertyBinding: Trying to update node for track: " + this.path + " but it wasn't found."); return; } if (objectName) { let objectIndex = parsedPath.objectIndex; switch (objectName) { case "materials": if (!targetObject.material) { console.error("THREE.PropertyBinding: Can not bind to material as node does not have a material.", this); return; } if (!targetObject.material.materials) { console.error("THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.", this); return; } targetObject = targetObject.material.materials; break; case "bones": if (!targetObject.skeleton) { console.error("THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.", this); return; } targetObject = targetObject.skeleton.bones; for (let i = 0; i < targetObject.length; i++) { if (targetObject[i].name === objectIndex) { objectIndex = i; break; } } break; default: if (targetObject[objectName] === void 0) { console.error("THREE.PropertyBinding: Can not bind to objectName of node undefined.", this); return; } targetObject = targetObject[objectName]; } if (objectIndex !== void 0) { if (targetObject[objectIndex] === void 0) { console.error("THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.", this, targetObject); return; } targetObject = targetObject[objectIndex]; } } const nodeProperty = targetObject[propertyName]; if (nodeProperty === void 0) { const nodeName = parsedPath.nodeName; console.error("THREE.PropertyBinding: Trying to update property for track: " + nodeName + "." + propertyName + " but it wasn't found.", targetObject); return; } let versioning = this.Versioning.None; this.targetObject = targetObject; if (targetObject.needsUpdate !== void 0) { versioning = this.Versioning.NeedsUpdate; } else if (targetObject.matrixWorldNeedsUpdate !== void 0) { versioning = this.Versioning.MatrixWorldNeedsUpdate; } let bindingType = this.BindingType.Direct; if (propertyIndex !== void 0) { if (propertyName === "morphTargetInfluences") { if (!targetObject.geometry) { console.error("THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.", this); return; } if (targetObject.geometry.isBufferGeometry) { if (!targetObject.geometry.morphAttributes) { console.error("THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.", this); return; } if (targetObject.morphTargetDictionary[propertyIndex] !== void 0) { propertyIndex = targetObject.morphTargetDictionary[propertyIndex]; } } else { console.error("THREE.PropertyBinding: Can not bind to morphTargetInfluences on THREE.Geometry. Use THREE.BufferGeometry instead.", this); return; } } bindingType = this.BindingType.ArrayElement; this.resolvedProperty = nodeProperty; this.propertyIndex = propertyIndex; } else if (nodeProperty.fromArray !== void 0 && nodeProperty.toArray !== void 0) { bindingType = this.BindingType.HasFromToArray; this.resolvedProperty = nodeProperty; } else if (Array.isArray(nodeProperty)) { bindingType = this.BindingType.EntireArray; this.resolvedProperty = nodeProperty; } else { this.propertyName = propertyName; } this.getValue = this.GetterByBindingType[bindingType]; this.setValue = this.SetterByBindingTypeAndVersioning[bindingType][versioning]; } unbind() { this.node = null; this.getValue = this._getValue_unbound; this.setValue = this._setValue_unbound; } }; PropertyBinding.Composite = Composite; PropertyBinding.prototype.BindingType = { Direct: 0, EntireArray: 1, ArrayElement: 2, HasFromToArray: 3 }; PropertyBinding.prototype.Versioning = { None: 0, NeedsUpdate: 1, MatrixWorldNeedsUpdate: 2 }; PropertyBinding.prototype.GetterByBindingType = [ PropertyBinding.prototype._getValue_direct, PropertyBinding.prototype._getValue_array, PropertyBinding.prototype._getValue_arrayElement, PropertyBinding.prototype._getValue_toArray ]; PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [ [ PropertyBinding.prototype._setValue_direct, PropertyBinding.prototype._setValue_direct_setNeedsUpdate, PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate ], [ PropertyBinding.prototype._setValue_array, PropertyBinding.prototype._setValue_array_setNeedsUpdate, PropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate ], [ PropertyBinding.prototype._setValue_arrayElement, PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate, PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate ], [ PropertyBinding.prototype._setValue_fromArray, PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate ] ]; var AnimationObjectGroup = class { constructor() { this.uuid = generateUUID(); this._objects = Array.prototype.slice.call(arguments); this.nCachedObjects_ = 0; const indices = {}; this._indicesByUUID = indices; for (let i = 0, n = arguments.length; i !== n; ++i) { indices[arguments[i].uuid] = i; } this._paths = []; this._parsedPaths = []; this._bindings = []; this._bindingsIndicesByPath = {}; const scope = this; this.stats = { objects: { get total() { return scope._objects.length; }, get inUse() { return this.total - scope.nCachedObjects_; } }, get bindingsPerObject() { return scope._bindings.length; } }; } add() { const objects = this._objects, indicesByUUID = this._indicesByUUID, paths = this._paths, parsedPaths = this._parsedPaths, bindings = this._bindings, nBindings = bindings.length; let knownObject = void 0, nObjects = objects.length, nCachedObjects = this.nCachedObjects_; for (let i = 0, n = arguments.length; i !== n; ++i) { const object = arguments[i], uuid = object.uuid; let index = indicesByUUID[uuid]; if (index === void 0) { index = nObjects++; indicesByUUID[uuid] = index; objects.push(object); for (let j = 0, m = nBindings; j !== m; ++j) { bindings[j].push(new PropertyBinding(object, paths[j], parsedPaths[j])); } } else if (index < nCachedObjects) { knownObject = objects[index]; const firstActiveIndex = --nCachedObjects, lastCachedObject = objects[firstActiveIndex]; indicesByUUID[lastCachedObject.uuid] = index; objects[index] = lastCachedObject; indicesByUUID[uuid] = firstActiveIndex; objects[firstActiveIndex] = object; for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j], lastCached = bindingsForPath[firstActiveIndex]; let binding = bindingsForPath[index]; bindingsForPath[index] = lastCached; if (binding === void 0) { binding = new PropertyBinding(object, paths[j], parsedPaths[j]); } bindingsForPath[firstActiveIndex] = binding; } } else if (objects[index] !== knownObject) { console.error("THREE.AnimationObjectGroup: Different objects with the same UUID detected. Clean the caches or recreate your infrastructure when reloading scenes."); } } this.nCachedObjects_ = nCachedObjects; } remove() { const objects = this._objects, indicesByUUID = this._indicesByUUID, bindings = this._bindings, nBindings = bindings.length; let nCachedObjects = this.nCachedObjects_; for (let i = 0, n = arguments.length; i !== n; ++i) { const object = arguments[i], uuid = object.uuid, index = indicesByUUID[uuid]; if (index !== void 0 && index >= nCachedObjects) { const lastCachedIndex = nCachedObjects++, firstActiveObject = objects[lastCachedIndex]; indicesByUUID[firstActiveObject.uuid] = index; objects[index] = firstActiveObject; indicesByUUID[uuid] = lastCachedIndex; objects[lastCachedIndex] = object; for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j], firstActive = bindingsForPath[lastCachedIndex], binding = bindingsForPath[index]; bindingsForPath[index] = firstActive; bindingsForPath[lastCachedIndex] = binding; } } } this.nCachedObjects_ = nCachedObjects; } uncache() { const objects = this._objects, indicesByUUID = this._indicesByUUID, bindings = this._bindings, nBindings = bindings.length; let nCachedObjects = this.nCachedObjects_, nObjects = objects.length; for (let i = 0, n = arguments.length; i !== n; ++i) { const object = arguments[i], uuid = object.uuid, index = indicesByUUID[uuid]; if (index !== void 0) { delete indicesByUUID[uuid]; if (index < nCachedObjects) { const firstActiveIndex = --nCachedObjects, lastCachedObject = objects[firstActiveIndex], lastIndex = --nObjects, lastObject = objects[lastIndex]; indicesByUUID[lastCachedObject.uuid] = index; objects[index] = lastCachedObject; indicesByUUID[lastObject.uuid] = firstActiveIndex; objects[firstActiveIndex] = lastObject; objects.pop(); for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j], lastCached = bindingsForPath[firstActiveIndex], last = bindingsForPath[lastIndex]; bindingsForPath[index] = lastCached; bindingsForPath[firstActiveIndex] = last; bindingsForPath.pop(); } } else { const lastIndex = --nObjects, lastObject = objects[lastIndex]; if (lastIndex > 0) { indicesByUUID[lastObject.uuid] = index; } objects[index] = lastObject; objects.pop(); for (let j = 0, m = nBindings; j !== m; ++j) { const bindingsForPath = bindings[j]; bindingsForPath[index] = bindingsForPath[lastIndex]; bindingsForPath.pop(); } } } } this.nCachedObjects_ = nCachedObjects; } subscribe_(path, parsedPath) { const indicesByPath = this._bindingsIndicesByPath; let index = indicesByPath[path]; const bindings = this._bindings; if (index !== void 0) return bindings[index]; const paths = this._paths, parsedPaths = this._parsedPaths, objects = this._objects, nObjects = objects.length, nCachedObjects = this.nCachedObjects_, bindingsForPath = new Array(nObjects); index = bindings.length; indicesByPath[path] = index; paths.push(path); parsedPaths.push(parsedPath); bindings.push(bindingsForPath); for (let i = nCachedObjects, n = objects.length; i !== n; ++i) { const object = objects[i]; bindingsForPath[i] = new PropertyBinding(object, path, parsedPath); } return bindingsForPath; } unsubscribe_(path) { const indicesByPath = this._bindingsIndicesByPath, index = indicesByPath[path]; if (index !== void 0) { const paths = this._paths, parsedPaths = this._parsedPaths, bindings = this._bindings, lastBindingsIndex = bindings.length - 1, lastBindings = bindings[lastBindingsIndex], lastBindingsPath = path[lastBindingsIndex]; indicesByPath[lastBindingsPath] = index; bindings[index] = lastBindings; bindings.pop(); parsedPaths[index] = parsedPaths[lastBindingsIndex]; parsedPaths.pop(); paths[index] = paths[lastBindingsIndex]; paths.pop(); } } }; AnimationObjectGroup.prototype.isAnimationObjectGroup = true; var AnimationAction = class { constructor(mixer, clip, localRoot = null, blendMode = clip.blendMode) { this._mixer = mixer; this._clip = clip; this._localRoot = localRoot; this.blendMode = blendMode; const tracks = clip.tracks, nTracks = tracks.length, interpolants = new Array(nTracks); const interpolantSettings = { endingStart: ZeroCurvatureEnding, endingEnd: ZeroCurvatureEnding }; for (let i = 0; i !== nTracks; ++i) { const interpolant = tracks[i].createInterpolant(null); interpolants[i] = interpolant; interpolant.settings = interpolantSettings; } this._interpolantSettings = interpolantSettings; this._interpolants = interpolants; this._propertyBindings = new Array(nTracks); this._cacheIndex = null; this._byClipCacheIndex = null; this._timeScaleInterpolant = null; this._weightInterpolant = null; this.loop = LoopRepeat; this._loopCount = -1; this._startTime = null; this.time = 0; this.timeScale = 1; this._effectiveTimeScale = 1; this.weight = 1; this._effectiveWeight = 1; this.repetitions = Infinity; this.paused = false; this.enabled = true; this.clampWhenFinished = false; this.zeroSlopeAtStart = true; this.zeroSlopeAtEnd = true; } play() { this._mixer._activateAction(this); return this; } stop() { this._mixer._deactivateAction(this); return this.reset(); } reset() { this.paused = false; this.enabled = true; this.time = 0; this._loopCount = -1; this._startTime = null; return this.stopFading().stopWarping(); } isRunning() { return this.enabled && !this.paused && this.timeScale !== 0 && this._startTime === null && this._mixer._isActiveAction(this); } isScheduled() { return this._mixer._isActiveAction(this); } startAt(time) { this._startTime = time; return this; } setLoop(mode, repetitions) { this.loop = mode; this.repetitions = repetitions; return this; } setEffectiveWeight(weight) { this.weight = weight; this._effectiveWeight = this.enabled ? weight : 0; return this.stopFading(); } getEffectiveWeight() { return this._effectiveWeight; } fadeIn(duration) { return this._scheduleFading(duration, 0, 1); } fadeOut(duration) { return this._scheduleFading(duration, 1, 0); } crossFadeFrom(fadeOutAction, duration, warp) { fadeOutAction.fadeOut(duration); this.fadeIn(duration); if (warp) { const fadeInDuration = this._clip.duration, fadeOutDuration = fadeOutAction._clip.duration, startEndRatio = fadeOutDuration / fadeInDuration, endStartRatio = fadeInDuration / fadeOutDuration; fadeOutAction.warp(1, startEndRatio, duration); this.warp(endStartRatio, 1, duration); } return this; } crossFadeTo(fadeInAction, duration, warp) { return fadeInAction.crossFadeFrom(this, duration, warp); } stopFading() { const weightInterpolant = this._weightInterpolant; if (weightInterpolant !== null) { this._weightInterpolant = null; this._mixer._takeBackControlInterpolant(weightInterpolant); } return this; } setEffectiveTimeScale(timeScale) { this.timeScale = timeScale; this._effectiveTimeScale = this.paused ? 0 : timeScale; return this.stopWarping(); } getEffectiveTimeScale() { return this._effectiveTimeScale; } setDuration(duration) { this.timeScale = this._clip.duration / duration; return this.stopWarping(); } syncWith(action) { this.time = action.time; this.timeScale = action.timeScale; return this.stopWarping(); } halt(duration) { return this.warp(this._effectiveTimeScale, 0, duration); } warp(startTimeScale, endTimeScale, duration) { const mixer = this._mixer, now = mixer.time, timeScale = this.timeScale; let interpolant = this._timeScaleInterpolant; if (interpolant === null) { interpolant = mixer._lendControlInterpolant(); this._timeScaleInterpolant = interpolant; } const times = interpolant.parameterPositions, values = interpolant.sampleValues; times[0] = now; times[1] = now + duration; values[0] = startTimeScale / timeScale; values[1] = endTimeScale / timeScale; return this; } stopWarping() { const timeScaleInterpolant = this._timeScaleInterpolant; if (timeScaleInterpolant !== null) { this._timeScaleInterpolant = null; this._mixer._takeBackControlInterpolant(timeScaleInterpolant); } return this; } getMixer() { return this._mixer; } getClip() { return this._clip; } getRoot() { return this._localRoot || this._mixer._root; } _update(time, deltaTime, timeDirection, accuIndex) { if (!this.enabled) { this._updateWeight(time); return; } const startTime = this._startTime; if (startTime !== null) { const timeRunning = (time - startTime) * timeDirection; if (timeRunning < 0 || timeDirection === 0) { return; } this._startTime = null; deltaTime = timeDirection * timeRunning; } deltaTime *= this._updateTimeScale(time); const clipTime = this._updateTime(deltaTime); const weight = this._updateWeight(time); if (weight > 0) { const interpolants = this._interpolants; const propertyMixers = this._propertyBindings; switch (this.blendMode) { case AdditiveAnimationBlendMode: for (let j = 0, m = interpolants.length; j !== m; ++j) { interpolants[j].evaluate(clipTime); propertyMixers[j].accumulateAdditive(weight); } break; case NormalAnimationBlendMode: default: for (let j = 0, m = interpolants.length; j !== m; ++j) { interpolants[j].evaluate(clipTime); propertyMixers[j].accumulate(accuIndex, weight); } } } } _updateWeight(time) { let weight = 0; if (this.enabled) { weight = this.weight; const interpolant = this._weightInterpolant; if (interpolant !== null) { const interpolantValue = interpolant.evaluate(time)[0]; weight *= interpolantValue; if (time > interpolant.parameterPositions[1]) { this.stopFading(); if (interpolantValue === 0) { this.enabled = false; } } } } this._effectiveWeight = weight; return weight; } _updateTimeScale(time) { let timeScale = 0; if (!this.paused) { timeScale = this.timeScale; const interpolant = this._timeScaleInterpolant; if (interpolant !== null) { const interpolantValue = interpolant.evaluate(time)[0]; timeScale *= interpolantValue; if (time > interpolant.parameterPositions[1]) { this.stopWarping(); if (timeScale === 0) { this.paused = true; } else { this.timeScale = timeScale; } } } } this._effectiveTimeScale = timeScale; return timeScale; } _updateTime(deltaTime) { const duration = this._clip.duration; const loop = this.loop; let time = this.time + deltaTime; let loopCount = this._loopCount; const pingPong = loop === LoopPingPong; if (deltaTime === 0) { if (loopCount === -1) return time; return pingPong && (loopCount & 1) === 1 ? duration - time : time; } if (loop === LoopOnce) { if (loopCount === -1) { this._loopCount = 0; this._setEndings(true, true, false); } handle_stop: { if (time >= duration) { time = duration; } else if (time < 0) { time = 0; } else { this.time = time; break handle_stop; } if (this.clampWhenFinished) this.paused = true; else this.enabled = false; this.time = time; this._mixer.dispatchEvent({ type: "finished", action: this, direction: deltaTime < 0 ? -1 : 1 }); } } else { if (loopCount === -1) { if (deltaTime >= 0) { loopCount = 0; this._setEndings(true, this.repetitions === 0, pingPong); } else { this._setEndings(this.repetitions === 0, true, pingPong); } } if (time >= duration || time < 0) { const loopDelta = Math.floor(time / duration); time -= duration * loopDelta; loopCount += Math.abs(loopDelta); const pending = this.repetitions - loopCount; if (pending <= 0) { if (this.clampWhenFinished) this.paused = true; else this.enabled = false; time = deltaTime > 0 ? duration : 0; this.time = time; this._mixer.dispatchEvent({ type: "finished", action: this, direction: deltaTime > 0 ? 1 : -1 }); } else { if (pending === 1) { const atStart = deltaTime < 0; this._setEndings(atStart, !atStart, pingPong); } else { this._setEndings(false, false, pingPong); } this._loopCount = loopCount; this.time = time; this._mixer.dispatchEvent({ type: "loop", action: this, loopDelta }); } } else { this.time = time; } if (pingPong && (loopCount & 1) === 1) { return duration - time; } } return time; } _setEndings(atStart, atEnd, pingPong) { const settings = this._interpolantSettings; if (pingPong) { settings.endingStart = ZeroSlopeEnding; settings.endingEnd = ZeroSlopeEnding; } else { if (atStart) { settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding; } else { settings.endingStart = WrapAroundEnding; } if (atEnd) { settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding; } else { settings.endingEnd = WrapAroundEnding; } } } _scheduleFading(duration, weightNow, weightThen) { const mixer = this._mixer, now = mixer.time; let interpolant = this._weightInterpolant; if (interpolant === null) { interpolant = mixer._lendControlInterpolant(); this._weightInterpolant = interpolant; } const times = interpolant.parameterPositions, values = interpolant.sampleValues; times[0] = now; values[0] = weightNow; times[1] = now + duration; values[1] = weightThen; return this; } }; var AnimationMixer = class extends EventDispatcher { constructor(root) { super(); this._root = root; this._initMemoryManager(); this._accuIndex = 0; this.time = 0; this.timeScale = 1; } _bindAction(action, prototypeAction) { const root = action._localRoot || this._root, tracks = action._clip.tracks, nTracks = tracks.length, bindings = action._propertyBindings, interpolants = action._interpolants, rootUuid = root.uuid, bindingsByRoot = this._bindingsByRootAndName; let bindingsByName = bindingsByRoot[rootUuid]; if (bindingsByName === void 0) { bindingsByName = {}; bindingsByRoot[rootUuid] = bindingsByName; } for (let i = 0; i !== nTracks; ++i) { const track = tracks[i], trackName = track.name; let binding = bindingsByName[trackName]; if (binding !== void 0) { bindings[i] = binding; } else { binding = bindings[i]; if (binding !== void 0) { if (binding._cacheIndex === null) { ++binding.referenceCount; this._addInactiveBinding(binding, rootUuid, trackName); } continue; } const path = prototypeAction && prototypeAction._propertyBindings[i].binding.parsedPath; binding = new PropertyMixer(PropertyBinding.create(root, trackName, path), track.ValueTypeName, track.getValueSize()); ++binding.referenceCount; this._addInactiveBinding(binding, rootUuid, trackName); bindings[i] = binding; } interpolants[i].resultBuffer = binding.buffer; } } _activateAction(action) { if (!this._isActiveAction(action)) { if (action._cacheIndex === null) { const rootUuid = (action._localRoot || this._root).uuid, clipUuid = action._clip.uuid, actionsForClip = this._actionsByClip[clipUuid]; this._bindAction(action, actionsForClip && actionsForClip.knownActions[0]); this._addInactiveAction(action, clipUuid, rootUuid); } const bindings = action._propertyBindings; for (let i = 0, n = bindings.length; i !== n; ++i) { const binding = bindings[i]; if (binding.useCount++ === 0) { this._lendBinding(binding); binding.saveOriginalState(); } } this._lendAction(action); } } _deactivateAction(action) { if (this._isActiveAction(action)) { const bindings = action._propertyBindings; for (let i = 0, n = bindings.length; i !== n; ++i) { const binding = bindings[i]; if (--binding.useCount === 0) { binding.restoreOriginalState(); this._takeBackBinding(binding); } } this._takeBackAction(action); } } _initMemoryManager() { this._actions = []; this._nActiveActions = 0; this._actionsByClip = {}; this._bindings = []; this._nActiveBindings = 0; this._bindingsByRootAndName = {}; this._controlInterpolants = []; this._nActiveControlInterpolants = 0; const scope = this; this.stats = { actions: { get total() { return scope._actions.length; }, get inUse() { return scope._nActiveActions; } }, bindings: { get total() { return scope._bindings.length; }, get inUse() { return scope._nActiveBindings; } }, controlInterpolants: { get total() { return scope._controlInterpolants.length; }, get inUse() { return scope._nActiveControlInterpolants; } } }; } _isActiveAction(action) { const index = action._cacheIndex; return index !== null && index < this._nActiveActions; } _addInactiveAction(action, clipUuid, rootUuid) { const actions = this._actions, actionsByClip = this._actionsByClip; let actionsForClip = actionsByClip[clipUuid]; if (actionsForClip === void 0) { actionsForClip = { knownActions: [action], actionByRoot: {} }; action._byClipCacheIndex = 0; actionsByClip[clipUuid] = actionsForClip; } else { const knownActions = actionsForClip.knownActions; action._byClipCacheIndex = knownActions.length; knownActions.push(action); } action._cacheIndex = actions.length; actions.push(action); actionsForClip.actionByRoot[rootUuid] = action; } _removeInactiveAction(action) { const actions = this._actions, lastInactiveAction = actions[actions.length - 1], cacheIndex = action._cacheIndex; lastInactiveAction._cacheIndex = cacheIndex; actions[cacheIndex] = lastInactiveAction; actions.pop(); action._cacheIndex = null; const clipUuid = action._clip.uuid, actionsByClip = this._actionsByClip, actionsForClip = actionsByClip[clipUuid], knownActionsForClip = actionsForClip.knownActions, lastKnownAction = knownActionsForClip[knownActionsForClip.length - 1], byClipCacheIndex = action._byClipCacheIndex; lastKnownAction._byClipCacheIndex = byClipCacheIndex; knownActionsForClip[byClipCacheIndex] = lastKnownAction; knownActionsForClip.pop(); action._byClipCacheIndex = null; const actionByRoot = actionsForClip.actionByRoot, rootUuid = (action._localRoot || this._root).uuid; delete actionByRoot[rootUuid]; if (knownActionsForClip.length === 0) { delete actionsByClip[clipUuid]; } this._removeInactiveBindingsForAction(action); } _removeInactiveBindingsForAction(action) { const bindings = action._propertyBindings; for (let i = 0, n = bindings.length; i !== n; ++i) { const binding = bindings[i]; if (--binding.referenceCount === 0) { this._removeInactiveBinding(binding); } } } _lendAction(action) { const actions = this._actions, prevIndex = action._cacheIndex, lastActiveIndex = this._nActiveActions++, firstInactiveAction = actions[lastActiveIndex]; action._cacheIndex = lastActiveIndex; actions[lastActiveIndex] = action; firstInactiveAction._cacheIndex = prevIndex; actions[prevIndex] = firstInactiveAction; } _takeBackAction(action) { const actions = this._actions, prevIndex = action._cacheIndex, firstInactiveIndex = --this._nActiveActions, lastActiveAction = actions[firstInactiveIndex]; action._cacheIndex = firstInactiveIndex; actions[firstInactiveIndex] = action; lastActiveAction._cacheIndex = prevIndex; actions[prevIndex] = lastActiveAction; } _addInactiveBinding(binding, rootUuid, trackName) { const bindingsByRoot = this._bindingsByRootAndName, bindings = this._bindings; let bindingByName = bindingsByRoot[rootUuid]; if (bindingByName === void 0) { bindingByName = {}; bindingsByRoot[rootUuid] = bindingByName; } bindingByName[trackName] = binding; binding._cacheIndex = bindings.length; bindings.push(binding); } _removeInactiveBinding(binding) { const bindings = this._bindings, propBinding = binding.binding, rootUuid = propBinding.rootNode.uuid, trackName = propBinding.path, bindingsByRoot = this._bindingsByRootAndName, bindingByName = bindingsByRoot[rootUuid], lastInactiveBinding = bindings[bindings.length - 1], cacheIndex = binding._cacheIndex; lastInactiveBinding._cacheIndex = cacheIndex; bindings[cacheIndex] = lastInactiveBinding; bindings.pop(); delete bindingByName[trackName]; if (Object.keys(bindingByName).length === 0) { delete bindingsByRoot[rootUuid]; } } _lendBinding(binding) { const bindings = this._bindings, prevIndex = binding._cacheIndex, lastActiveIndex = this._nActiveBindings++, firstInactiveBinding = bindings[lastActiveIndex]; binding._cacheIndex = lastActiveIndex; bindings[lastActiveIndex] = binding; firstInactiveBinding._cacheIndex = prevIndex; bindings[prevIndex] = firstInactiveBinding; } _takeBackBinding(binding) { const bindings = this._bindings, prevIndex = binding._cacheIndex, firstInactiveIndex = --this._nActiveBindings, lastActiveBinding = bindings[firstInactiveIndex]; binding._cacheIndex = firstInactiveIndex; bindings[firstInactiveIndex] = binding; lastActiveBinding._cacheIndex = prevIndex; bindings[prevIndex] = lastActiveBinding; } _lendControlInterpolant() { const interpolants = this._controlInterpolants, lastActiveIndex = this._nActiveControlInterpolants++; let interpolant = interpolants[lastActiveIndex]; if (interpolant === void 0) { interpolant = new LinearInterpolant(new Float32Array(2), new Float32Array(2), 1, this._controlInterpolantsResultBuffer); interpolant.__cacheIndex = lastActiveIndex; interpolants[lastActiveIndex] = interpolant; } return interpolant; } _takeBackControlInterpolant(interpolant) { const interpolants = this._controlInterpolants, prevIndex = interpolant.__cacheIndex, firstInactiveIndex = --this._nActiveControlInterpolants, lastActiveInterpolant = interpolants[firstInactiveIndex]; interpolant.__cacheIndex = firstInactiveIndex; interpolants[firstInactiveIndex] = interpolant; lastActiveInterpolant.__cacheIndex = prevIndex; interpolants[prevIndex] = lastActiveInterpolant; } clipAction(clip, optionalRoot, blendMode) { const root = optionalRoot || this._root, rootUuid = root.uuid; let clipObject = typeof clip === "string" ? AnimationClip.findByName(root, clip) : clip; const clipUuid = clipObject !== null ? clipObject.uuid : clip; const actionsForClip = this._actionsByClip[clipUuid]; let prototypeAction = null; if (blendMode === void 0) { if (clipObject !== null) { blendMode = clipObject.blendMode; } else { blendMode = NormalAnimationBlendMode; } } if (actionsForClip !== void 0) { const existingAction = actionsForClip.actionByRoot[rootUuid]; if (existingAction !== void 0 && existingAction.blendMode === blendMode) { return existingAction; } prototypeAction = actionsForClip.knownActions[0]; if (clipObject === null) clipObject = prototypeAction._clip; } if (clipObject === null) return null; const newAction = new AnimationAction(this, clipObject, optionalRoot, blendMode); this._bindAction(newAction, prototypeAction); this._addInactiveAction(newAction, clipUuid, rootUuid); return newAction; } existingAction(clip, optionalRoot) { const root = optionalRoot || this._root, rootUuid = root.uuid, clipObject = typeof clip === "string" ? AnimationClip.findByName(root, clip) : clip, clipUuid = clipObject ? clipObject.uuid : clip, actionsForClip = this._actionsByClip[clipUuid]; if (actionsForClip !== void 0) { return actionsForClip.actionByRoot[rootUuid] || null; } return null; } stopAllAction() { const actions = this._actions, nActions = this._nActiveActions; for (let i = nActions - 1; i >= 0; --i) { actions[i].stop(); } return this; } update(deltaTime) { deltaTime *= this.timeScale; const actions = this._actions, nActions = this._nActiveActions, time = this.time += deltaTime, timeDirection = Math.sign(deltaTime), accuIndex = this._accuIndex ^= 1; for (let i = 0; i !== nActions; ++i) { const action = actions[i]; action._update(time, deltaTime, timeDirection, accuIndex); } const bindings = this._bindings, nBindings = this._nActiveBindings; for (let i = 0; i !== nBindings; ++i) { bindings[i].apply(accuIndex); } return this; } setTime(timeInSeconds) { this.time = 0; for (let i = 0; i < this._actions.length; i++) { this._actions[i].time = 0; } return this.update(timeInSeconds); } getRoot() { return this._root; } uncacheClip(clip) { const actions = this._actions, clipUuid = clip.uuid, actionsByClip = this._actionsByClip, actionsForClip = actionsByClip[clipUuid]; if (actionsForClip !== void 0) { const actionsToRemove = actionsForClip.knownActions; for (let i = 0, n = actionsToRemove.length; i !== n; ++i) { const action = actionsToRemove[i]; this._deactivateAction(action); const cacheIndex = action._cacheIndex, lastInactiveAction = actions[actions.length - 1]; action._cacheIndex = null; action._byClipCacheIndex = null; lastInactiveAction._cacheIndex = cacheIndex; actions[cacheIndex] = lastInactiveAction; actions.pop(); this._removeInactiveBindingsForAction(action); } delete actionsByClip[clipUuid]; } } uncacheRoot(root) { const rootUuid = root.uuid, actionsByClip = this._actionsByClip; for (const clipUuid in actionsByClip) { const actionByRoot = actionsByClip[clipUuid].actionByRoot, action = actionByRoot[rootUuid]; if (action !== void 0) { this._deactivateAction(action); this._removeInactiveAction(action); } } const bindingsByRoot = this._bindingsByRootAndName, bindingByName = bindingsByRoot[rootUuid]; if (bindingByName !== void 0) { for (const trackName in bindingByName) { const binding = bindingByName[trackName]; binding.restoreOriginalState(); this._removeInactiveBinding(binding); } } } uncacheAction(clip, optionalRoot) { const action = this.existingAction(clip, optionalRoot); if (action !== null) { this._deactivateAction(action); this._removeInactiveAction(action); } } }; AnimationMixer.prototype._controlInterpolantsResultBuffer = new Float32Array(1); var Uniform = class { constructor(value) { if (typeof value === "string") { console.warn("THREE.Uniform: Type parameter is no longer needed."); value = arguments[1]; } this.value = value; } clone() { return new Uniform(this.value.clone === void 0 ? this.value : this.value.clone()); } }; var InstancedInterleavedBuffer = class extends InterleavedBuffer { constructor(array, stride, meshPerAttribute = 1) { super(array, stride); this.meshPerAttribute = meshPerAttribute; } copy(source) { super.copy(source); this.meshPerAttribute = source.meshPerAttribute; return this; } clone(data) { const ib = super.clone(data); ib.meshPerAttribute = this.meshPerAttribute; return ib; } toJSON(data) { const json = super.toJSON(data); json.isInstancedInterleavedBuffer = true; json.meshPerAttribute = this.meshPerAttribute; return json; } }; InstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true; var GLBufferAttribute = class { constructor(buffer, type, itemSize, elementSize, count) { this.buffer = buffer; this.type = type; this.itemSize = itemSize; this.elementSize = elementSize; this.count = count; this.version = 0; } set needsUpdate(value) { if (value === true) this.version++; } setBuffer(buffer) { this.buffer = buffer; return this; } setType(type, elementSize) { this.type = type; this.elementSize = elementSize; return this; } setItemSize(itemSize) { this.itemSize = itemSize; return this; } setCount(count) { this.count = count; return this; } }; GLBufferAttribute.prototype.isGLBufferAttribute = true; var _vector$4 = /* @__PURE__ */ new Vector2(); var Box2 = class { constructor(min = new Vector2(Infinity, Infinity), max = new Vector2(-Infinity, -Infinity)) { this.min = min; this.max = max; } set(min, max) { this.min.copy(min); this.max.copy(max); return this; } setFromPoints(points) { this.makeEmpty(); for (let i = 0, il = points.length; i < il; i++) { this.expandByPoint(points[i]); } return this; } setFromCenterAndSize(center, size) { const halfSize = _vector$4.copy(size).multiplyScalar(0.5); this.min.copy(center).sub(halfSize); this.max.copy(center).add(halfSize); return this; } clone() { return new this.constructor().copy(this); } copy(box) { this.min.copy(box.min); this.max.copy(box.max); return this; } makeEmpty() { this.min.x = this.min.y = Infinity; this.max.x = this.max.y = -Infinity; return this; } isEmpty() { return this.max.x < this.min.x || this.max.y < this.min.y; } getCenter(target) { return this.isEmpty() ? target.set(0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5); } getSize(target) { return this.isEmpty() ? target.set(0, 0) : target.subVectors(this.max, this.min); } expandByPoint(point) { this.min.min(point); this.max.max(point); return this; } expandByVector(vector) { this.min.sub(vector); this.max.add(vector); return this; } expandByScalar(scalar) { this.min.addScalar(-scalar); this.max.addScalar(scalar); return this; } containsPoint(point) { return point.x < this.min.x || point.x > this.max.x || point.y < this.min.y || point.y > this.max.y ? false : true; } containsBox(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; } getParameter(point, target) { 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)); } intersectsBox(box) { 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 ? false : true; } clampPoint(point, target) { return target.copy(point).clamp(this.min, this.max); } distanceToPoint(point) { const clampedPoint = _vector$4.copy(point).clamp(this.min, this.max); return clampedPoint.sub(point).length(); } intersect(box) { this.min.max(box.min); this.max.min(box.max); return this; } union(box) { this.min.min(box.min); this.max.max(box.max); return this; } translate(offset) { this.min.add(offset); this.max.add(offset); return this; } equals(box) { return box.min.equals(this.min) && box.max.equals(this.max); } }; Box2.prototype.isBox2 = true; var _startP = /* @__PURE__ */ new Vector3(); var _startEnd = /* @__PURE__ */ new Vector3(); var Line3 = class { constructor(start = new Vector3(), end = new Vector3()) { this.start = start; this.end = end; } set(start, end) { this.start.copy(start); this.end.copy(end); return this; } copy(line) { this.start.copy(line.start); this.end.copy(line.end); return this; } getCenter(target) { return target.addVectors(this.start, this.end).multiplyScalar(0.5); } delta(target) { return target.subVectors(this.end, this.start); } distanceSq() { return this.start.distanceToSquared(this.end); } distance() { return this.start.distanceTo(this.end); } at(t, target) { return this.delta(target).multiplyScalar(t).add(this.start); } closestPointToPointParameter(point, clampToLine) { _startP.subVectors(point, this.start); _startEnd.subVectors(this.end, this.start); const startEnd2 = _startEnd.dot(_startEnd); const startEnd_startP = _startEnd.dot(_startP); let t = startEnd_startP / startEnd2; if (clampToLine) { t = clamp(t, 0, 1); } return t; } closestPointToPoint(point, clampToLine, target) { const t = this.closestPointToPointParameter(point, clampToLine); return this.delta(target).multiplyScalar(t).add(this.start); } applyMatrix4(matrix) { this.start.applyMatrix4(matrix); this.end.applyMatrix4(matrix); return this; } equals(line) { return line.start.equals(this.start) && line.end.equals(this.end); } clone() { return new this.constructor().copy(this); } }; var ImmediateRenderObject = class extends Object3D { constructor(material) { super(); this.material = material; this.render = function() { }; this.hasPositions = false; this.hasNormals = false; this.hasColors = false; this.hasUvs = false; this.positionArray = null; this.normalArray = null; this.colorArray = null; this.uvArray = null; this.count = 0; } }; ImmediateRenderObject.prototype.isImmediateRenderObject = true; var _vector$2 = /* @__PURE__ */ new Vector3(); var _boneMatrix = /* @__PURE__ */ new Matrix4(); var _matrixWorldInv = /* @__PURE__ */ new Matrix4(); var SkeletonHelper = class extends LineSegments { constructor(object) { const bones = getBoneList(object); const geometry = new BufferGeometry(); const vertices = []; const colors = []; const color1 = new Color(0, 0, 1); const color2 = new Color(0, 1, 0); for (let i = 0; i < bones.length; i++) { const bone = bones[i]; if (bone.parent && bone.parent.isBone) { vertices.push(0, 0, 0); vertices.push(0, 0, 0); colors.push(color1.r, color1.g, color1.b); colors.push(color2.r, color2.g, color2.b); } } geometry.setAttribute("position", new Float32BufferAttribute(vertices, 3)); geometry.setAttribute("color", new Float32BufferAttribute(colors, 3)); const material = new LineBasicMaterial({ vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true }); super(geometry, material); this.type = "SkeletonHelper"; this.isSkeletonHelper = true; this.root = object; this.bones = bones; this.matrix = object.matrixWorld; this.matrixAutoUpdate = false; } updateMatrixWorld(force) { const bones = this.bones; const geometry = this.geometry; const position = geometry.getAttribute("position"); _matrixWorldInv.copy(this.root.matrixWorld).invert(); for (let i = 0, j = 0; i < bones.length; i++) { const bone = bones[i]; if (bone.parent && bone.parent.isBone) { _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.matrixWorld); _vector$2.setFromMatrixPosition(_boneMatrix); position.setXYZ(j, _vector$2.x, _vector$2.y, _vector$2.z); _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.parent.matrixWorld); _vector$2.setFromMatrixPosition(_boneMatrix); position.setXYZ(j + 1, _vector$2.x, _vector$2.y, _vector$2.z); j += 2; } } geometry.getAttribute("position").needsUpdate = true; super.updateMatrixWorld(force); } }; function getBoneList(object) { const boneList = []; if (object && object.isBone) { boneList.push(object); } for (let i = 0; i < object.children.length; i++) { boneList.push.apply(boneList, getBoneList(object.children[i])); } return boneList; } var GridHelper = class extends LineSegments { constructor(size = 10, divisions = 10, color1 = 4473924, color2 = 8947848) { color1 = new Color(color1); color2 = new Color(color2); const center = divisions / 2; const step = size / divisions; const halfSize = size / 2; const vertices = [], colors = []; for (let i = 0, j = 0, k = -halfSize; i <= divisions; i++, k += step) { vertices.push(-halfSize, 0, k, halfSize, 0, k); vertices.push(k, 0, -halfSize, k, 0, halfSize); const color = i === center ? color1 : color2; color.toArray(colors, j); j += 3; color.toArray(colors, j); j += 3; color.toArray(colors, j); j += 3; color.toArray(colors, j); j += 3; } const geometry = new BufferGeometry(); geometry.setAttribute("position", new Float32BufferAttribute(vertices, 3)); geometry.setAttribute("color", new Float32BufferAttribute(colors, 3)); const material = new LineBasicMaterial({ vertexColors: true, toneMapped: false }); super(geometry, material); this.type = "GridHelper"; } }; var _floatView = new Float32Array(1); var _int32View = new Int32Array(_floatView.buffer); Curve.create = function(construct, getPoint) { console.log("THREE.Curve.create() has been deprecated"); construct.prototype = Object.create(Curve.prototype); construct.prototype.constructor = construct; construct.prototype.getPoint = getPoint; return construct; }; Path.prototype.fromPoints = function(points) { console.warn("THREE.Path: .fromPoints() has been renamed to .setFromPoints()."); return this.setFromPoints(points); }; GridHelper.prototype.setColors = function() { console.error("THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead."); }; SkeletonHelper.prototype.update = function() { console.error("THREE.SkeletonHelper: update() no longer needs to be called."); }; Loader.prototype.extractUrlBase = function(url) { console.warn("THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead."); return LoaderUtils.extractUrlBase(url); }; Loader.Handlers = { add: function() { console.error("THREE.Loader: Handlers.add() has been removed. Use LoadingManager.addHandler() instead."); }, get: function() { console.error("THREE.Loader: Handlers.get() has been removed. Use LoadingManager.getHandler() instead."); } }; Box2.prototype.center = function(optionalTarget) { console.warn("THREE.Box2: .center() has been renamed to .getCenter()."); return this.getCenter(optionalTarget); }; Box2.prototype.empty = function() { console.warn("THREE.Box2: .empty() has been renamed to .isEmpty()."); return this.isEmpty(); }; Box2.prototype.isIntersectionBox = function(box) { console.warn("THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox()."); return this.intersectsBox(box); }; Box2.prototype.size = function(optionalTarget) { console.warn("THREE.Box2: .size() has been renamed to .getSize()."); return this.getSize(optionalTarget); }; Box3.prototype.center = function(optionalTarget) { console.warn("THREE.Box3: .center() has been renamed to .getCenter()."); return this.getCenter(optionalTarget); }; Box3.prototype.empty = function() { console.warn("THREE.Box3: .empty() has been renamed to .isEmpty()."); return this.isEmpty(); }; Box3.prototype.isIntersectionBox = function(box) { console.warn("THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox()."); return this.intersectsBox(box); }; Box3.prototype.isIntersectionSphere = function(sphere) { console.warn("THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere()."); return this.intersectsSphere(sphere); }; Box3.prototype.size = function(optionalTarget) { console.warn("THREE.Box3: .size() has been renamed to .getSize()."); return this.getSize(optionalTarget); }; Sphere.prototype.empty = function() { console.warn("THREE.Sphere: .empty() has been renamed to .isEmpty()."); return this.isEmpty(); }; Frustum.prototype.setFromMatrix = function(m) { console.warn("THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix()."); return this.setFromProjectionMatrix(m); }; Line3.prototype.center = function(optionalTarget) { console.warn("THREE.Line3: .center() has been renamed to .getCenter()."); return this.getCenter(optionalTarget); }; Matrix3.prototype.flattenToArrayOffset = function(array, offset) { console.warn("THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead."); return this.toArray(array, offset); }; Matrix3.prototype.multiplyVector3 = function(vector) { console.warn("THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead."); return vector.applyMatrix3(this); }; Matrix3.prototype.multiplyVector3Array = function() { console.error("THREE.Matrix3: .multiplyVector3Array() has been removed."); }; Matrix3.prototype.applyToBufferAttribute = function(attribute) { console.warn("THREE.Matrix3: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix3( matrix ) instead."); return attribute.applyMatrix3(this); }; Matrix3.prototype.applyToVector3Array = function() { console.error("THREE.Matrix3: .applyToVector3Array() has been removed."); }; Matrix3.prototype.getInverse = function(matrix) { console.warn("THREE.Matrix3: .getInverse() has been removed. Use matrixInv.copy( matrix ).invert(); instead."); return this.copy(matrix).invert(); }; Matrix4.prototype.extractPosition = function(m) { console.warn("THREE.Matrix4: .extractPosition() has been renamed to .copyPosition()."); return this.copyPosition(m); }; Matrix4.prototype.flattenToArrayOffset = function(array, offset) { console.warn("THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead."); return this.toArray(array, offset); }; Matrix4.prototype.getPosition = function() { console.warn("THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead."); return new Vector3().setFromMatrixColumn(this, 3); }; Matrix4.prototype.setRotationFromQuaternion = function(q) { console.warn("THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion()."); return this.makeRotationFromQuaternion(q); }; Matrix4.prototype.multiplyToArray = function() { console.warn("THREE.Matrix4: .multiplyToArray() has been removed."); }; Matrix4.prototype.multiplyVector3 = function(vector) { console.warn("THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead."); return vector.applyMatrix4(this); }; Matrix4.prototype.multiplyVector4 = function(vector) { console.warn("THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead."); return vector.applyMatrix4(this); }; Matrix4.prototype.multiplyVector3Array = function() { console.error("THREE.Matrix4: .multiplyVector3Array() has been removed."); }; Matrix4.prototype.rotateAxis = function(v) { console.warn("THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead."); v.transformDirection(this); }; Matrix4.prototype.crossVector = function(vector) { console.warn("THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead."); return vector.applyMatrix4(this); }; Matrix4.prototype.translate = function() { console.error("THREE.Matrix4: .translate() has been removed."); }; Matrix4.prototype.rotateX = function() { console.error("THREE.Matrix4: .rotateX() has been removed."); }; Matrix4.prototype.rotateY = function() { console.error("THREE.Matrix4: .rotateY() has been removed."); }; Matrix4.prototype.rotateZ = function() { console.error("THREE.Matrix4: .rotateZ() has been removed."); }; Matrix4.prototype.rotateByAxis = function() { console.error("THREE.Matrix4: .rotateByAxis() has been removed."); }; Matrix4.prototype.applyToBufferAttribute = function(attribute) { console.warn("THREE.Matrix4: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix4( matrix ) instead."); return attribute.applyMatrix4(this); }; Matrix4.prototype.applyToVector3Array = function() { console.error("THREE.Matrix4: .applyToVector3Array() has been removed."); }; Matrix4.prototype.makeFrustum = function(left, right, bottom, top, near, far) { console.warn("THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead."); return this.makePerspective(left, right, top, bottom, near, far); }; Matrix4.prototype.getInverse = function(matrix) { console.warn("THREE.Matrix4: .getInverse() has been removed. Use matrixInv.copy( matrix ).invert(); instead."); return this.copy(matrix).invert(); }; Plane.prototype.isIntersectionLine = function(line) { console.warn("THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine()."); return this.intersectsLine(line); }; Quaternion.prototype.multiplyVector3 = function(vector) { console.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead."); return vector.applyQuaternion(this); }; Quaternion.prototype.inverse = function() { console.warn("THREE.Quaternion: .inverse() has been renamed to invert()."); return this.invert(); }; Ray.prototype.isIntersectionBox = function(box) { console.warn("THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox()."); return this.intersectsBox(box); }; Ray.prototype.isIntersectionPlane = function(plane) { console.warn("THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane()."); return this.intersectsPlane(plane); }; Ray.prototype.isIntersectionSphere = function(sphere) { console.warn("THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere()."); return this.intersectsSphere(sphere); }; Triangle.prototype.area = function() { console.warn("THREE.Triangle: .area() has been renamed to .getArea()."); return this.getArea(); }; Triangle.prototype.barycoordFromPoint = function(point, target) { console.warn("THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord()."); return this.getBarycoord(point, target); }; Triangle.prototype.midpoint = function(target) { console.warn("THREE.Triangle: .midpoint() has been renamed to .getMidpoint()."); return this.getMidpoint(target); }; Triangle.prototypenormal = function(target) { console.warn("THREE.Triangle: .normal() has been renamed to .getNormal()."); return this.getNormal(target); }; Triangle.prototype.plane = function(target) { console.warn("THREE.Triangle: .plane() has been renamed to .getPlane()."); return this.getPlane(target); }; Triangle.barycoordFromPoint = function(point, a2, b2, c2, target) { console.warn("THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord()."); return Triangle.getBarycoord(point, a2, b2, c2, target); }; Triangle.normal = function(a2, b2, c2, target) { console.warn("THREE.Triangle: .normal() has been renamed to .getNormal()."); return Triangle.getNormal(a2, b2, c2, target); }; Shape.prototype.extractAllPoints = function(divisions) { console.warn("THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead."); return this.extractPoints(divisions); }; Shape.prototype.extrude = function(options) { console.warn("THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead."); return new ExtrudeGeometry(this, options); }; Shape.prototype.makeGeometry = function(options) { console.warn("THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead."); return new ShapeGeometry(this, options); }; Vector2.prototype.fromAttribute = function(attribute, index, offset) { console.warn("THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute()."); return this.fromBufferAttribute(attribute, index, offset); }; Vector2.prototype.distanceToManhattan = function(v) { console.warn("THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo()."); return this.manhattanDistanceTo(v); }; Vector2.prototype.lengthManhattan = function() { console.warn("THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength()."); return this.manhattanLength(); }; Vector3.prototype.setEulerFromRotationMatrix = function() { console.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead."); }; Vector3.prototype.setEulerFromQuaternion = function() { console.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead."); }; Vector3.prototype.getPositionFromMatrix = function(m) { console.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition()."); return this.setFromMatrixPosition(m); }; Vector3.prototype.getScaleFromMatrix = function(m) { console.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale()."); return this.setFromMatrixScale(m); }; Vector3.prototype.getColumnFromMatrix = function(index, matrix) { console.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn()."); return this.setFromMatrixColumn(matrix, index); }; Vector3.prototype.applyProjection = function(m) { console.warn("THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead."); return this.applyMatrix4(m); }; Vector3.prototype.fromAttribute = function(attribute, index, offset) { console.warn("THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute()."); return this.fromBufferAttribute(attribute, index, offset); }; Vector3.prototype.distanceToManhattan = function(v) { console.warn("THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo()."); return this.manhattanDistanceTo(v); }; Vector3.prototype.lengthManhattan = function() { console.warn("THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength()."); return this.manhattanLength(); }; Vector4.prototype.fromAttribute = function(attribute, index, offset) { console.warn("THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute()."); return this.fromBufferAttribute(attribute, index, offset); }; Vector4.prototype.lengthManhattan = function() { console.warn("THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength()."); return this.manhattanLength(); }; Object3D.prototype.getChildByName = function(name) { console.warn("THREE.Object3D: .getChildByName() has been renamed to .getObjectByName()."); return this.getObjectByName(name); }; Object3D.prototype.renderDepth = function() { console.warn("THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead."); }; Object3D.prototype.translate = function(distance, axis) { console.warn("THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead."); return this.translateOnAxis(axis, distance); }; Object3D.prototype.getWorldRotation = function() { console.error("THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead."); }; Object3D.prototype.applyMatrix = function(matrix) { console.warn("THREE.Object3D: .applyMatrix() has been renamed to .applyMatrix4()."); return this.applyMatrix4(matrix); }; Object.defineProperties(Object3D.prototype, { eulerOrder: { get: function() { console.warn("THREE.Object3D: .eulerOrder is now .rotation.order."); return this.rotation.order; }, set: function(value) { console.warn("THREE.Object3D: .eulerOrder is now .rotation.order."); this.rotation.order = value; } }, useQuaternion: { get: function() { console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default."); }, set: function() { console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default."); } } }); Mesh.prototype.setDrawMode = function() { console.error("THREE.Mesh: .setDrawMode() has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary."); }; Object.defineProperties(Mesh.prototype, { drawMode: { get: function() { console.error("THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode."); return TrianglesDrawMode; }, set: function() { console.error("THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary."); } } }); SkinnedMesh.prototype.initBones = function() { console.error("THREE.SkinnedMesh: initBones() has been removed."); }; PerspectiveCamera.prototype.setLens = function(focalLength, filmGauge) { console.warn("THREE.PerspectiveCamera.setLens is deprecated. Use .setFocalLength and .filmGauge for a photographic setup."); if (filmGauge !== void 0) this.filmGauge = filmGauge; this.setFocalLength(focalLength); }; Object.defineProperties(Light.prototype, { onlyShadow: { set: function() { console.warn("THREE.Light: .onlyShadow has been removed."); } }, shadowCameraFov: { set: function(value) { console.warn("THREE.Light: .shadowCameraFov is now .shadow.camera.fov."); this.shadow.camera.fov = value; } }, shadowCameraLeft: { set: function(value) { console.warn("THREE.Light: .shadowCameraLeft is now .shadow.camera.left."); this.shadow.camera.left = value; } }, shadowCameraRight: { set: function(value) { console.warn("THREE.Light: .shadowCameraRight is now .shadow.camera.right."); this.shadow.camera.right = value; } }, shadowCameraTop: { set: function(value) { console.warn("THREE.Light: .shadowCameraTop is now .shadow.camera.top."); this.shadow.camera.top = value; } }, shadowCameraBottom: { set: function(value) { console.warn("THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom."); this.shadow.camera.bottom = value; } }, shadowCameraNear: { set: function(value) { console.warn("THREE.Light: .shadowCameraNear is now .shadow.camera.near."); this.shadow.camera.near = value; } }, shadowCameraFar: { set: function(value) { console.warn("THREE.Light: .shadowCameraFar is now .shadow.camera.far."); this.shadow.camera.far = value; } }, shadowCameraVisible: { set: function() { console.warn("THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead."); } }, shadowBias: { set: function(value) { console.warn("THREE.Light: .shadowBias is now .shadow.bias."); this.shadow.bias = value; } }, shadowDarkness: { set: function() { console.warn("THREE.Light: .shadowDarkness has been removed."); } }, shadowMapWidth: { set: function(value) { console.warn("THREE.Light: .shadowMapWidth is now .shadow.mapSize.width."); this.shadow.mapSize.width = value; } }, shadowMapHeight: { set: function(value) { console.warn("THREE.Light: .shadowMapHeight is now .shadow.mapSize.height."); this.shadow.mapSize.height = value; } } }); Object.defineProperties(BufferAttribute.prototype, { length: { get: function() { console.warn("THREE.BufferAttribute: .length has been deprecated. Use .count instead."); return this.array.length; } }, dynamic: { get: function() { console.warn("THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead."); return this.usage === DynamicDrawUsage; }, set: function() { console.warn("THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead."); this.setUsage(DynamicDrawUsage); } } }); BufferAttribute.prototype.setDynamic = function(value) { console.warn("THREE.BufferAttribute: .setDynamic() has been deprecated. Use .setUsage() instead."); this.setUsage(value === true ? DynamicDrawUsage : StaticDrawUsage); return this; }; BufferAttribute.prototype.copyIndicesArray = function() { console.error("THREE.BufferAttribute: .copyIndicesArray() has been removed."); }, BufferAttribute.prototype.setArray = function() { console.error("THREE.BufferAttribute: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers"); }; BufferGeometry.prototype.addIndex = function(index) { console.warn("THREE.BufferGeometry: .addIndex() has been renamed to .setIndex()."); this.setIndex(index); }; BufferGeometry.prototype.addAttribute = function(name, attribute) { console.warn("THREE.BufferGeometry: .addAttribute() has been renamed to .setAttribute()."); if (!(attribute && attribute.isBufferAttribute) && !(attribute && attribute.isInterleavedBufferAttribute)) { console.warn("THREE.BufferGeometry: .addAttribute() now expects ( name, attribute )."); return this.setAttribute(name, new BufferAttribute(arguments[1], arguments[2])); } if (name === "index") { console.warn("THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute."); this.setIndex(attribute); return this; } return this.setAttribute(name, attribute); }; BufferGeometry.prototype.addDrawCall = function(start, count, indexOffset) { if (indexOffset !== void 0) { console.warn("THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset."); } console.warn("THREE.BufferGeometry: .addDrawCall() is now .addGroup()."); this.addGroup(start, count); }; BufferGeometry.prototype.clearDrawCalls = function() { console.warn("THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups()."); this.clearGroups(); }; BufferGeometry.prototype.computeOffsets = function() { console.warn("THREE.BufferGeometry: .computeOffsets() has been removed."); }; BufferGeometry.prototype.removeAttribute = function(name) { console.warn("THREE.BufferGeometry: .removeAttribute() has been renamed to .deleteAttribute()."); return this.deleteAttribute(name); }; BufferGeometry.prototype.applyMatrix = function(matrix) { console.warn("THREE.BufferGeometry: .applyMatrix() has been renamed to .applyMatrix4()."); return this.applyMatrix4(matrix); }; Object.defineProperties(BufferGeometry.prototype, { drawcalls: { get: function() { console.error("THREE.BufferGeometry: .drawcalls has been renamed to .groups."); return this.groups; } }, offsets: { get: function() { console.warn("THREE.BufferGeometry: .offsets has been renamed to .groups."); return this.groups; } } }); InterleavedBuffer.prototype.setDynamic = function(value) { console.warn("THREE.InterleavedBuffer: .setDynamic() has been deprecated. Use .setUsage() instead."); this.setUsage(value === true ? DynamicDrawUsage : StaticDrawUsage); return this; }; InterleavedBuffer.prototype.setArray = function() { console.error("THREE.InterleavedBuffer: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers"); }; ExtrudeGeometry.prototype.getArrays = function() { console.error("THREE.ExtrudeGeometry: .getArrays() has been removed."); }; ExtrudeGeometry.prototype.addShapeList = function() { console.error("THREE.ExtrudeGeometry: .addShapeList() has been removed."); }; ExtrudeGeometry.prototype.addShape = function() { console.error("THREE.ExtrudeGeometry: .addShape() has been removed."); }; Scene.prototype.dispose = function() { console.error("THREE.Scene: .dispose() has been removed."); }; Uniform.prototype.onUpdate = function() { console.warn("THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead."); return this; }; Object.defineProperties(Material.prototype, { wrapAround: { get: function() { console.warn("THREE.Material: .wrapAround has been removed."); }, set: function() { console.warn("THREE.Material: .wrapAround has been removed."); } }, overdraw: { get: function() { console.warn("THREE.Material: .overdraw has been removed."); }, set: function() { console.warn("THREE.Material: .overdraw has been removed."); } }, wrapRGB: { get: function() { console.warn("THREE.Material: .wrapRGB has been removed."); return new Color(); } }, shading: { get: function() { console.error("THREE." + this.type + ": .shading has been removed. Use the boolean .flatShading instead."); }, set: function(value) { console.warn("THREE." + this.type + ": .shading has been removed. Use the boolean .flatShading instead."); this.flatShading = value === FlatShading; } }, stencilMask: { get: function() { console.warn("THREE." + this.type + ": .stencilMask has been removed. Use .stencilFuncMask instead."); return this.stencilFuncMask; }, set: function(value) { console.warn("THREE." + this.type + ": .stencilMask has been removed. Use .stencilFuncMask instead."); this.stencilFuncMask = value; } }, vertexTangents: { get: function() { console.warn("THREE." + this.type + ": .vertexTangents has been removed."); }, set: function() { console.warn("THREE." + this.type + ": .vertexTangents has been removed."); } } }); Object.defineProperties(ShaderMaterial.prototype, { derivatives: { get: function() { console.warn("THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives."); return this.extensions.derivatives; }, set: function(value) { console.warn("THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives."); this.extensions.derivatives = value; } } }); WebGLRenderer.prototype.clearTarget = function(renderTarget, color, depth, stencil) { console.warn("THREE.WebGLRenderer: .clearTarget() has been deprecated. Use .setRenderTarget() and .clear() instead."); this.setRenderTarget(renderTarget); this.clear(color, depth, stencil); }; WebGLRenderer.prototype.animate = function(callback) { console.warn("THREE.WebGLRenderer: .animate() is now .setAnimationLoop()."); this.setAnimationLoop(callback); }; WebGLRenderer.prototype.getCurrentRenderTarget = function() { console.warn("THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget()."); return this.getRenderTarget(); }; WebGLRenderer.prototype.getMaxAnisotropy = function() { console.warn("THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy()."); return this.capabilities.getMaxAnisotropy(); }; WebGLRenderer.prototype.getPrecision = function() { console.warn("THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision."); return this.capabilities.precision; }; WebGLRenderer.prototype.resetGLState = function() { console.warn("THREE.WebGLRenderer: .resetGLState() is now .state.reset()."); return this.state.reset(); }; WebGLRenderer.prototype.supportsFloatTextures = function() { console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' )."); return this.extensions.get("OES_texture_float"); }; WebGLRenderer.prototype.supportsHalfFloatTextures = function() { console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' )."); return this.extensions.get("OES_texture_half_float"); }; WebGLRenderer.prototype.supportsStandardDerivatives = function() { console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' )."); return this.extensions.get("OES_standard_derivatives"); }; WebGLRenderer.prototype.supportsCompressedTextureS3TC = function() { console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' )."); return this.extensions.get("WEBGL_compressed_texture_s3tc"); }; WebGLRenderer.prototype.supportsCompressedTexturePVRTC = function() { console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' )."); return this.extensions.get("WEBGL_compressed_texture_pvrtc"); }; WebGLRenderer.prototype.supportsBlendMinMax = function() { console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' )."); return this.extensions.get("EXT_blend_minmax"); }; WebGLRenderer.prototype.supportsVertexTextures = function() { console.warn("THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures."); return this.capabilities.vertexTextures; }; WebGLRenderer.prototype.supportsInstancedArrays = function() { console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' )."); return this.extensions.get("ANGLE_instanced_arrays"); }; WebGLRenderer.prototype.enableScissorTest = function(boolean) { console.warn("THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest()."); this.setScissorTest(boolean); }; WebGLRenderer.prototype.initMaterial = function() { console.warn("THREE.WebGLRenderer: .initMaterial() has been removed."); }; WebGLRenderer.prototype.addPrePlugin = function() { console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed."); }; WebGLRenderer.prototype.addPostPlugin = function() { console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed."); }; WebGLRenderer.prototype.updateShadowMap = function() { console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed."); }; WebGLRenderer.prototype.setFaceCulling = function() { console.warn("THREE.WebGLRenderer: .setFaceCulling() has been removed."); }; WebGLRenderer.prototype.allocTextureUnit = function() { console.warn("THREE.WebGLRenderer: .allocTextureUnit() has been removed."); }; WebGLRenderer.prototype.setTexture = function() { console.warn("THREE.WebGLRenderer: .setTexture() has been removed."); }; WebGLRenderer.prototype.setTexture2D = function() { console.warn("THREE.WebGLRenderer: .setTexture2D() has been removed."); }; WebGLRenderer.prototype.setTextureCube = function() { console.warn("THREE.WebGLRenderer: .setTextureCube() has been removed."); }; WebGLRenderer.prototype.getActiveMipMapLevel = function() { console.warn("THREE.WebGLRenderer: .getActiveMipMapLevel() is now .getActiveMipmapLevel()."); return this.getActiveMipmapLevel(); }; Object.defineProperties(WebGLRenderer.prototype, { shadowMapEnabled: { get: function() { return this.shadowMap.enabled; }, set: function(value) { console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled."); this.shadowMap.enabled = value; } }, shadowMapType: { get: function() { return this.shadowMap.type; }, set: function(value) { console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type."); this.shadowMap.type = value; } }, shadowMapCullFace: { get: function() { console.warn("THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead."); return void 0; }, set: function() { console.warn("THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead."); } }, context: { get: function() { console.warn("THREE.WebGLRenderer: .context has been removed. Use .getContext() instead."); return this.getContext(); } }, vr: { get: function() { console.warn("THREE.WebGLRenderer: .vr has been renamed to .xr"); return this.xr; } }, gammaInput: { get: function() { console.warn("THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead."); return false; }, set: function() { console.warn("THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead."); } }, gammaOutput: { get: function() { console.warn("THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead."); return false; }, set: function(value) { console.warn("THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead."); this.outputEncoding = value === true ? sRGBEncoding : LinearEncoding; } }, toneMappingWhitePoint: { get: function() { console.warn("THREE.WebGLRenderer: .toneMappingWhitePoint has been removed."); return 1; }, set: function() { console.warn("THREE.WebGLRenderer: .toneMappingWhitePoint has been removed."); } } }); Object.defineProperties(WebGLShadowMap.prototype, { cullFace: { get: function() { console.warn("THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead."); return void 0; }, set: function() { console.warn("THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead."); } }, renderReverseSided: { get: function() { console.warn("THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead."); return void 0; }, set: function() { console.warn("THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead."); } }, renderSingleSided: { get: function() { console.warn("THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead."); return void 0; }, set: function() { console.warn("THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead."); } } }); Object.defineProperties(WebGLRenderTarget.prototype, { wrapS: { get: function() { console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS."); return this.texture.wrapS; }, set: function(value) { console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS."); this.texture.wrapS = value; } }, wrapT: { get: function() { console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT."); return this.texture.wrapT; }, set: function(value) { console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT."); this.texture.wrapT = value; } }, magFilter: { get: function() { console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter."); return this.texture.magFilter; }, set: function(value) { console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter."); this.texture.magFilter = value; } }, minFilter: { get: function() { console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter."); return this.texture.minFilter; }, set: function(value) { console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter."); this.texture.minFilter = value; } }, anisotropy: { get: function() { console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy."); return this.texture.anisotropy; }, set: function(value) { console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy."); this.texture.anisotropy = value; } }, offset: { get: function() { console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset."); return this.texture.offset; }, set: function(value) { console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset."); this.texture.offset = value; } }, repeat: { get: function() { console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat."); return this.texture.repeat; }, set: function(value) { console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat."); this.texture.repeat = value; } }, format: { get: function() { console.warn("THREE.WebGLRenderTarget: .format is now .texture.format."); return this.texture.format; }, set: function(value) { console.warn("THREE.WebGLRenderTarget: .format is now .texture.format."); this.texture.format = value; } }, type: { get: function() { console.warn("THREE.WebGLRenderTarget: .type is now .texture.type."); return this.texture.type; }, set: function(value) { console.warn("THREE.WebGLRenderTarget: .type is now .texture.type."); this.texture.type = value; } }, generateMipmaps: { get: function() { console.warn("THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps."); return this.texture.generateMipmaps; }, set: function(value) { console.warn("THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps."); this.texture.generateMipmaps = value; } } }); Audio.prototype.load = function(file) { console.warn("THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead."); const scope = this; const audioLoader = new AudioLoader(); audioLoader.load(file, function(buffer) { scope.setBuffer(buffer); }); return this; }; AudioAnalyser.prototype.getData = function() { console.warn("THREE.AudioAnalyser: .getData() is now .getFrequencyData()."); return this.getFrequencyData(); }; CubeCamera.prototype.updateCubeMap = function(renderer, scene) { console.warn("THREE.CubeCamera: .updateCubeMap() is now .update()."); return this.update(renderer, scene); }; CubeCamera.prototype.clear = function(renderer, color, depth, stencil) { console.warn("THREE.CubeCamera: .clear() is now .renderTarget.clear()."); return this.renderTarget.clear(renderer, color, depth, stencil); }; ImageUtils.crossOrigin = void 0; ImageUtils.loadTexture = function(url, mapping, onLoad, onError) { console.warn("THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead."); const loader = new TextureLoader(); loader.setCrossOrigin(this.crossOrigin); const texture = loader.load(url, onLoad, void 0, onError); if (mapping) texture.mapping = mapping; return texture; }; ImageUtils.loadTextureCube = function(urls, mapping, onLoad, onError) { console.warn("THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead."); const loader = new CubeTextureLoader(); loader.setCrossOrigin(this.crossOrigin); const texture = loader.load(urls, onLoad, void 0, onError); if (mapping) texture.mapping = mapping; return texture; }; ImageUtils.loadCompressedTexture = function() { console.error("THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead."); }; ImageUtils.loadCompressedTextureCube = function() { console.error("THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead."); }; if (typeof __THREE_DEVTOOLS__ !== "undefined") { __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register", { detail: { revision: REVISION } })); } if (typeof window !== "undefined") { if (window.__THREE__) { console.warn("WARNING: Multiple instances of Three.js being imported."); } else { window.__THREE__ = REVISION; } } // node_modules/cannon-es/dist/cannon-es.js var Mat3 = class { constructor(elements = [0, 0, 0, 0, 0, 0, 0, 0, 0]) { this.elements = void 0; this.elements = elements; } identity() { const e = this.elements; e[0] = 1; e[1] = 0; e[2] = 0; e[3] = 0; e[4] = 1; e[5] = 0; e[6] = 0; e[7] = 0; e[8] = 1; } setZero() { const e = this.elements; e[0] = 0; e[1] = 0; e[2] = 0; e[3] = 0; e[4] = 0; e[5] = 0; e[6] = 0; e[7] = 0; e[8] = 0; } setTrace(vector) { const e = this.elements; e[0] = vector.x; e[4] = vector.y; e[8] = vector.z; } getTrace(target = new Vec3()) { const e = this.elements; target.x = e[0]; target.y = e[4]; target.z = e[8]; return target; } vmult(v, target = new Vec3()) { const e = this.elements; const x = v.x; const y = v.y; const z = v.z; target.x = e[0] * x + e[1] * y + e[2] * z; target.y = e[3] * x + e[4] * y + e[5] * z; target.z = e[6] * x + e[7] * y + e[8] * z; return target; } smult(s) { for (let i = 0; i < this.elements.length; i++) { this.elements[i] *= s; } } mmult(matrix, target = new Mat3()) { const A = this.elements; const B = matrix.elements; const T = target.elements; const a11 = A[0], a12 = A[1], a13 = A[2], a21 = A[3], a22 = A[4], a23 = A[5], a31 = A[6], a32 = A[7], a33 = A[8]; const b11 = B[0], b12 = B[1], b13 = B[2], b21 = B[3], b22 = B[4], b23 = B[5], b31 = B[6], b32 = B[7], b33 = B[8]; T[0] = a11 * b11 + a12 * b21 + a13 * b31; T[1] = a11 * b12 + a12 * b22 + a13 * b32; T[2] = a11 * b13 + a12 * b23 + a13 * b33; T[3] = a21 * b11 + a22 * b21 + a23 * b31; T[4] = a21 * b12 + a22 * b22 + a23 * b32; T[5] = a21 * b13 + a22 * b23 + a23 * b33; T[6] = a31 * b11 + a32 * b21 + a33 * b31; T[7] = a31 * b12 + a32 * b22 + a33 * b32; T[8] = a31 * b13 + a32 * b23 + a33 * b33; return target; } scale(vector, target = new Mat3()) { const e = this.elements; const t = target.elements; for (let i = 0; i !== 3; i++) { t[3 * i + 0] = vector.x * e[3 * i + 0]; t[3 * i + 1] = vector.y * e[3 * i + 1]; t[3 * i + 2] = vector.z * e[3 * i + 2]; } return target; } solve(b2, target = new Vec3()) { const nr = 3; const nc = 4; const eqns = []; let i; let j; for (i = 0; i < nr * nc; i++) { eqns.push(0); } for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { eqns[i + nc * j] = this.elements[i + 3 * j]; } } eqns[3 + 4 * 0] = b2.x; eqns[3 + 4 * 1] = b2.y; eqns[3 + 4 * 2] = b2.z; let n = 3; const k = n; let np; const kp = 4; let p2; do { i = k - n; if (eqns[i + nc * i] === 0) { for (j = i + 1; j < k; j++) { if (eqns[i + nc * j] !== 0) { np = kp; do { p2 = kp - np; eqns[p2 + nc * i] += eqns[p2 + nc * j]; } while (--np); break; } } } if (eqns[i + nc * i] !== 0) { for (j = i + 1; j < k; j++) { const multiplier = eqns[i + nc * j] / eqns[i + nc * i]; np = kp; do { p2 = kp - np; eqns[p2 + nc * j] = p2 <= i ? 0 : eqns[p2 + nc * j] - eqns[p2 + nc * i] * multiplier; } while (--np); } } } while (--n); target.z = eqns[2 * nc + 3] / eqns[2 * nc + 2]; target.y = (eqns[1 * nc + 3] - eqns[1 * nc + 2] * target.z) / eqns[1 * nc + 1]; target.x = (eqns[0 * nc + 3] - eqns[0 * nc + 2] * target.z - eqns[0 * nc + 1] * target.y) / eqns[0 * nc + 0]; if (isNaN(target.x) || isNaN(target.y) || isNaN(target.z) || target.x === Infinity || target.y === Infinity || target.z === Infinity) { throw "Could not solve equation! Got x=[" + target.toString() + "], b=[" + b2.toString() + "], A=[" + this.toString() + "]"; } return target; } e(row, column, value) { if (value === void 0) { return this.elements[column + 3 * row]; } else { this.elements[column + 3 * row] = value; } } copy(matrix) { for (let i = 0; i < matrix.elements.length; i++) { this.elements[i] = matrix.elements[i]; } return this; } toString() { let r = ""; const sep = ","; for (let i = 0; i < 9; i++) { r += this.elements[i] + sep; } return r; } reverse(target = new Mat3()) { const nr = 3; const nc = 6; const eqns = reverse_eqns; let i; let j; for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { eqns[i + nc * j] = this.elements[i + 3 * j]; } } eqns[3 + 6 * 0] = 1; eqns[3 + 6 * 1] = 0; eqns[3 + 6 * 2] = 0; eqns[4 + 6 * 0] = 0; eqns[4 + 6 * 1] = 1; eqns[4 + 6 * 2] = 0; eqns[5 + 6 * 0] = 0; eqns[5 + 6 * 1] = 0; eqns[5 + 6 * 2] = 1; let n = 3; const k = n; let np; const kp = nc; let p2; do { i = k - n; if (eqns[i + nc * i] === 0) { for (j = i + 1; j < k; j++) { if (eqns[i + nc * j] !== 0) { np = kp; do { p2 = kp - np; eqns[p2 + nc * i] += eqns[p2 + nc * j]; } while (--np); break; } } } if (eqns[i + nc * i] !== 0) { for (j = i + 1; j < k; j++) { const multiplier = eqns[i + nc * j] / eqns[i + nc * i]; np = kp; do { p2 = kp - np; eqns[p2 + nc * j] = p2 <= i ? 0 : eqns[p2 + nc * j] - eqns[p2 + nc * i] * multiplier; } while (--np); } } } while (--n); i = 2; do { j = i - 1; do { const multiplier = eqns[i + nc * j] / eqns[i + nc * i]; np = nc; do { p2 = nc - np; eqns[p2 + nc * j] = eqns[p2 + nc * j] - eqns[p2 + nc * i] * multiplier; } while (--np); } while (j--); } while (--i); i = 2; do { const multiplier = 1 / eqns[i + nc * i]; np = nc; do { p2 = nc - np; eqns[p2 + nc * i] = eqns[p2 + nc * i] * multiplier; } while (--np); } while (i--); i = 2; do { j = 2; do { p2 = eqns[nr + j + nc * i]; if (isNaN(p2) || p2 === Infinity) { throw "Could not reverse! A=[" + this.toString() + "]"; } target.e(i, j, p2); } while (j--); } while (i--); return target; } setRotationFromQuaternion(q) { const x = q.x; const y = q.y; const z = q.z; const w2 = q.w; const x2 = x + x; const y2 = y + y; const z2 = z + z; const xx = x * x2; const xy = x * y2; const xz = x * z2; const yy = y * y2; const yz = y * z2; const zz = z * z2; const wx = w2 * x2; const wy = w2 * y2; const wz = w2 * z2; const e = this.elements; e[3 * 0 + 0] = 1 - (yy + zz); e[3 * 0 + 1] = xy - wz; e[3 * 0 + 2] = xz + wy; e[3 * 1 + 0] = xy + wz; e[3 * 1 + 1] = 1 - (xx + zz); e[3 * 1 + 2] = yz - wx; e[3 * 2 + 0] = xz - wy; e[3 * 2 + 1] = yz + wx; e[3 * 2 + 2] = 1 - (xx + yy); return this; } transpose(target = new Mat3()) { const M = this.elements; const T = target.elements; let tmp3; T[0] = M[0]; T[4] = M[4]; T[8] = M[8]; tmp3 = M[1]; T[1] = M[3]; T[3] = tmp3; tmp3 = M[2]; T[2] = M[6]; T[6] = tmp3; tmp3 = M[5]; T[5] = M[7]; T[7] = tmp3; return target; } }; var reverse_eqns = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; var Vec3 = class { constructor(x = 0, y = 0, z = 0) { this.x = void 0; this.y = void 0; this.z = void 0; this.x = x; this.y = y; this.z = z; } cross(vector, target = new Vec3()) { const vx = vector.x; const vy = vector.y; const vz = vector.z; const x = this.x; const y = this.y; const z = this.z; target.x = y * vz - z * vy; target.y = z * vx - x * vz; target.z = x * vy - y * vx; return target; } set(x, y, z) { this.x = x; this.y = y; this.z = z; return this; } setZero() { this.x = this.y = this.z = 0; } vadd(vector, target) { if (target) { target.x = vector.x + this.x; target.y = vector.y + this.y; target.z = vector.z + this.z; } else { return new Vec3(this.x + vector.x, this.y + vector.y, this.z + vector.z); } } vsub(vector, target) { if (target) { target.x = this.x - vector.x; target.y = this.y - vector.y; target.z = this.z - vector.z; } else { return new Vec3(this.x - vector.x, this.y - vector.y, this.z - vector.z); } } crossmat() { return new Mat3([0, -this.z, this.y, this.z, 0, -this.x, -this.y, this.x, 0]); } normalize() { const x = this.x; const y = this.y; const z = this.z; const n = Math.sqrt(x * x + y * y + z * z); if (n > 0) { const invN = 1 / n; this.x *= invN; this.y *= invN; this.z *= invN; } else { this.x = 0; this.y = 0; this.z = 0; } return n; } unit(target = new Vec3()) { const x = this.x; const y = this.y; const z = this.z; let ninv = Math.sqrt(x * x + y * y + z * z); if (ninv > 0) { ninv = 1 / ninv; target.x = x * ninv; target.y = y * ninv; target.z = z * ninv; } else { target.x = 1; target.y = 0; target.z = 0; } return target; } length() { const x = this.x; const y = this.y; const z = this.z; return Math.sqrt(x * x + y * y + z * z); } lengthSquared() { return this.dot(this); } distanceTo(p2) { const x = this.x; const y = this.y; const z = this.z; const px2 = p2.x; const py2 = p2.y; const pz2 = p2.z; return Math.sqrt((px2 - x) * (px2 - x) + (py2 - y) * (py2 - y) + (pz2 - z) * (pz2 - z)); } distanceSquared(p2) { const x = this.x; const y = this.y; const z = this.z; const px2 = p2.x; const py2 = p2.y; const pz2 = p2.z; return (px2 - x) * (px2 - x) + (py2 - y) * (py2 - y) + (pz2 - z) * (pz2 - z); } scale(scalar, target = new Vec3()) { const x = this.x; const y = this.y; const z = this.z; target.x = scalar * x; target.y = scalar * y; target.z = scalar * z; return target; } vmul(vector, target = new Vec3()) { target.x = vector.x * this.x; target.y = vector.y * this.y; target.z = vector.z * this.z; return target; } addScaledVector(scalar, vector, target = new Vec3()) { target.x = this.x + scalar * vector.x; target.y = this.y + scalar * vector.y; target.z = this.z + scalar * vector.z; return target; } dot(vector) { return this.x * vector.x + this.y * vector.y + this.z * vector.z; } isZero() { return this.x === 0 && this.y === 0 && this.z === 0; } negate(target = new Vec3()) { target.x = -this.x; target.y = -this.y; target.z = -this.z; return target; } tangents(t1, t2) { const norm = this.length(); if (norm > 0) { const n = Vec3_tangents_n; const inorm = 1 / norm; n.set(this.x * inorm, this.y * inorm, this.z * inorm); const randVec = Vec3_tangents_randVec; if (Math.abs(n.x) < 0.9) { randVec.set(1, 0, 0); n.cross(randVec, t1); } else { randVec.set(0, 1, 0); n.cross(randVec, t1); } n.cross(t1, t2); } else { t1.set(1, 0, 0); t2.set(0, 1, 0); } } toString() { return this.x + "," + this.y + "," + this.z; } toArray() { return [this.x, this.y, this.z]; } copy(vector) { this.x = vector.x; this.y = vector.y; this.z = vector.z; return this; } lerp(vector, t, target) { const x = this.x; const y = this.y; const z = this.z; target.x = x + (vector.x - x) * t; target.y = y + (vector.y - y) * t; target.z = z + (vector.z - z) * t; } almostEquals(vector, precision = 1e-6) { if (Math.abs(this.x - vector.x) > precision || Math.abs(this.y - vector.y) > precision || Math.abs(this.z - vector.z) > precision) { return false; } return true; } almostZero(precision = 1e-6) { if (Math.abs(this.x) > precision || Math.abs(this.y) > precision || Math.abs(this.z) > precision) { return false; } return true; } isAntiparallelTo(vector, precision) { this.negate(antip_neg); return antip_neg.almostEquals(vector, precision); } clone() { return new Vec3(this.x, this.y, this.z); } }; Vec3.ZERO = void 0; Vec3.UNIT_X = void 0; Vec3.UNIT_Y = void 0; Vec3.UNIT_Z = void 0; Vec3.ZERO = new Vec3(0, 0, 0); Vec3.UNIT_X = new Vec3(1, 0, 0); Vec3.UNIT_Y = new Vec3(0, 1, 0); Vec3.UNIT_Z = new Vec3(0, 0, 1); var Vec3_tangents_n = new Vec3(); var Vec3_tangents_randVec = new Vec3(); var antip_neg = new Vec3(); var AABB = class { constructor(options = {}) { this.lowerBound = void 0; this.upperBound = void 0; this.lowerBound = new Vec3(); this.upperBound = new Vec3(); if (options.lowerBound) { this.lowerBound.copy(options.lowerBound); } if (options.upperBound) { this.upperBound.copy(options.upperBound); } } setFromPoints(points, position, quaternion, skinSize) { const l = this.lowerBound; const u = this.upperBound; const q = quaternion; l.copy(points[0]); if (q) { q.vmult(l, l); } u.copy(l); for (let i = 1; i < points.length; i++) { let p2 = points[i]; if (q) { q.vmult(p2, tmp$1); p2 = tmp$1; } if (p2.x > u.x) { u.x = p2.x; } if (p2.x < l.x) { l.x = p2.x; } if (p2.y > u.y) { u.y = p2.y; } if (p2.y < l.y) { l.y = p2.y; } if (p2.z > u.z) { u.z = p2.z; } if (p2.z < l.z) { l.z = p2.z; } } if (position) { position.vadd(l, l); position.vadd(u, u); } if (skinSize) { l.x -= skinSize; l.y -= skinSize; l.z -= skinSize; u.x += skinSize; u.y += skinSize; u.z += skinSize; } return this; } copy(aabb) { this.lowerBound.copy(aabb.lowerBound); this.upperBound.copy(aabb.upperBound); return this; } clone() { return new AABB().copy(this); } extend(aabb) { this.lowerBound.x = Math.min(this.lowerBound.x, aabb.lowerBound.x); this.upperBound.x = Math.max(this.upperBound.x, aabb.upperBound.x); this.lowerBound.y = Math.min(this.lowerBound.y, aabb.lowerBound.y); this.upperBound.y = Math.max(this.upperBound.y, aabb.upperBound.y); this.lowerBound.z = Math.min(this.lowerBound.z, aabb.lowerBound.z); this.upperBound.z = Math.max(this.upperBound.z, aabb.upperBound.z); } overlaps(aabb) { const l1 = this.lowerBound; const u1 = this.upperBound; const l2 = aabb.lowerBound; const u2 = aabb.upperBound; const overlapsX = l2.x <= u1.x && u1.x <= u2.x || l1.x <= u2.x && u2.x <= u1.x; const overlapsY = l2.y <= u1.y && u1.y <= u2.y || l1.y <= u2.y && u2.y <= u1.y; const overlapsZ = l2.z <= u1.z && u1.z <= u2.z || l1.z <= u2.z && u2.z <= u1.z; return overlapsX && overlapsY && overlapsZ; } volume() { const l = this.lowerBound; const u = this.upperBound; return (u.x - l.x) * (u.y - l.y) * (u.z - l.z); } contains(aabb) { const l1 = this.lowerBound; const u1 = this.upperBound; const l2 = aabb.lowerBound; const u2 = aabb.upperBound; return l1.x <= l2.x && u1.x >= u2.x && l1.y <= l2.y && u1.y >= u2.y && l1.z <= l2.z && u1.z >= u2.z; } getCorners(a2, b2, c2, d, e, f, g, h) { const l = this.lowerBound; const u = this.upperBound; a2.copy(l); b2.set(u.x, l.y, l.z); c2.set(u.x, u.y, l.z); d.set(l.x, u.y, u.z); e.set(u.x, l.y, u.z); f.set(l.x, u.y, l.z); g.set(l.x, l.y, u.z); h.copy(u); } toLocalFrame(frame, target) { const corners = transformIntoFrame_corners; const a2 = corners[0]; const b2 = corners[1]; const c2 = corners[2]; const d = corners[3]; const e = corners[4]; const f = corners[5]; const g = corners[6]; const h = corners[7]; this.getCorners(a2, b2, c2, d, e, f, g, h); for (let i = 0; i !== 8; i++) { const corner = corners[i]; frame.pointToLocal(corner, corner); } return target.setFromPoints(corners); } toWorldFrame(frame, target) { const corners = transformIntoFrame_corners; const a2 = corners[0]; const b2 = corners[1]; const c2 = corners[2]; const d = corners[3]; const e = corners[4]; const f = corners[5]; const g = corners[6]; const h = corners[7]; this.getCorners(a2, b2, c2, d, e, f, g, h); for (let i = 0; i !== 8; i++) { const corner = corners[i]; frame.pointToWorld(corner, corner); } return target.setFromPoints(corners); } overlapsRay(ray) { const { direction, from } = ray; const dirFracX = 1 / direction.x; const dirFracY = 1 / direction.y; const dirFracZ = 1 / direction.z; const t1 = (this.lowerBound.x - from.x) * dirFracX; const t2 = (this.upperBound.x - from.x) * dirFracX; const t3 = (this.lowerBound.y - from.y) * dirFracY; const t4 = (this.upperBound.y - from.y) * dirFracY; const t5 = (this.lowerBound.z - from.z) * dirFracZ; const t6 = (this.upperBound.z - from.z) * dirFracZ; const tmin = Math.max(Math.max(Math.min(t1, t2), Math.min(t3, t4)), Math.min(t5, t6)); const tmax = Math.min(Math.min(Math.max(t1, t2), Math.max(t3, t4)), Math.max(t5, t6)); if (tmax < 0) { return false; } if (tmin > tmax) { return false; } return true; } }; var tmp$1 = new Vec3(); var transformIntoFrame_corners = [new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3()]; var ArrayCollisionMatrix = class { constructor() { this.matrix = void 0; this.matrix = []; } get(bi, bj) { let { index: i } = bi; let { index: j } = bj; if (j > i) { const temp = j; j = i; i = temp; } return this.matrix[(i * (i + 1) >> 1) + j - 1]; } set(bi, bj, value) { let { index: i } = bi; let { index: j } = bj; if (j > i) { const temp = j; j = i; i = temp; } this.matrix[(i * (i + 1) >> 1) + j - 1] = value ? 1 : 0; } reset() { for (let i = 0, l = this.matrix.length; i !== l; i++) { this.matrix[i] = 0; } } setNumObjects(n) { this.matrix.length = n * (n - 1) >> 1; } }; var EventTarget = class { constructor() { this._listeners = void 0; } addEventListener(type, listener3) { if (this._listeners === void 0) { this._listeners = {}; } const listeners = this._listeners; if (listeners[type] === void 0) { listeners[type] = []; } if (!listeners[type].includes(listener3)) { listeners[type].push(listener3); } return this; } hasEventListener(type, listener3) { if (this._listeners === void 0) { return false; } const listeners = this._listeners; if (listeners[type] !== void 0 && listeners[type].includes(listener3)) { return true; } return false; } hasAnyEventListener(type) { if (this._listeners === void 0) { return false; } const listeners = this._listeners; return listeners[type] !== void 0; } removeEventListener(type, listener3) { if (this._listeners === void 0) { return this; } const listeners = this._listeners; if (listeners[type] === void 0) { return this; } const index = listeners[type].indexOf(listener3); if (index !== -1) { listeners[type].splice(index, 1); } return this; } dispatchEvent(event) { if (this._listeners === void 0) { return this; } const listeners = this._listeners; const listenerArray = listeners[event.type]; if (listenerArray !== void 0) { event.target = this; for (let i = 0, l = listenerArray.length; i < l; i++) { listenerArray[i].call(this, event); } } return this; } }; var Quaternion2 = class { constructor(x = 0, y = 0, z = 0, w2 = 1) { this.x = void 0; this.y = void 0; this.z = void 0; this.w = void 0; this.x = x; this.y = y; this.z = z; this.w = w2; } set(x, y, z, w2) { this.x = x; this.y = y; this.z = z; this.w = w2; return this; } toString() { return this.x + "," + this.y + "," + this.z + "," + this.w; } toArray() { return [this.x, this.y, this.z, this.w]; } setFromAxisAngle(vector, angle) { const s = Math.sin(angle * 0.5); this.x = vector.x * s; this.y = vector.y * s; this.z = vector.z * s; this.w = Math.cos(angle * 0.5); return this; } toAxisAngle(targetAxis = new Vec3()) { this.normalize(); const angle = 2 * Math.acos(this.w); const s = Math.sqrt(1 - this.w * this.w); if (s < 1e-3) { targetAxis.x = this.x; targetAxis.y = this.y; targetAxis.z = this.z; } else { targetAxis.x = this.x / s; targetAxis.y = this.y / s; targetAxis.z = this.z / s; } return [targetAxis, angle]; } setFromVectors(u, v) { if (u.isAntiparallelTo(v)) { const t1 = sfv_t1; const t2 = sfv_t2; u.tangents(t1, t2); this.setFromAxisAngle(t1, Math.PI); } else { const a2 = u.cross(v); this.x = a2.x; this.y = a2.y; this.z = a2.z; this.w = Math.sqrt(u.length() ** 2 * v.length() ** 2) + u.dot(v); this.normalize(); } return this; } mult(quat, target = new Quaternion2()) { const ax = this.x; const ay = this.y; const az = this.z; const aw = this.w; const bx = quat.x; const by = quat.y; const bz = quat.z; const bw = quat.w; target.x = ax * bw + aw * bx + ay * bz - az * by; target.y = ay * bw + aw * by + az * bx - ax * bz; target.z = az * bw + aw * bz + ax * by - ay * bx; target.w = aw * bw - ax * bx - ay * by - az * bz; return target; } inverse(target = new Quaternion2()) { const x = this.x; const y = this.y; const z = this.z; const w2 = this.w; this.conjugate(target); const inorm2 = 1 / (x * x + y * y + z * z + w2 * w2); target.x *= inorm2; target.y *= inorm2; target.z *= inorm2; target.w *= inorm2; return target; } conjugate(target = new Quaternion2()) { target.x = -this.x; target.y = -this.y; target.z = -this.z; target.w = this.w; return target; } normalize() { let l = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); if (l === 0) { this.x = 0; this.y = 0; this.z = 0; this.w = 0; } else { l = 1 / l; this.x *= l; this.y *= l; this.z *= l; this.w *= l; } return this; } normalizeFast() { const f = (3 - (this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w)) / 2; if (f === 0) { this.x = 0; this.y = 0; this.z = 0; this.w = 0; } else { this.x *= f; this.y *= f; this.z *= f; this.w *= f; } return this; } vmult(v, target = new Vec3()) { const x = v.x; const y = v.y; const z = v.z; const qx = this.x; const qy = this.y; const qz = this.z; const qw = this.w; const ix = qw * x + qy * z - qz * y; const iy = qw * y + qz * x - qx * z; const iz = qw * z + qx * y - qy * x; const iw = -qx * x - qy * y - qz * z; target.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; target.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; target.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; return target; } copy(quat) { this.x = quat.x; this.y = quat.y; this.z = quat.z; this.w = quat.w; return this; } toEuler(target, order = "YZX") { let heading; let attitude; let bank; const x = this.x; const y = this.y; const z = this.z; const w2 = this.w; switch (order) { case "YZX": const test = x * y + z * w2; if (test > 0.499) { heading = 2 * Math.atan2(x, w2); attitude = Math.PI / 2; bank = 0; } if (test < -0.499) { heading = -2 * Math.atan2(x, w2); attitude = -Math.PI / 2; bank = 0; } if (heading === void 0) { const sqx = x * x; const sqy = y * y; const sqz = z * z; heading = Math.atan2(2 * y * w2 - 2 * x * z, 1 - 2 * sqy - 2 * sqz); attitude = Math.asin(2 * test); bank = Math.atan2(2 * x * w2 - 2 * y * z, 1 - 2 * sqx - 2 * sqz); } break; default: throw new Error("Euler order " + order + " not supported yet."); } target.y = heading; target.z = attitude; target.x = bank; } setFromEuler(x, y, z, order = "XYZ") { const c1 = Math.cos(x / 2); const c2 = Math.cos(y / 2); const c3 = Math.cos(z / 2); const s1 = Math.sin(x / 2); const s2 = Math.sin(y / 2); const s3 = Math.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; } return this; } clone() { return new Quaternion2(this.x, this.y, this.z, this.w); } slerp(toQuat, t, target = new Quaternion2()) { const ax = this.x; const ay = this.y; const az = this.z; const aw = this.w; let bx = toQuat.x; let by = toQuat.y; let bz = toQuat.z; let bw = toQuat.w; let omega; let cosom; let sinom; let scale0; let scale1; cosom = ax * bx + ay * by + az * bz + aw * bw; if (cosom < 0) { cosom = -cosom; bx = -bx; by = -by; bz = -bz; bw = -bw; } if (1 - cosom > 1e-6) { omega = Math.acos(cosom); sinom = Math.sin(omega); scale0 = Math.sin((1 - t) * omega) / sinom; scale1 = Math.sin(t * omega) / sinom; } else { scale0 = 1 - t; scale1 = t; } target.x = scale0 * ax + scale1 * bx; target.y = scale0 * ay + scale1 * by; target.z = scale0 * az + scale1 * bz; target.w = scale0 * aw + scale1 * bw; return target; } integrate(angularVelocity, dt, angularFactor, target = new Quaternion2()) { const ax = angularVelocity.x * angularFactor.x, ay = angularVelocity.y * angularFactor.y, az = angularVelocity.z * angularFactor.z, bx = this.x, by = this.y, bz = this.z, bw = this.w; const half_dt = dt * 0.5; target.x += half_dt * (ax * bw + ay * bz - az * by); target.y += half_dt * (ay * bw + az * bx - ax * bz); target.z += half_dt * (az * bw + ax * by - ay * bx); target.w += half_dt * (-ax * bx - ay * by - az * bz); return target; } }; var sfv_t1 = new Vec3(); var sfv_t2 = new Vec3(); var SHAPE_TYPES = { SPHERE: 1, PLANE: 2, BOX: 4, COMPOUND: 8, CONVEXPOLYHEDRON: 16, HEIGHTFIELD: 32, PARTICLE: 64, CYLINDER: 128, TRIMESH: 256 }; var Shape2 = class { constructor(options = {}) { this.id = void 0; this.type = void 0; this.boundingSphereRadius = void 0; this.collisionResponse = void 0; this.collisionFilterGroup = void 0; this.collisionFilterMask = void 0; this.material = void 0; this.body = void 0; this.id = Shape2.idCounter++; this.type = options.type || 0; this.boundingSphereRadius = 0; this.collisionResponse = options.collisionResponse ? options.collisionResponse : true; this.collisionFilterGroup = options.collisionFilterGroup !== void 0 ? options.collisionFilterGroup : 1; this.collisionFilterMask = options.collisionFilterMask !== void 0 ? options.collisionFilterMask : -1; this.material = options.material ? options.material : null; this.body = null; } updateBoundingSphereRadius() { throw "computeBoundingSphereRadius() not implemented for shape type " + this.type; } volume() { throw "volume() not implemented for shape type " + this.type; } calculateLocalInertia(mass, target) { throw "calculateLocalInertia() not implemented for shape type " + this.type; } calculateWorldAABB(pos, quat, min, max) { throw "calculateWorldAABB() not implemented for shape type " + this.type; } }; Shape2.idCounter = 0; Shape2.types = SHAPE_TYPES; var Transform = class { constructor(options = {}) { this.position = void 0; this.quaternion = void 0; this.position = new Vec3(); this.quaternion = new Quaternion2(); if (options.position) { this.position.copy(options.position); } if (options.quaternion) { this.quaternion.copy(options.quaternion); } } pointToLocal(worldPoint, result) { return Transform.pointToLocalFrame(this.position, this.quaternion, worldPoint, result); } pointToWorld(localPoint, result) { return Transform.pointToWorldFrame(this.position, this.quaternion, localPoint, result); } vectorToWorldFrame(localVector, result = new Vec3()) { this.quaternion.vmult(localVector, result); return result; } static pointToLocalFrame(position, quaternion, worldPoint, result = new Vec3()) { worldPoint.vsub(position, result); quaternion.conjugate(tmpQuat$1); tmpQuat$1.vmult(result, result); return result; } static pointToWorldFrame(position, quaternion, localPoint, result = new Vec3()) { quaternion.vmult(localPoint, result); result.vadd(position, result); return result; } static vectorToWorldFrame(quaternion, localVector, result = new Vec3()) { quaternion.vmult(localVector, result); return result; } static vectorToLocalFrame(position, quaternion, worldVector, result = new Vec3()) { quaternion.w *= -1; quaternion.vmult(worldVector, result); quaternion.w *= -1; return result; } }; var tmpQuat$1 = new Quaternion2(); var ConvexPolyhedron = class extends Shape2 { constructor(props = {}) { const { vertices = [], faces = [], normals = [], axes, boundingSphereRadius } = props; super({ type: Shape2.types.CONVEXPOLYHEDRON }); this.vertices = void 0; this.faces = void 0; this.faceNormals = void 0; this.worldVertices = void 0; this.worldVerticesNeedsUpdate = void 0; this.worldFaceNormals = void 0; this.worldFaceNormalsNeedsUpdate = void 0; this.uniqueAxes = void 0; this.uniqueEdges = void 0; this.vertices = vertices; this.faces = faces; this.faceNormals = normals; if (this.faceNormals.length === 0) { this.computeNormals(); } if (!boundingSphereRadius) { this.updateBoundingSphereRadius(); } else { this.boundingSphereRadius = boundingSphereRadius; } this.worldVertices = []; this.worldVerticesNeedsUpdate = true; this.worldFaceNormals = []; this.worldFaceNormalsNeedsUpdate = true; this.uniqueAxes = axes ? axes.slice() : null; this.uniqueEdges = []; this.computeEdges(); } computeEdges() { const faces = this.faces; const vertices = this.vertices; const edges = this.uniqueEdges; edges.length = 0; const edge = new Vec3(); for (let i = 0; i !== faces.length; i++) { const face = faces[i]; const numVertices = face.length; for (let j = 0; j !== numVertices; j++) { const k = (j + 1) % numVertices; vertices[face[j]].vsub(vertices[face[k]], edge); edge.normalize(); let found = false; for (let p2 = 0; p2 !== edges.length; p2++) { if (edges[p2].almostEquals(edge) || edges[p2].almostEquals(edge)) { found = true; break; } } if (!found) { edges.push(edge.clone()); } } } } computeNormals() { this.faceNormals.length = this.faces.length; for (let i = 0; i < this.faces.length; i++) { for (let j = 0; j < this.faces[i].length; j++) { if (!this.vertices[this.faces[i][j]]) { throw new Error("Vertex " + this.faces[i][j] + " not found!"); } } const n = this.faceNormals[i] || new Vec3(); this.getFaceNormal(i, n); n.negate(n); this.faceNormals[i] = n; const vertex = this.vertices[this.faces[i][0]]; if (n.dot(vertex) < 0) { console.error(".faceNormals[" + i + "] = Vec3(" + n.toString() + ") looks like it points into the shape? The vertices follow. Make sure they are ordered CCW around the normal, using the right hand rule."); for (let j = 0; j < this.faces[i].length; j++) { console.warn(".vertices[" + this.faces[i][j] + "] = Vec3(" + this.vertices[this.faces[i][j]].toString() + ")"); } } } } getFaceNormal(i, target) { const f = this.faces[i]; const va2 = this.vertices[f[0]]; const vb2 = this.vertices[f[1]]; const vc2 = this.vertices[f[2]]; ConvexPolyhedron.computeNormal(va2, vb2, vc2, target); } static computeNormal(va2, vb2, vc2, target) { const cb2 = new Vec3(); const ab2 = new Vec3(); vb2.vsub(va2, ab2); vc2.vsub(vb2, cb2); cb2.cross(ab2, target); if (!target.isZero()) { target.normalize(); } } clipAgainstHull(posA, quatA, hullB, posB, quatB, separatingNormal, minDist, maxDist, result) { const WorldNormal = new Vec3(); let closestFaceB = -1; let dmax = -Number.MAX_VALUE; for (let face = 0; face < hullB.faces.length; face++) { WorldNormal.copy(hullB.faceNormals[face]); quatB.vmult(WorldNormal, WorldNormal); const d = WorldNormal.dot(separatingNormal); if (d > dmax) { dmax = d; closestFaceB = face; } } const worldVertsB1 = []; for (let i = 0; i < hullB.faces[closestFaceB].length; i++) { const b2 = hullB.vertices[hullB.faces[closestFaceB][i]]; const worldb = new Vec3(); worldb.copy(b2); quatB.vmult(worldb, worldb); posB.vadd(worldb, worldb); worldVertsB1.push(worldb); } if (closestFaceB >= 0) { this.clipFaceAgainstHull(separatingNormal, posA, quatA, worldVertsB1, minDist, maxDist, result); } } findSeparatingAxis(hullB, posA, quatA, posB, quatB, target, faceListA, faceListB) { const faceANormalWS3 = new Vec3(); const Worldnormal1 = new Vec3(); const deltaC = new Vec3(); const worldEdge0 = new Vec3(); const worldEdge1 = new Vec3(); const Cross = new Vec3(); let dmin = Number.MAX_VALUE; const hullA = this; if (!hullA.uniqueAxes) { const numFacesA = faceListA ? faceListA.length : hullA.faces.length; for (let i = 0; i < numFacesA; i++) { const fi = faceListA ? faceListA[i] : i; faceANormalWS3.copy(hullA.faceNormals[fi]); quatA.vmult(faceANormalWS3, faceANormalWS3); const d = hullA.testSepAxis(faceANormalWS3, hullB, posA, quatA, posB, quatB); if (d === false) { return false; } if (d < dmin) { dmin = d; target.copy(faceANormalWS3); } } } else { for (let i = 0; i !== hullA.uniqueAxes.length; i++) { quatA.vmult(hullA.uniqueAxes[i], faceANormalWS3); const d = hullA.testSepAxis(faceANormalWS3, hullB, posA, quatA, posB, quatB); if (d === false) { return false; } if (d < dmin) { dmin = d; target.copy(faceANormalWS3); } } } if (!hullB.uniqueAxes) { const numFacesB = faceListB ? faceListB.length : hullB.faces.length; for (let i = 0; i < numFacesB; i++) { const fi = faceListB ? faceListB[i] : i; Worldnormal1.copy(hullB.faceNormals[fi]); quatB.vmult(Worldnormal1, Worldnormal1); const d = hullA.testSepAxis(Worldnormal1, hullB, posA, quatA, posB, quatB); if (d === false) { return false; } if (d < dmin) { dmin = d; target.copy(Worldnormal1); } } } else { for (let i = 0; i !== hullB.uniqueAxes.length; i++) { quatB.vmult(hullB.uniqueAxes[i], Worldnormal1); const d = hullA.testSepAxis(Worldnormal1, hullB, posA, quatA, posB, quatB); if (d === false) { return false; } if (d < dmin) { dmin = d; target.copy(Worldnormal1); } } } for (let e0 = 0; e0 !== hullA.uniqueEdges.length; e0++) { quatA.vmult(hullA.uniqueEdges[e0], worldEdge0); for (let e1 = 0; e1 !== hullB.uniqueEdges.length; e1++) { quatB.vmult(hullB.uniqueEdges[e1], worldEdge1); worldEdge0.cross(worldEdge1, Cross); if (!Cross.almostZero()) { Cross.normalize(); const dist = hullA.testSepAxis(Cross, hullB, posA, quatA, posB, quatB); if (dist === false) { return false; } if (dist < dmin) { dmin = dist; target.copy(Cross); } } } } posB.vsub(posA, deltaC); if (deltaC.dot(target) > 0) { target.negate(target); } return true; } testSepAxis(axis, hullB, posA, quatA, posB, quatB) { const hullA = this; ConvexPolyhedron.project(hullA, axis, posA, quatA, maxminA); ConvexPolyhedron.project(hullB, axis, posB, quatB, maxminB); const maxA = maxminA[0]; const minA = maxminA[1]; const maxB = maxminB[0]; const minB = maxminB[1]; if (maxA < minB || maxB < minA) { return false; } const d0 = maxA - minB; const d1 = maxB - minA; const depth = d0 < d1 ? d0 : d1; return depth; } calculateLocalInertia(mass, target) { const aabbmax = new Vec3(); const aabbmin = new Vec3(); this.computeLocalAABB(aabbmin, aabbmax); const x = aabbmax.x - aabbmin.x; const y = aabbmax.y - aabbmin.y; const z = aabbmax.z - aabbmin.z; target.x = 1 / 12 * mass * (2 * y * 2 * y + 2 * z * 2 * z); target.y = 1 / 12 * mass * (2 * x * 2 * x + 2 * z * 2 * z); target.z = 1 / 12 * mass * (2 * y * 2 * y + 2 * x * 2 * x); } getPlaneConstantOfFace(face_i) { const f = this.faces[face_i]; const n = this.faceNormals[face_i]; const v = this.vertices[f[0]]; const c2 = -n.dot(v); return c2; } clipFaceAgainstHull(separatingNormal, posA, quatA, worldVertsB1, minDist, maxDist, result) { const faceANormalWS = new Vec3(); const edge0 = new Vec3(); const WorldEdge0 = new Vec3(); const worldPlaneAnormal1 = new Vec3(); const planeNormalWS1 = new Vec3(); const worldA1 = new Vec3(); const localPlaneNormal = new Vec3(); const planeNormalWS = new Vec3(); const hullA = this; const worldVertsB2 = []; const pVtxIn = worldVertsB1; const pVtxOut = worldVertsB2; let closestFaceA = -1; let dmin = Number.MAX_VALUE; for (let face = 0; face < hullA.faces.length; face++) { faceANormalWS.copy(hullA.faceNormals[face]); quatA.vmult(faceANormalWS, faceANormalWS); const d = faceANormalWS.dot(separatingNormal); if (d < dmin) { dmin = d; closestFaceA = face; } } if (closestFaceA < 0) { return; } const polyA = hullA.faces[closestFaceA]; polyA.connectedFaces = []; for (let i = 0; i < hullA.faces.length; i++) { for (let j = 0; j < hullA.faces[i].length; j++) { if (polyA.indexOf(hullA.faces[i][j]) !== -1 && i !== closestFaceA && polyA.connectedFaces.indexOf(i) === -1) { polyA.connectedFaces.push(i); } } } const numVerticesA = polyA.length; for (let i = 0; i < numVerticesA; i++) { const a2 = hullA.vertices[polyA[i]]; const b2 = hullA.vertices[polyA[(i + 1) % numVerticesA]]; a2.vsub(b2, edge0); WorldEdge0.copy(edge0); quatA.vmult(WorldEdge0, WorldEdge0); posA.vadd(WorldEdge0, WorldEdge0); worldPlaneAnormal1.copy(this.faceNormals[closestFaceA]); quatA.vmult(worldPlaneAnormal1, worldPlaneAnormal1); posA.vadd(worldPlaneAnormal1, worldPlaneAnormal1); WorldEdge0.cross(worldPlaneAnormal1, planeNormalWS1); planeNormalWS1.negate(planeNormalWS1); worldA1.copy(a2); quatA.vmult(worldA1, worldA1); posA.vadd(worldA1, worldA1); const otherFace = polyA.connectedFaces[i]; localPlaneNormal.copy(this.faceNormals[otherFace]); const localPlaneEq2 = this.getPlaneConstantOfFace(otherFace); planeNormalWS.copy(localPlaneNormal); quatA.vmult(planeNormalWS, planeNormalWS); const planeEqWS2 = localPlaneEq2 - planeNormalWS.dot(posA); this.clipFaceAgainstPlane(pVtxIn, pVtxOut, planeNormalWS, planeEqWS2); while (pVtxIn.length) { pVtxIn.shift(); } while (pVtxOut.length) { pVtxIn.push(pVtxOut.shift()); } } localPlaneNormal.copy(this.faceNormals[closestFaceA]); const localPlaneEq = this.getPlaneConstantOfFace(closestFaceA); planeNormalWS.copy(localPlaneNormal); quatA.vmult(planeNormalWS, planeNormalWS); const planeEqWS = localPlaneEq - planeNormalWS.dot(posA); for (let i = 0; i < pVtxIn.length; i++) { let depth = planeNormalWS.dot(pVtxIn[i]) + planeEqWS; if (depth <= minDist) { console.log("clamped: depth=" + depth + " to minDist=" + minDist); depth = minDist; } if (depth <= maxDist) { const point = pVtxIn[i]; if (depth <= 1e-6) { const p2 = { point, normal: planeNormalWS, depth }; result.push(p2); } } } } clipFaceAgainstPlane(inVertices, outVertices, planeNormal, planeConstant) { let n_dot_first; let n_dot_last; const numVerts = inVertices.length; if (numVerts < 2) { return outVertices; } let firstVertex = inVertices[inVertices.length - 1]; let lastVertex = inVertices[0]; n_dot_first = planeNormal.dot(firstVertex) + planeConstant; for (let vi = 0; vi < numVerts; vi++) { lastVertex = inVertices[vi]; n_dot_last = planeNormal.dot(lastVertex) + planeConstant; if (n_dot_first < 0) { if (n_dot_last < 0) { const newv = new Vec3(); newv.copy(lastVertex); outVertices.push(newv); } else { const newv = new Vec3(); firstVertex.lerp(lastVertex, n_dot_first / (n_dot_first - n_dot_last), newv); outVertices.push(newv); } } else { if (n_dot_last < 0) { const newv = new Vec3(); firstVertex.lerp(lastVertex, n_dot_first / (n_dot_first - n_dot_last), newv); outVertices.push(newv); outVertices.push(lastVertex); } } firstVertex = lastVertex; n_dot_first = n_dot_last; } return outVertices; } computeWorldVertices(position, quat) { while (this.worldVertices.length < this.vertices.length) { this.worldVertices.push(new Vec3()); } const verts = this.vertices; const worldVerts = this.worldVertices; for (let i = 0; i !== this.vertices.length; i++) { quat.vmult(verts[i], worldVerts[i]); position.vadd(worldVerts[i], worldVerts[i]); } this.worldVerticesNeedsUpdate = false; } computeLocalAABB(aabbmin, aabbmax) { const vertices = this.vertices; aabbmin.set(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); aabbmax.set(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); for (let i = 0; i < this.vertices.length; i++) { const v = vertices[i]; if (v.x < aabbmin.x) { aabbmin.x = v.x; } else if (v.x > aabbmax.x) { aabbmax.x = v.x; } if (v.y < aabbmin.y) { aabbmin.y = v.y; } else if (v.y > aabbmax.y) { aabbmax.y = v.y; } if (v.z < aabbmin.z) { aabbmin.z = v.z; } else if (v.z > aabbmax.z) { aabbmax.z = v.z; } } } computeWorldFaceNormals(quat) { const N = this.faceNormals.length; while (this.worldFaceNormals.length < N) { this.worldFaceNormals.push(new Vec3()); } const normals = this.faceNormals; const worldNormals = this.worldFaceNormals; for (let i = 0; i !== N; i++) { quat.vmult(normals[i], worldNormals[i]); } this.worldFaceNormalsNeedsUpdate = false; } updateBoundingSphereRadius() { let max2 = 0; const verts = this.vertices; for (let i = 0; i !== verts.length; i++) { const norm2 = verts[i].lengthSquared(); if (norm2 > max2) { max2 = norm2; } } this.boundingSphereRadius = Math.sqrt(max2); } calculateWorldAABB(pos, quat, min, max) { const verts = this.vertices; let minx; let miny; let minz; let maxx; let maxy; let maxz; let tempWorldVertex = new Vec3(); for (let i = 0; i < verts.length; i++) { tempWorldVertex.copy(verts[i]); quat.vmult(tempWorldVertex, tempWorldVertex); pos.vadd(tempWorldVertex, tempWorldVertex); const v = tempWorldVertex; if (minx === void 0 || v.x < minx) { minx = v.x; } if (maxx === void 0 || v.x > maxx) { maxx = v.x; } if (miny === void 0 || v.y < miny) { miny = v.y; } if (maxy === void 0 || v.y > maxy) { maxy = v.y; } if (minz === void 0 || v.z < minz) { minz = v.z; } if (maxz === void 0 || v.z > maxz) { maxz = v.z; } } min.set(minx, miny, minz); max.set(maxx, maxy, maxz); } volume() { return 4 * Math.PI * this.boundingSphereRadius / 3; } getAveragePointLocal(target = new Vec3()) { const verts = this.vertices; for (let i = 0; i < verts.length; i++) { target.vadd(verts[i], target); } target.scale(1 / verts.length, target); return target; } transformAllPoints(offset, quat) { const n = this.vertices.length; const verts = this.vertices; if (quat) { for (let i = 0; i < n; i++) { const v = verts[i]; quat.vmult(v, v); } for (let i = 0; i < this.faceNormals.length; i++) { const v = this.faceNormals[i]; quat.vmult(v, v); } } if (offset) { for (let i = 0; i < n; i++) { const v = verts[i]; v.vadd(offset, v); } } } pointIsInside(p2) { const verts = this.vertices; const faces = this.faces; const normals = this.faceNormals; const pointInside = new Vec3(); this.getAveragePointLocal(pointInside); for (let i = 0; i < this.faces.length; i++) { let n = normals[i]; const v = verts[faces[i][0]]; const vToP = new Vec3(); p2.vsub(v, vToP); const r1 = n.dot(vToP); const vToPointInside = new Vec3(); pointInside.vsub(v, vToPointInside); const r2 = n.dot(vToPointInside); if (r1 < 0 && r2 > 0 || r1 > 0 && r2 < 0) { return false; } } return -1; } static project(shape, axis, pos, quat, result) { const n = shape.vertices.length; const localAxis = project_localAxis; let max = 0; let min = 0; const localOrigin = project_localOrigin; const vs = shape.vertices; localOrigin.setZero(); Transform.vectorToLocalFrame(pos, quat, axis, localAxis); Transform.pointToLocalFrame(pos, quat, localOrigin, localOrigin); const add = localOrigin.dot(localAxis); min = max = vs[0].dot(localAxis); for (let i = 1; i < n; i++) { const val = vs[i].dot(localAxis); if (val > max) { max = val; } if (val < min) { min = val; } } min -= add; max -= add; if (min > max) { const temp = min; min = max; max = temp; } result[0] = max; result[1] = min; } }; var maxminA = []; var maxminB = []; var project_localAxis = new Vec3(); var project_localOrigin = new Vec3(); var Box = class extends Shape2 { constructor(halfExtents) { super({ type: Shape2.types.BOX }); this.halfExtents = void 0; this.convexPolyhedronRepresentation = void 0; this.halfExtents = halfExtents; this.convexPolyhedronRepresentation = null; this.updateConvexPolyhedronRepresentation(); this.updateBoundingSphereRadius(); } updateConvexPolyhedronRepresentation() { const sx = this.halfExtents.x; const sy = this.halfExtents.y; const sz = this.halfExtents.z; const V = Vec3; const vertices = [new V(-sx, -sy, -sz), new V(sx, -sy, -sz), new V(sx, sy, -sz), new V(-sx, sy, -sz), new V(-sx, -sy, sz), new V(sx, -sy, sz), new V(sx, sy, sz), new V(-sx, sy, sz)]; const faces = [ [3, 2, 1, 0], [4, 5, 6, 7], [5, 4, 0, 1], [2, 3, 7, 6], [0, 4, 7, 3], [1, 2, 6, 5] ]; const axes = [new V(0, 0, 1), new V(0, 1, 0), new V(1, 0, 0)]; const h = new ConvexPolyhedron({ vertices, faces, axes }); this.convexPolyhedronRepresentation = h; h.material = this.material; } calculateLocalInertia(mass, target = new Vec3()) { Box.calculateInertia(this.halfExtents, mass, target); return target; } static calculateInertia(halfExtents, mass, target) { const e = halfExtents; target.x = 1 / 12 * mass * (2 * e.y * 2 * e.y + 2 * e.z * 2 * e.z); target.y = 1 / 12 * mass * (2 * e.x * 2 * e.x + 2 * e.z * 2 * e.z); target.z = 1 / 12 * mass * (2 * e.y * 2 * e.y + 2 * e.x * 2 * e.x); } getSideNormals(sixTargetVectors, quat) { const sides = sixTargetVectors; const ex = this.halfExtents; sides[0].set(ex.x, 0, 0); sides[1].set(0, ex.y, 0); sides[2].set(0, 0, ex.z); sides[3].set(-ex.x, 0, 0); sides[4].set(0, -ex.y, 0); sides[5].set(0, 0, -ex.z); if (quat !== void 0) { for (let i = 0; i !== sides.length; i++) { quat.vmult(sides[i], sides[i]); } } return sides; } volume() { return 8 * this.halfExtents.x * this.halfExtents.y * this.halfExtents.z; } updateBoundingSphereRadius() { this.boundingSphereRadius = this.halfExtents.length(); } forEachWorldCorner(pos, quat, callback) { const e = this.halfExtents; const corners = [[e.x, e.y, e.z], [-e.x, e.y, e.z], [-e.x, -e.y, e.z], [-e.x, -e.y, -e.z], [e.x, -e.y, -e.z], [e.x, e.y, -e.z], [-e.x, e.y, -e.z], [e.x, -e.y, e.z]]; for (let i = 0; i < corners.length; i++) { worldCornerTempPos.set(corners[i][0], corners[i][1], corners[i][2]); quat.vmult(worldCornerTempPos, worldCornerTempPos); pos.vadd(worldCornerTempPos, worldCornerTempPos); callback(worldCornerTempPos.x, worldCornerTempPos.y, worldCornerTempPos.z); } } calculateWorldAABB(pos, quat, min, max) { const e = this.halfExtents; worldCornersTemp[0].set(e.x, e.y, e.z); worldCornersTemp[1].set(-e.x, e.y, e.z); worldCornersTemp[2].set(-e.x, -e.y, e.z); worldCornersTemp[3].set(-e.x, -e.y, -e.z); worldCornersTemp[4].set(e.x, -e.y, -e.z); worldCornersTemp[5].set(e.x, e.y, -e.z); worldCornersTemp[6].set(-e.x, e.y, -e.z); worldCornersTemp[7].set(e.x, -e.y, e.z); const wc = worldCornersTemp[0]; quat.vmult(wc, wc); pos.vadd(wc, wc); max.copy(wc); min.copy(wc); for (let i = 1; i < 8; i++) { const wc2 = worldCornersTemp[i]; quat.vmult(wc2, wc2); pos.vadd(wc2, wc2); const x = wc2.x; const y = wc2.y; const z = wc2.z; if (x > max.x) { max.x = x; } if (y > max.y) { max.y = y; } if (z > max.z) { max.z = z; } if (x < min.x) { min.x = x; } if (y < min.y) { min.y = y; } if (z < min.z) { min.z = z; } } } }; var worldCornerTempPos = new Vec3(); var worldCornersTemp = [new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3()]; var BODY_TYPES = { DYNAMIC: 1, STATIC: 2, KINEMATIC: 4 }; var BODY_SLEEP_STATES = { AWAKE: 0, SLEEPY: 1, SLEEPING: 2 }; var Body = class extends EventTarget { constructor(options = {}) { super(); this.id = void 0; this.index = void 0; this.world = void 0; this.preStep = void 0; this.postStep = void 0; this.vlambda = void 0; this.collisionFilterGroup = void 0; this.collisionFilterMask = void 0; this.collisionResponse = void 0; this.position = void 0; this.previousPosition = void 0; this.interpolatedPosition = void 0; this.initPosition = void 0; this.velocity = void 0; this.initVelocity = void 0; this.force = void 0; this.mass = void 0; this.invMass = void 0; this.material = void 0; this.linearDamping = void 0; this.type = void 0; this.allowSleep = void 0; this.sleepState = void 0; this.sleepSpeedLimit = void 0; this.sleepTimeLimit = void 0; this.timeLastSleepy = void 0; this.wakeUpAfterNarrowphase = void 0; this.torque = void 0; this.quaternion = void 0; this.initQuaternion = void 0; this.previousQuaternion = void 0; this.interpolatedQuaternion = void 0; this.angularVelocity = void 0; this.initAngularVelocity = void 0; this.shapes = void 0; this.shapeOffsets = void 0; this.shapeOrientations = void 0; this.inertia = void 0; this.invInertia = void 0; this.invInertiaWorld = void 0; this.invMassSolve = void 0; this.invInertiaSolve = void 0; this.invInertiaWorldSolve = void 0; this.fixedRotation = void 0; this.angularDamping = void 0; this.linearFactor = void 0; this.angularFactor = void 0; this.aabb = void 0; this.aabbNeedsUpdate = void 0; this.boundingRadius = void 0; this.wlambda = void 0; this.isTrigger = void 0; this.id = Body.idCounter++; this.index = -1; this.world = null; this.preStep = null; this.postStep = null; this.vlambda = new Vec3(); this.collisionFilterGroup = typeof options.collisionFilterGroup === "number" ? options.collisionFilterGroup : 1; this.collisionFilterMask = typeof options.collisionFilterMask === "number" ? options.collisionFilterMask : -1; this.collisionResponse = typeof options.collisionResponse === "boolean" ? options.collisionResponse : true; this.position = new Vec3(); this.previousPosition = new Vec3(); this.interpolatedPosition = new Vec3(); this.initPosition = new Vec3(); if (options.position) { this.position.copy(options.position); this.previousPosition.copy(options.position); this.interpolatedPosition.copy(options.position); this.initPosition.copy(options.position); } this.velocity = new Vec3(); if (options.velocity) { this.velocity.copy(options.velocity); } this.initVelocity = new Vec3(); this.force = new Vec3(); const mass = typeof options.mass === "number" ? options.mass : 0; this.mass = mass; this.invMass = mass > 0 ? 1 / mass : 0; this.material = options.material || null; this.linearDamping = typeof options.linearDamping === "number" ? options.linearDamping : 0.01; this.type = mass <= 0 ? Body.STATIC : Body.DYNAMIC; if (typeof options.type === typeof Body.STATIC) { this.type = options.type; } this.allowSleep = typeof options.allowSleep !== "undefined" ? options.allowSleep : true; this.sleepState = Body.AWAKE; this.sleepSpeedLimit = typeof options.sleepSpeedLimit !== "undefined" ? options.sleepSpeedLimit : 0.1; this.sleepTimeLimit = typeof options.sleepTimeLimit !== "undefined" ? options.sleepTimeLimit : 1; this.timeLastSleepy = 0; this.wakeUpAfterNarrowphase = false; this.torque = new Vec3(); this.quaternion = new Quaternion2(); this.initQuaternion = new Quaternion2(); this.previousQuaternion = new Quaternion2(); this.interpolatedQuaternion = new Quaternion2(); if (options.quaternion) { this.quaternion.copy(options.quaternion); this.initQuaternion.copy(options.quaternion); this.previousQuaternion.copy(options.quaternion); this.interpolatedQuaternion.copy(options.quaternion); } this.angularVelocity = new Vec3(); if (options.angularVelocity) { this.angularVelocity.copy(options.angularVelocity); } this.initAngularVelocity = new Vec3(); this.shapes = []; this.shapeOffsets = []; this.shapeOrientations = []; this.inertia = new Vec3(); this.invInertia = new Vec3(); this.invInertiaWorld = new Mat3(); this.invMassSolve = 0; this.invInertiaSolve = new Vec3(); this.invInertiaWorldSolve = new Mat3(); this.fixedRotation = typeof options.fixedRotation !== "undefined" ? options.fixedRotation : false; this.angularDamping = typeof options.angularDamping !== "undefined" ? options.angularDamping : 0.01; this.linearFactor = new Vec3(1, 1, 1); if (options.linearFactor) { this.linearFactor.copy(options.linearFactor); } this.angularFactor = new Vec3(1, 1, 1); if (options.angularFactor) { this.angularFactor.copy(options.angularFactor); } this.aabb = new AABB(); this.aabbNeedsUpdate = true; this.boundingRadius = 0; this.wlambda = new Vec3(); this.isTrigger = Boolean(options.isTrigger); if (options.shape) { this.addShape(options.shape); } this.updateMassProperties(); } wakeUp() { const prevState = this.sleepState; this.sleepState = Body.AWAKE; this.wakeUpAfterNarrowphase = false; if (prevState === Body.SLEEPING) { this.dispatchEvent(Body.wakeupEvent); } } sleep() { this.sleepState = Body.SLEEPING; this.velocity.set(0, 0, 0); this.angularVelocity.set(0, 0, 0); this.wakeUpAfterNarrowphase = false; } sleepTick(time) { if (this.allowSleep) { const sleepState = this.sleepState; const speedSquared = this.velocity.lengthSquared() + this.angularVelocity.lengthSquared(); const speedLimitSquared = this.sleepSpeedLimit ** 2; if (sleepState === Body.AWAKE && speedSquared < speedLimitSquared) { this.sleepState = Body.SLEEPY; this.timeLastSleepy = time; this.dispatchEvent(Body.sleepyEvent); } else if (sleepState === Body.SLEEPY && speedSquared > speedLimitSquared) { this.wakeUp(); } else if (sleepState === Body.SLEEPY && time - this.timeLastSleepy > this.sleepTimeLimit) { this.sleep(); this.dispatchEvent(Body.sleepEvent); } } } updateSolveMassProperties() { if (this.sleepState === Body.SLEEPING || this.type === Body.KINEMATIC) { this.invMassSolve = 0; this.invInertiaSolve.setZero(); this.invInertiaWorldSolve.setZero(); } else { this.invMassSolve = this.invMass; this.invInertiaSolve.copy(this.invInertia); this.invInertiaWorldSolve.copy(this.invInertiaWorld); } } pointToLocalFrame(worldPoint, result = new Vec3()) { worldPoint.vsub(this.position, result); this.quaternion.conjugate().vmult(result, result); return result; } vectorToLocalFrame(worldVector, result = new Vec3()) { this.quaternion.conjugate().vmult(worldVector, result); return result; } pointToWorldFrame(localPoint, result = new Vec3()) { this.quaternion.vmult(localPoint, result); result.vadd(this.position, result); return result; } vectorToWorldFrame(localVector, result = new Vec3()) { this.quaternion.vmult(localVector, result); return result; } addShape(shape, _offset2, _orientation) { const offset = new Vec3(); const orientation = new Quaternion2(); if (_offset2) { offset.copy(_offset2); } if (_orientation) { orientation.copy(_orientation); } this.shapes.push(shape); this.shapeOffsets.push(offset); this.shapeOrientations.push(orientation); this.updateMassProperties(); this.updateBoundingRadius(); this.aabbNeedsUpdate = true; shape.body = this; return this; } removeShape(shape) { const index = this.shapes.indexOf(shape); if (index === -1) { console.warn("Shape does not belong to the body"); return this; } this.shapes.splice(index, 1); this.shapeOffsets.splice(index, 1); this.shapeOrientations.splice(index, 1); this.updateMassProperties(); this.updateBoundingRadius(); this.aabbNeedsUpdate = true; shape.body = null; return this; } updateBoundingRadius() { const shapes = this.shapes; const shapeOffsets = this.shapeOffsets; const N = shapes.length; let radius = 0; for (let i = 0; i !== N; i++) { const shape = shapes[i]; shape.updateBoundingSphereRadius(); const offset = shapeOffsets[i].length(); const r = shape.boundingSphereRadius; if (offset + r > radius) { radius = offset + r; } } this.boundingRadius = radius; } updateAABB() { const shapes = this.shapes; const shapeOffsets = this.shapeOffsets; const shapeOrientations = this.shapeOrientations; const N = shapes.length; const offset = tmpVec; const orientation = tmpQuat; const bodyQuat = this.quaternion; const aabb = this.aabb; const shapeAABB = updateAABB_shapeAABB; for (let i = 0; i !== N; i++) { const shape = shapes[i]; bodyQuat.vmult(shapeOffsets[i], offset); offset.vadd(this.position, offset); bodyQuat.mult(shapeOrientations[i], orientation); shape.calculateWorldAABB(offset, orientation, shapeAABB.lowerBound, shapeAABB.upperBound); if (i === 0) { aabb.copy(shapeAABB); } else { aabb.extend(shapeAABB); } } this.aabbNeedsUpdate = false; } updateInertiaWorld(force) { const I = this.invInertia; if (I.x === I.y && I.y === I.z && !force) ; else { const m1 = uiw_m1; const m2 = uiw_m2; m1.setRotationFromQuaternion(this.quaternion); m1.transpose(m2); m1.scale(I, m1); m1.mmult(m2, this.invInertiaWorld); } } applyForce(force, relativePoint = new Vec3()) { if (this.type !== Body.DYNAMIC) { return; } if (this.sleepState === Body.SLEEPING) { this.wakeUp(); } const rotForce = Body_applyForce_rotForce; relativePoint.cross(force, rotForce); this.force.vadd(force, this.force); this.torque.vadd(rotForce, this.torque); } applyLocalForce(localForce, localPoint = new Vec3()) { if (this.type !== Body.DYNAMIC) { return; } const worldForce = Body_applyLocalForce_worldForce; const relativePointWorld = Body_applyLocalForce_relativePointWorld; this.vectorToWorldFrame(localForce, worldForce); this.vectorToWorldFrame(localPoint, relativePointWorld); this.applyForce(worldForce, relativePointWorld); } applyTorque(torque2) { if (this.type !== Body.DYNAMIC) { return; } if (this.sleepState === Body.SLEEPING) { this.wakeUp(); } this.torque.vadd(torque2, this.torque); } applyImpulse(impulse, relativePoint = new Vec3()) { if (this.type !== Body.DYNAMIC) { return; } if (this.sleepState === Body.SLEEPING) { this.wakeUp(); } const r = relativePoint; const velo = Body_applyImpulse_velo; velo.copy(impulse); velo.scale(this.invMass, velo); this.velocity.vadd(velo, this.velocity); const rotVelo = Body_applyImpulse_rotVelo; r.cross(impulse, rotVelo); this.invInertiaWorld.vmult(rotVelo, rotVelo); this.angularVelocity.vadd(rotVelo, this.angularVelocity); } applyLocalImpulse(localImpulse, localPoint = new Vec3()) { if (this.type !== Body.DYNAMIC) { return; } const worldImpulse = Body_applyLocalImpulse_worldImpulse; const relativePointWorld = Body_applyLocalImpulse_relativePoint; this.vectorToWorldFrame(localImpulse, worldImpulse); this.vectorToWorldFrame(localPoint, relativePointWorld); this.applyImpulse(worldImpulse, relativePointWorld); } updateMassProperties() { const halfExtents = Body_updateMassProperties_halfExtents; this.invMass = this.mass > 0 ? 1 / this.mass : 0; const I = this.inertia; const fixed = this.fixedRotation; this.updateAABB(); halfExtents.set((this.aabb.upperBound.x - this.aabb.lowerBound.x) / 2, (this.aabb.upperBound.y - this.aabb.lowerBound.y) / 2, (this.aabb.upperBound.z - this.aabb.lowerBound.z) / 2); Box.calculateInertia(halfExtents, this.mass, I); this.invInertia.set(I.x > 0 && !fixed ? 1 / I.x : 0, I.y > 0 && !fixed ? 1 / I.y : 0, I.z > 0 && !fixed ? 1 / I.z : 0); this.updateInertiaWorld(true); } getVelocityAtWorldPoint(worldPoint, result) { const r = new Vec3(); worldPoint.vsub(this.position, r); this.angularVelocity.cross(r, result); this.velocity.vadd(result, result); return result; } integrate(dt, quatNormalize, quatNormalizeFast) { this.previousPosition.copy(this.position); this.previousQuaternion.copy(this.quaternion); if (!(this.type === Body.DYNAMIC || this.type === Body.KINEMATIC) || this.sleepState === Body.SLEEPING) { return; } const velo = this.velocity; const angularVelo = this.angularVelocity; const pos = this.position; const force = this.force; const torque2 = this.torque; const quat = this.quaternion; const invMass = this.invMass; const invInertia = this.invInertiaWorld; const linearFactor = this.linearFactor; const iMdt = invMass * dt; velo.x += force.x * iMdt * linearFactor.x; velo.y += force.y * iMdt * linearFactor.y; velo.z += force.z * iMdt * linearFactor.z; const e = invInertia.elements; const angularFactor = this.angularFactor; const tx = torque2.x * angularFactor.x; const ty = torque2.y * angularFactor.y; const tz = torque2.z * angularFactor.z; angularVelo.x += dt * (e[0] * tx + e[1] * ty + e[2] * tz); angularVelo.y += dt * (e[3] * tx + e[4] * ty + e[5] * tz); angularVelo.z += dt * (e[6] * tx + e[7] * ty + e[8] * tz); pos.x += velo.x * dt; pos.y += velo.y * dt; pos.z += velo.z * dt; quat.integrate(this.angularVelocity, dt, this.angularFactor, quat); if (quatNormalize) { if (quatNormalizeFast) { quat.normalizeFast(); } else { quat.normalize(); } } this.aabbNeedsUpdate = true; this.updateInertiaWorld(); } }; Body.idCounter = 0; Body.COLLIDE_EVENT_NAME = "collide"; Body.DYNAMIC = BODY_TYPES.DYNAMIC; Body.STATIC = BODY_TYPES.STATIC; Body.KINEMATIC = BODY_TYPES.KINEMATIC; Body.AWAKE = BODY_SLEEP_STATES.AWAKE; Body.SLEEPY = BODY_SLEEP_STATES.SLEEPY; Body.SLEEPING = BODY_SLEEP_STATES.SLEEPING; Body.wakeupEvent = { type: "wakeup" }; Body.sleepyEvent = { type: "sleepy" }; Body.sleepEvent = { type: "sleep" }; var tmpVec = new Vec3(); var tmpQuat = new Quaternion2(); var updateAABB_shapeAABB = new AABB(); var uiw_m1 = new Mat3(); var uiw_m2 = new Mat3(); var Body_applyForce_rotForce = new Vec3(); var Body_applyLocalForce_worldForce = new Vec3(); var Body_applyLocalForce_relativePointWorld = new Vec3(); var Body_applyImpulse_velo = new Vec3(); var Body_applyImpulse_rotVelo = new Vec3(); var Body_applyLocalImpulse_worldImpulse = new Vec3(); var Body_applyLocalImpulse_relativePoint = new Vec3(); var Body_updateMassProperties_halfExtents = new Vec3(); var Broadphase = class { constructor() { this.world = void 0; this.useBoundingBoxes = void 0; this.dirty = void 0; this.world = null; this.useBoundingBoxes = false; this.dirty = true; } collisionPairs(world, p1, p2) { throw new Error("collisionPairs not implemented for this BroadPhase class!"); } needBroadphaseCollision(bodyA, bodyB) { if ((bodyA.collisionFilterGroup & bodyB.collisionFilterMask) === 0 || (bodyB.collisionFilterGroup & bodyA.collisionFilterMask) === 0) { return false; } if (((bodyA.type & Body.STATIC) !== 0 || bodyA.sleepState === Body.SLEEPING) && ((bodyB.type & Body.STATIC) !== 0 || bodyB.sleepState === Body.SLEEPING)) { return false; } return true; } intersectionTest(bodyA, bodyB, pairs1, pairs2) { if (this.useBoundingBoxes) { this.doBoundingBoxBroadphase(bodyA, bodyB, pairs1, pairs2); } else { this.doBoundingSphereBroadphase(bodyA, bodyB, pairs1, pairs2); } } doBoundingSphereBroadphase(bodyA, bodyB, pairs1, pairs2) { const r = Broadphase_collisionPairs_r; bodyB.position.vsub(bodyA.position, r); const boundingRadiusSum2 = (bodyA.boundingRadius + bodyB.boundingRadius) ** 2; const norm2 = r.lengthSquared(); if (norm2 < boundingRadiusSum2) { pairs1.push(bodyA); pairs2.push(bodyB); } } doBoundingBoxBroadphase(bodyA, bodyB, pairs1, pairs2) { if (bodyA.aabbNeedsUpdate) { bodyA.updateAABB(); } if (bodyB.aabbNeedsUpdate) { bodyB.updateAABB(); } if (bodyA.aabb.overlaps(bodyB.aabb)) { pairs1.push(bodyA); pairs2.push(bodyB); } } makePairsUnique(pairs1, pairs2) { const t = Broadphase_makePairsUnique_temp; const p1 = Broadphase_makePairsUnique_p1; const p2 = Broadphase_makePairsUnique_p2; const N = pairs1.length; for (let i = 0; i !== N; i++) { p1[i] = pairs1[i]; p2[i] = pairs2[i]; } pairs1.length = 0; pairs2.length = 0; for (let i = 0; i !== N; i++) { const id1 = p1[i].id; const id2 = p2[i].id; const key = id1 < id2 ? id1 + "," + id2 : id2 + "," + id1; t[key] = i; t.keys.push(key); } for (let i = 0; i !== t.keys.length; i++) { const key = t.keys.pop(); const pairIndex = t[key]; pairs1.push(p1[pairIndex]); pairs2.push(p2[pairIndex]); delete t[key]; } } setWorld(world) { } static boundingSphereCheck(bodyA, bodyB) { const dist = new Vec3(); bodyA.position.vsub(bodyB.position, dist); const sa = bodyA.shapes[0]; const sb = bodyB.shapes[0]; return Math.pow(sa.boundingSphereRadius + sb.boundingSphereRadius, 2) > dist.lengthSquared(); } aabbQuery(world, aabb, result) { console.warn(".aabbQuery is not implemented in this Broadphase subclass."); return []; } }; var Broadphase_collisionPairs_r = new Vec3(); var Broadphase_makePairsUnique_temp = { keys: [] }; var Broadphase_makePairsUnique_p1 = []; var Broadphase_makePairsUnique_p2 = []; var GridBroadphase_collisionPairs_d = new Vec3(); var NaiveBroadphase = class extends Broadphase { constructor() { super(); } collisionPairs(world, pairs1, pairs2) { const bodies = world.bodies; const n = bodies.length; let bi; let bj; for (let i = 0; i !== n; i++) { for (let j = 0; j !== i; j++) { bi = bodies[i]; bj = bodies[j]; if (!this.needBroadphaseCollision(bi, bj)) { continue; } this.intersectionTest(bi, bj, pairs1, pairs2); } } } aabbQuery(world, aabb, result = []) { for (let i = 0; i < world.bodies.length; i++) { const b2 = world.bodies[i]; if (b2.aabbNeedsUpdate) { b2.updateAABB(); } if (b2.aabb.overlaps(aabb)) { result.push(b2); } } return result; } }; var RaycastResult = class { constructor() { this.rayFromWorld = void 0; this.rayToWorld = void 0; this.hitNormalWorld = void 0; this.hitPointWorld = void 0; this.hasHit = void 0; this.shape = void 0; this.body = void 0; this.hitFaceIndex = void 0; this.distance = void 0; this.shouldStop = void 0; this.rayFromWorld = new Vec3(); this.rayToWorld = new Vec3(); this.hitNormalWorld = new Vec3(); this.hitPointWorld = new Vec3(); this.hasHit = false; this.shape = null; this.body = null; this.hitFaceIndex = -1; this.distance = -1; this.shouldStop = false; } reset() { this.rayFromWorld.setZero(); this.rayToWorld.setZero(); this.hitNormalWorld.setZero(); this.hitPointWorld.setZero(); this.hasHit = false; this.shape = null; this.body = null; this.hitFaceIndex = -1; this.distance = -1; this.shouldStop = false; } abort() { this.shouldStop = true; } set(rayFromWorld, rayToWorld, hitNormalWorld, hitPointWorld, shape, body, distance) { this.rayFromWorld.copy(rayFromWorld); this.rayToWorld.copy(rayToWorld); this.hitNormalWorld.copy(hitNormalWorld); this.hitPointWorld.copy(hitPointWorld); this.shape = shape; this.body = body; this.distance = distance; } }; var _Shape$types$SPHERE; var _Shape$types$PLANE; var _Shape$types$BOX; var _Shape$types$CYLINDER; var _Shape$types$CONVEXPO; var _Shape$types$HEIGHTFI; var _Shape$types$TRIMESH; var RAY_MODES = { CLOSEST: 1, ANY: 2, ALL: 4 }; _Shape$types$SPHERE = Shape2.types.SPHERE; _Shape$types$PLANE = Shape2.types.PLANE; _Shape$types$BOX = Shape2.types.BOX; _Shape$types$CYLINDER = Shape2.types.CYLINDER; _Shape$types$CONVEXPO = Shape2.types.CONVEXPOLYHEDRON; _Shape$types$HEIGHTFI = Shape2.types.HEIGHTFIELD; _Shape$types$TRIMESH = Shape2.types.TRIMESH; var Ray2 = class { get [_Shape$types$SPHERE]() { return this._intersectSphere; } get [_Shape$types$PLANE]() { return this._intersectPlane; } get [_Shape$types$BOX]() { return this._intersectBox; } get [_Shape$types$CYLINDER]() { return this._intersectConvex; } get [_Shape$types$CONVEXPO]() { return this._intersectConvex; } get [_Shape$types$HEIGHTFI]() { return this._intersectHeightfield; } get [_Shape$types$TRIMESH]() { return this._intersectTrimesh; } constructor(from = new Vec3(), to = new Vec3()) { this.from = void 0; this.to = void 0; this.direction = void 0; this.precision = void 0; this.checkCollisionResponse = void 0; this.skipBackfaces = void 0; this.collisionFilterMask = void 0; this.collisionFilterGroup = void 0; this.mode = void 0; this.result = void 0; this.hasHit = void 0; this.callback = void 0; this.from = from.clone(); this.to = to.clone(); this.direction = new Vec3(); this.precision = 1e-4; this.checkCollisionResponse = true; this.skipBackfaces = false; this.collisionFilterMask = -1; this.collisionFilterGroup = -1; this.mode = Ray2.ANY; this.result = new RaycastResult(); this.hasHit = false; this.callback = (result) => { }; } intersectWorld(world, options) { this.mode = options.mode || Ray2.ANY; this.result = options.result || new RaycastResult(); this.skipBackfaces = !!options.skipBackfaces; this.collisionFilterMask = typeof options.collisionFilterMask !== "undefined" ? options.collisionFilterMask : -1; this.collisionFilterGroup = typeof options.collisionFilterGroup !== "undefined" ? options.collisionFilterGroup : -1; this.checkCollisionResponse = typeof options.checkCollisionResponse !== "undefined" ? options.checkCollisionResponse : true; if (options.from) { this.from.copy(options.from); } if (options.to) { this.to.copy(options.to); } this.callback = options.callback || (() => { }); this.hasHit = false; this.result.reset(); this.updateDirection(); this.getAABB(tmpAABB$1); tmpArray.length = 0; world.broadphase.aabbQuery(world, tmpAABB$1, tmpArray); this.intersectBodies(tmpArray); return this.hasHit; } intersectBody(body, result) { if (result) { this.result = result; this.updateDirection(); } const checkCollisionResponse = this.checkCollisionResponse; if (checkCollisionResponse && !body.collisionResponse) { return; } if ((this.collisionFilterGroup & body.collisionFilterMask) === 0 || (body.collisionFilterGroup & this.collisionFilterMask) === 0) { return; } const xi = intersectBody_xi; const qi = intersectBody_qi; for (let i = 0, N = body.shapes.length; i < N; i++) { const shape = body.shapes[i]; if (checkCollisionResponse && !shape.collisionResponse) { continue; } body.quaternion.mult(body.shapeOrientations[i], qi); body.quaternion.vmult(body.shapeOffsets[i], xi); xi.vadd(body.position, xi); this.intersectShape(shape, qi, xi, body); if (this.result.shouldStop) { break; } } } intersectBodies(bodies, result) { if (result) { this.result = result; this.updateDirection(); } for (let i = 0, l = bodies.length; !this.result.shouldStop && i < l; i++) { this.intersectBody(bodies[i]); } } updateDirection() { this.to.vsub(this.from, this.direction); this.direction.normalize(); } intersectShape(shape, quat, position, body) { const from = this.from; const distance = distanceFromIntersection(from, this.direction, position); if (distance > shape.boundingSphereRadius) { return; } const intersectMethod = this[shape.type]; if (intersectMethod) { intersectMethod.call(this, shape, quat, position, body, shape); } } _intersectBox(box, quat, position, body, reportedShape) { return this._intersectConvex(box.convexPolyhedronRepresentation, quat, position, body, reportedShape); } _intersectPlane(shape, quat, position, body, reportedShape) { const from = this.from; const to = this.to; const direction = this.direction; const worldNormal = new Vec3(0, 0, 1); quat.vmult(worldNormal, worldNormal); const len = new Vec3(); from.vsub(position, len); const planeToFrom = len.dot(worldNormal); to.vsub(position, len); const planeToTo = len.dot(worldNormal); if (planeToFrom * planeToTo > 0) { return; } if (from.distanceTo(to) < planeToFrom) { return; } const n_dot_dir = worldNormal.dot(direction); if (Math.abs(n_dot_dir) < this.precision) { return; } const planePointToFrom = new Vec3(); const dir_scaled_with_t = new Vec3(); const hitPointWorld = new Vec3(); from.vsub(position, planePointToFrom); const t = -worldNormal.dot(planePointToFrom) / n_dot_dir; direction.scale(t, dir_scaled_with_t); from.vadd(dir_scaled_with_t, hitPointWorld); this.reportIntersection(worldNormal, hitPointWorld, reportedShape, body, -1); } getAABB(aabb) { const { lowerBound, upperBound } = aabb; const to = this.to; const from = this.from; lowerBound.x = Math.min(to.x, from.x); lowerBound.y = Math.min(to.y, from.y); lowerBound.z = Math.min(to.z, from.z); upperBound.x = Math.max(to.x, from.x); upperBound.y = Math.max(to.y, from.y); upperBound.z = Math.max(to.z, from.z); } _intersectHeightfield(shape, quat, position, body, reportedShape) { shape.data; shape.elementSize; const localRay = intersectHeightfield_localRay; localRay.from.copy(this.from); localRay.to.copy(this.to); Transform.pointToLocalFrame(position, quat, localRay.from, localRay.from); Transform.pointToLocalFrame(position, quat, localRay.to, localRay.to); localRay.updateDirection(); const index = intersectHeightfield_index; let iMinX; let iMinY; let iMaxX; let iMaxY; iMinX = iMinY = 0; iMaxX = iMaxY = shape.data.length - 1; const aabb = new AABB(); localRay.getAABB(aabb); shape.getIndexOfPosition(aabb.lowerBound.x, aabb.lowerBound.y, index, true); iMinX = Math.max(iMinX, index[0]); iMinY = Math.max(iMinY, index[1]); shape.getIndexOfPosition(aabb.upperBound.x, aabb.upperBound.y, index, true); iMaxX = Math.min(iMaxX, index[0] + 1); iMaxY = Math.min(iMaxY, index[1] + 1); for (let i = iMinX; i < iMaxX; i++) { for (let j = iMinY; j < iMaxY; j++) { if (this.result.shouldStop) { return; } shape.getAabbAtIndex(i, j, aabb); if (!aabb.overlapsRay(localRay)) { continue; } shape.getConvexTrianglePillar(i, j, false); Transform.pointToWorldFrame(position, quat, shape.pillarOffset, worldPillarOffset); this._intersectConvex(shape.pillarConvex, quat, worldPillarOffset, body, reportedShape, intersectConvexOptions); if (this.result.shouldStop) { return; } shape.getConvexTrianglePillar(i, j, true); Transform.pointToWorldFrame(position, quat, shape.pillarOffset, worldPillarOffset); this._intersectConvex(shape.pillarConvex, quat, worldPillarOffset, body, reportedShape, intersectConvexOptions); } } } _intersectSphere(sphere, quat, position, body, reportedShape) { const from = this.from; const to = this.to; const r = sphere.radius; const a2 = (to.x - from.x) ** 2 + (to.y - from.y) ** 2 + (to.z - from.z) ** 2; const b2 = 2 * ((to.x - from.x) * (from.x - position.x) + (to.y - from.y) * (from.y - position.y) + (to.z - from.z) * (from.z - position.z)); const c2 = (from.x - position.x) ** 2 + (from.y - position.y) ** 2 + (from.z - position.z) ** 2 - r ** 2; const delta = b2 ** 2 - 4 * a2 * c2; const intersectionPoint = Ray_intersectSphere_intersectionPoint; const normal = Ray_intersectSphere_normal; if (delta < 0) { return; } else if (delta === 0) { from.lerp(to, delta, intersectionPoint); intersectionPoint.vsub(position, normal); normal.normalize(); this.reportIntersection(normal, intersectionPoint, reportedShape, body, -1); } else { const d1 = (-b2 - Math.sqrt(delta)) / (2 * a2); const d2 = (-b2 + Math.sqrt(delta)) / (2 * a2); if (d1 >= 0 && d1 <= 1) { from.lerp(to, d1, intersectionPoint); intersectionPoint.vsub(position, normal); normal.normalize(); this.reportIntersection(normal, intersectionPoint, reportedShape, body, -1); } if (this.result.shouldStop) { return; } if (d2 >= 0 && d2 <= 1) { from.lerp(to, d2, intersectionPoint); intersectionPoint.vsub(position, normal); normal.normalize(); this.reportIntersection(normal, intersectionPoint, reportedShape, body, -1); } } } _intersectConvex(shape, quat, position, body, reportedShape, options) { const normal = intersectConvex_normal; const vector = intersectConvex_vector; const faceList = options && options.faceList || null; const faces = shape.faces; const vertices = shape.vertices; const normals = shape.faceNormals; const direction = this.direction; const from = this.from; const to = this.to; const fromToDistance = from.distanceTo(to); const Nfaces = faceList ? faceList.length : faces.length; const result = this.result; for (let j = 0; !result.shouldStop && j < Nfaces; j++) { const fi = faceList ? faceList[j] : j; const face = faces[fi]; const faceNormal = normals[fi]; const q = quat; const x = position; vector.copy(vertices[face[0]]); q.vmult(vector, vector); vector.vadd(x, vector); vector.vsub(from, vector); q.vmult(faceNormal, normal); const dot = direction.dot(normal); if (Math.abs(dot) < this.precision) { continue; } const scalar = normal.dot(vector) / dot; if (scalar < 0) { continue; } direction.scale(scalar, intersectPoint); intersectPoint.vadd(from, intersectPoint); a.copy(vertices[face[0]]); q.vmult(a, a); x.vadd(a, a); for (let i = 1; !result.shouldStop && i < face.length - 1; i++) { b.copy(vertices[face[i]]); c.copy(vertices[face[i + 1]]); q.vmult(b, b); q.vmult(c, c); x.vadd(b, b); x.vadd(c, c); const distance = intersectPoint.distanceTo(from); if (!(Ray2.pointInTriangle(intersectPoint, a, b, c) || Ray2.pointInTriangle(intersectPoint, b, a, c)) || distance > fromToDistance) { continue; } this.reportIntersection(normal, intersectPoint, reportedShape, body, fi); } } } _intersectTrimesh(mesh, quat, position, body, reportedShape, options) { const normal = intersectTrimesh_normal; const triangles = intersectTrimesh_triangles; const treeTransform = intersectTrimesh_treeTransform; const vector = intersectConvex_vector; const localDirection = intersectTrimesh_localDirection; const localFrom = intersectTrimesh_localFrom; const localTo = intersectTrimesh_localTo; const worldIntersectPoint = intersectTrimesh_worldIntersectPoint; const worldNormal = intersectTrimesh_worldNormal; const indices = mesh.indices; mesh.vertices; const from = this.from; const to = this.to; const direction = this.direction; treeTransform.position.copy(position); treeTransform.quaternion.copy(quat); Transform.vectorToLocalFrame(position, quat, direction, localDirection); Transform.pointToLocalFrame(position, quat, from, localFrom); Transform.pointToLocalFrame(position, quat, to, localTo); localTo.x *= mesh.scale.x; localTo.y *= mesh.scale.y; localTo.z *= mesh.scale.z; localFrom.x *= mesh.scale.x; localFrom.y *= mesh.scale.y; localFrom.z *= mesh.scale.z; localTo.vsub(localFrom, localDirection); localDirection.normalize(); const fromToDistanceSquared = localFrom.distanceSquared(localTo); mesh.tree.rayQuery(this, treeTransform, triangles); for (let i = 0, N = triangles.length; !this.result.shouldStop && i !== N; i++) { const trianglesIndex = triangles[i]; mesh.getNormal(trianglesIndex, normal); mesh.getVertex(indices[trianglesIndex * 3], a); a.vsub(localFrom, vector); const dot = localDirection.dot(normal); const scalar = normal.dot(vector) / dot; if (scalar < 0) { continue; } localDirection.scale(scalar, intersectPoint); intersectPoint.vadd(localFrom, intersectPoint); mesh.getVertex(indices[trianglesIndex * 3 + 1], b); mesh.getVertex(indices[trianglesIndex * 3 + 2], c); const squaredDistance = intersectPoint.distanceSquared(localFrom); if (!(Ray2.pointInTriangle(intersectPoint, b, a, c) || Ray2.pointInTriangle(intersectPoint, a, b, c)) || squaredDistance > fromToDistanceSquared) { continue; } Transform.vectorToWorldFrame(quat, normal, worldNormal); Transform.pointToWorldFrame(position, quat, intersectPoint, worldIntersectPoint); this.reportIntersection(worldNormal, worldIntersectPoint, reportedShape, body, trianglesIndex); } triangles.length = 0; } reportIntersection(normal, hitPointWorld, shape, body, hitFaceIndex) { const from = this.from; const to = this.to; const distance = from.distanceTo(hitPointWorld); const result = this.result; if (this.skipBackfaces && normal.dot(this.direction) > 0) { return; } result.hitFaceIndex = typeof hitFaceIndex !== "undefined" ? hitFaceIndex : -1; switch (this.mode) { case Ray2.ALL: this.hasHit = true; result.set(from, to, normal, hitPointWorld, shape, body, distance); result.hasHit = true; this.callback(result); break; case Ray2.CLOSEST: if (distance < result.distance || !result.hasHit) { this.hasHit = true; result.hasHit = true; result.set(from, to, normal, hitPointWorld, shape, body, distance); } break; case Ray2.ANY: this.hasHit = true; result.hasHit = true; result.set(from, to, normal, hitPointWorld, shape, body, distance); result.shouldStop = true; break; } } static pointInTriangle(p2, a2, b2, c2) { c2.vsub(a2, v0); b2.vsub(a2, v1); p2.vsub(a2, v2); const dot00 = v0.dot(v0); const dot01 = v0.dot(v1); const dot02 = v0.dot(v2); const dot11 = v1.dot(v1); const dot12 = v1.dot(v2); let u; let v; return (u = dot11 * dot02 - dot01 * dot12) >= 0 && (v = dot00 * dot12 - dot01 * dot02) >= 0 && u + v < dot00 * dot11 - dot01 * dot01; } }; Ray2.CLOSEST = RAY_MODES.CLOSEST; Ray2.ANY = RAY_MODES.ANY; Ray2.ALL = RAY_MODES.ALL; var tmpAABB$1 = new AABB(); var tmpArray = []; var v1 = new Vec3(); var v2 = new Vec3(); var intersectBody_xi = new Vec3(); var intersectBody_qi = new Quaternion2(); var intersectPoint = new Vec3(); var a = new Vec3(); var b = new Vec3(); var c = new Vec3(); var intersectConvexOptions = { faceList: [0] }; var worldPillarOffset = new Vec3(); var intersectHeightfield_localRay = new Ray2(); var intersectHeightfield_index = []; var Ray_intersectSphere_intersectionPoint = new Vec3(); var Ray_intersectSphere_normal = new Vec3(); var intersectConvex_normal = new Vec3(); var intersectConvex_vector = new Vec3(); var intersectTrimesh_normal = new Vec3(); var intersectTrimesh_localDirection = new Vec3(); var intersectTrimesh_localFrom = new Vec3(); var intersectTrimesh_localTo = new Vec3(); var intersectTrimesh_worldNormal = new Vec3(); var intersectTrimesh_worldIntersectPoint = new Vec3(); new AABB(); var intersectTrimesh_triangles = []; var intersectTrimesh_treeTransform = new Transform(); var v0 = new Vec3(); var intersect = new Vec3(); function distanceFromIntersection(from, direction, position) { position.vsub(from, v0); const dot = v0.dot(direction); direction.scale(dot, intersect); intersect.vadd(from, intersect); const distance = position.distanceTo(intersect); return distance; } var Utils = class { static defaults(options = {}, defaults) { for (let key in defaults) { if (!(key in options)) { options[key] = defaults[key]; } } return options; } }; var Constraint = class { constructor(bodyA, bodyB, options = {}) { this.equations = void 0; this.bodyA = void 0; this.bodyB = void 0; this.id = void 0; this.collideConnected = void 0; options = Utils.defaults(options, { collideConnected: true, wakeUpBodies: true }); this.equations = []; this.bodyA = bodyA; this.bodyB = bodyB; this.id = Constraint.idCounter++; this.collideConnected = options.collideConnected; if (options.wakeUpBodies) { if (bodyA) { bodyA.wakeUp(); } if (bodyB) { bodyB.wakeUp(); } } } update() { throw new Error("method update() not implmemented in this Constraint subclass!"); } enable() { const eqs = this.equations; for (let i = 0; i < eqs.length; i++) { eqs[i].enabled = true; } } disable() { const eqs = this.equations; for (let i = 0; i < eqs.length; i++) { eqs[i].enabled = false; } } }; Constraint.idCounter = 0; var JacobianElement = class { constructor() { this.spatial = void 0; this.rotational = void 0; this.spatial = new Vec3(); this.rotational = new Vec3(); } multiplyElement(element) { return element.spatial.dot(this.spatial) + element.rotational.dot(this.rotational); } multiplyVectors(spatial, rotational) { return spatial.dot(this.spatial) + rotational.dot(this.rotational); } }; var Equation = class { constructor(bi, bj, minForce = -1e6, maxForce = 1e6) { this.id = void 0; this.minForce = void 0; this.maxForce = void 0; this.bi = void 0; this.bj = void 0; this.si = void 0; this.sj = void 0; this.a = void 0; this.b = void 0; this.eps = void 0; this.jacobianElementA = void 0; this.jacobianElementB = void 0; this.enabled = void 0; this.multiplier = void 0; this.id = Equation.idCounter++; this.minForce = minForce; this.maxForce = maxForce; this.bi = bi; this.bj = bj; this.a = 0; this.b = 0; this.eps = 0; this.jacobianElementA = new JacobianElement(); this.jacobianElementB = new JacobianElement(); this.enabled = true; this.multiplier = 0; this.setSpookParams(1e7, 4, 1 / 60); } setSpookParams(stiffness, relaxation, timeStep) { const d = relaxation; const k = stiffness; const h = timeStep; this.a = 4 / (h * (1 + 4 * d)); this.b = 4 * d / (1 + 4 * d); this.eps = 4 / (h * h * k * (1 + 4 * d)); } computeB(a2, b2, h) { const GW = this.computeGW(); const Gq = this.computeGq(); const GiMf = this.computeGiMf(); return -Gq * a2 - GW * b2 - GiMf * h; } computeGq() { const GA = this.jacobianElementA; const GB = this.jacobianElementB; const bi = this.bi; const bj = this.bj; const xi = bi.position; const xj = bj.position; return GA.spatial.dot(xi) + GB.spatial.dot(xj); } computeGW() { const GA = this.jacobianElementA; const GB = this.jacobianElementB; const bi = this.bi; const bj = this.bj; const vi = bi.velocity; const vj = bj.velocity; const wi = bi.angularVelocity; const wj = bj.angularVelocity; return GA.multiplyVectors(vi, wi) + GB.multiplyVectors(vj, wj); } computeGWlambda() { const GA = this.jacobianElementA; const GB = this.jacobianElementB; const bi = this.bi; const bj = this.bj; const vi = bi.vlambda; const vj = bj.vlambda; const wi = bi.wlambda; const wj = bj.wlambda; return GA.multiplyVectors(vi, wi) + GB.multiplyVectors(vj, wj); } computeGiMf() { const GA = this.jacobianElementA; const GB = this.jacobianElementB; const bi = this.bi; const bj = this.bj; const fi = bi.force; const ti = bi.torque; const fj = bj.force; const tj = bj.torque; const invMassi = bi.invMassSolve; const invMassj = bj.invMassSolve; fi.scale(invMassi, iMfi); fj.scale(invMassj, iMfj); bi.invInertiaWorldSolve.vmult(ti, invIi_vmult_taui); bj.invInertiaWorldSolve.vmult(tj, invIj_vmult_tauj); return GA.multiplyVectors(iMfi, invIi_vmult_taui) + GB.multiplyVectors(iMfj, invIj_vmult_tauj); } computeGiMGt() { const GA = this.jacobianElementA; const GB = this.jacobianElementB; const bi = this.bi; const bj = this.bj; const invMassi = bi.invMassSolve; const invMassj = bj.invMassSolve; const invIi = bi.invInertiaWorldSolve; const invIj = bj.invInertiaWorldSolve; let result = invMassi + invMassj; invIi.vmult(GA.rotational, tmp2); result += tmp2.dot(GA.rotational); invIj.vmult(GB.rotational, tmp2); result += tmp2.dot(GB.rotational); return result; } addToWlambda(deltalambda) { const GA = this.jacobianElementA; const GB = this.jacobianElementB; const bi = this.bi; const bj = this.bj; const temp = addToWlambda_temp; bi.vlambda.addScaledVector(bi.invMassSolve * deltalambda, GA.spatial, bi.vlambda); bj.vlambda.addScaledVector(bj.invMassSolve * deltalambda, GB.spatial, bj.vlambda); bi.invInertiaWorldSolve.vmult(GA.rotational, temp); bi.wlambda.addScaledVector(deltalambda, temp, bi.wlambda); bj.invInertiaWorldSolve.vmult(GB.rotational, temp); bj.wlambda.addScaledVector(deltalambda, temp, bj.wlambda); } computeC() { return this.computeGiMGt() + this.eps; } }; Equation.idCounter = 0; var iMfi = new Vec3(); var iMfj = new Vec3(); var invIi_vmult_taui = new Vec3(); var invIj_vmult_tauj = new Vec3(); var tmp2 = new Vec3(); var addToWlambda_temp = new Vec3(); var ContactEquation = class extends Equation { constructor(bodyA, bodyB, maxForce = 1e6) { super(bodyA, bodyB, 0, maxForce); this.restitution = void 0; this.ri = void 0; this.rj = void 0; this.ni = void 0; this.restitution = 0; this.ri = new Vec3(); this.rj = new Vec3(); this.ni = new Vec3(); } computeB(h) { const a2 = this.a; const b2 = this.b; const bi = this.bi; const bj = this.bj; const ri = this.ri; const rj = this.rj; const rixn = ContactEquation_computeB_temp1; const rjxn = ContactEquation_computeB_temp2; const vi = bi.velocity; const wi = bi.angularVelocity; bi.force; bi.torque; const vj = bj.velocity; const wj = bj.angularVelocity; bj.force; bj.torque; const penetrationVec = ContactEquation_computeB_temp3; const GA = this.jacobianElementA; const GB = this.jacobianElementB; const n = this.ni; ri.cross(n, rixn); rj.cross(n, rjxn); n.negate(GA.spatial); rixn.negate(GA.rotational); GB.spatial.copy(n); GB.rotational.copy(rjxn); penetrationVec.copy(bj.position); penetrationVec.vadd(rj, penetrationVec); penetrationVec.vsub(bi.position, penetrationVec); penetrationVec.vsub(ri, penetrationVec); const g = n.dot(penetrationVec); const ePlusOne = this.restitution + 1; const GW = ePlusOne * vj.dot(n) - ePlusOne * vi.dot(n) + wj.dot(rjxn) - wi.dot(rixn); const GiMf = this.computeGiMf(); const B = -g * a2 - GW * b2 - h * GiMf; return B; } getImpactVelocityAlongNormal() { const vi = ContactEquation_getImpactVelocityAlongNormal_vi; const vj = ContactEquation_getImpactVelocityAlongNormal_vj; const xi = ContactEquation_getImpactVelocityAlongNormal_xi; const xj = ContactEquation_getImpactVelocityAlongNormal_xj; const relVel = ContactEquation_getImpactVelocityAlongNormal_relVel; this.bi.position.vadd(this.ri, xi); this.bj.position.vadd(this.rj, xj); this.bi.getVelocityAtWorldPoint(xi, vi); this.bj.getVelocityAtWorldPoint(xj, vj); vi.vsub(vj, relVel); return this.ni.dot(relVel); } }; var ContactEquation_computeB_temp1 = new Vec3(); var ContactEquation_computeB_temp2 = new Vec3(); var ContactEquation_computeB_temp3 = new Vec3(); var ContactEquation_getImpactVelocityAlongNormal_vi = new Vec3(); var ContactEquation_getImpactVelocityAlongNormal_vj = new Vec3(); var ContactEquation_getImpactVelocityAlongNormal_xi = new Vec3(); var ContactEquation_getImpactVelocityAlongNormal_xj = new Vec3(); var ContactEquation_getImpactVelocityAlongNormal_relVel = new Vec3(); var tmpVec1$2 = new Vec3(); var tmpVec2$2 = new Vec3(); var tmpVec1$1 = new Vec3(); var tmpVec2$1 = new Vec3(); var HingeConstraint_update_tmpVec1 = new Vec3(); var HingeConstraint_update_tmpVec2 = new Vec3(); var FrictionEquation = class extends Equation { constructor(bodyA, bodyB, slipForce) { super(bodyA, bodyB, -slipForce, slipForce); this.ri = void 0; this.rj = void 0; this.t = void 0; this.ri = new Vec3(); this.rj = new Vec3(); this.t = new Vec3(); } computeB(h) { this.a; const b2 = this.b; this.bi; this.bj; const ri = this.ri; const rj = this.rj; const rixt = FrictionEquation_computeB_temp1; const rjxt = FrictionEquation_computeB_temp2; const t = this.t; ri.cross(t, rixt); rj.cross(t, rjxt); const GA = this.jacobianElementA; const GB = this.jacobianElementB; t.negate(GA.spatial); rixt.negate(GA.rotational); GB.spatial.copy(t); GB.rotational.copy(rjxt); const GW = this.computeGW(); const GiMf = this.computeGiMf(); const B = -GW * b2 - h * GiMf; return B; } }; var FrictionEquation_computeB_temp1 = new Vec3(); var FrictionEquation_computeB_temp2 = new Vec3(); var ContactMaterial = class { constructor(m1, m2, options) { this.id = void 0; this.materials = void 0; this.friction = void 0; this.restitution = void 0; this.contactEquationStiffness = void 0; this.contactEquationRelaxation = void 0; this.frictionEquationStiffness = void 0; this.frictionEquationRelaxation = void 0; options = Utils.defaults(options, { friction: 0.3, restitution: 0.3, contactEquationStiffness: 1e7, contactEquationRelaxation: 3, frictionEquationStiffness: 1e7, frictionEquationRelaxation: 3 }); this.id = ContactMaterial.idCounter++; this.materials = [m1, m2]; this.friction = options.friction; this.restitution = options.restitution; this.contactEquationStiffness = options.contactEquationStiffness; this.contactEquationRelaxation = options.contactEquationRelaxation; this.frictionEquationStiffness = options.frictionEquationStiffness; this.frictionEquationRelaxation = options.frictionEquationRelaxation; } }; ContactMaterial.idCounter = 0; var Material2 = class { constructor(options = {}) { this.name = void 0; this.id = void 0; this.friction = void 0; this.restitution = void 0; let name = ""; if (typeof options === "string") { name = options; options = {}; } this.name = name; this.id = Material2.idCounter++; this.friction = typeof options.friction !== "undefined" ? options.friction : -1; this.restitution = typeof options.restitution !== "undefined" ? options.restitution : -1; } }; Material2.idCounter = 0; var applyForce_r = new Vec3(); var applyForce_r_unit = new Vec3(); var applyForce_u = new Vec3(); var applyForce_f = new Vec3(); var applyForce_worldAnchorA = new Vec3(); var applyForce_worldAnchorB = new Vec3(); var applyForce_ri = new Vec3(); var applyForce_rj = new Vec3(); var applyForce_ri_x_f = new Vec3(); var applyForce_rj_x_f = new Vec3(); var applyForce_tmp = new Vec3(); var chassis_velocity_at_contactPoint = new Vec3(); var relpos = new Vec3(); var tmpVec4 = new Vec3(); var tmpVec5 = new Vec3(); var tmpVec6 = new Vec3(); new Ray2(); var castRay_rayvector = new Vec3(); var castRay_target = new Vec3(); var directions = [new Vec3(1, 0, 0), new Vec3(0, 1, 0), new Vec3(0, 0, 1)]; var updateFriction_surfNormalWS_scaled_proj = new Vec3(); var calcRollingFriction_vel1 = new Vec3(); var calcRollingFriction_vel2 = new Vec3(); var calcRollingFriction_vel = new Vec3(); var computeImpulseDenominator_r0 = new Vec3(); var computeImpulseDenominator_c0 = new Vec3(); var computeImpulseDenominator_vec = new Vec3(); var computeImpulseDenominator_m = new Vec3(); var resolveSingleBilateral_vel1 = new Vec3(); var resolveSingleBilateral_vel2 = new Vec3(); var resolveSingleBilateral_vel = new Vec3(); var torque = new Vec3(); var worldAxis = new Vec3(); var SPHSystem_getNeighbors_dist = new Vec3(); var SPHSystem_update_dist = new Vec3(); var SPHSystem_update_a_pressure = new Vec3(); var SPHSystem_update_a_visc = new Vec3(); var SPHSystem_update_gradW = new Vec3(); var SPHSystem_update_r_vec = new Vec3(); var SPHSystem_update_u = new Vec3(); var Plane2 = class extends Shape2 { constructor() { super({ type: Shape2.types.PLANE }); this.worldNormal = void 0; this.worldNormalNeedsUpdate = void 0; this.boundingSphereRadius = void 0; this.worldNormal = new Vec3(); this.worldNormalNeedsUpdate = true; this.boundingSphereRadius = Number.MAX_VALUE; } computeWorldNormal(quat) { const n = this.worldNormal; n.set(0, 0, 1); quat.vmult(n, n); this.worldNormalNeedsUpdate = false; } calculateLocalInertia(mass, target = new Vec3()) { return target; } volume() { return Number.MAX_VALUE; } calculateWorldAABB(pos, quat, min, max) { tempNormal.set(0, 0, 1); quat.vmult(tempNormal, tempNormal); const maxVal = Number.MAX_VALUE; min.set(-maxVal, -maxVal, -maxVal); max.set(maxVal, maxVal, maxVal); if (tempNormal.x === 1) { max.x = pos.x; } else if (tempNormal.x === -1) { min.x = pos.x; } if (tempNormal.y === 1) { max.y = pos.y; } else if (tempNormal.y === -1) { min.y = pos.y; } if (tempNormal.z === 1) { max.z = pos.z; } else if (tempNormal.z === -1) { min.z = pos.z; } } updateBoundingSphereRadius() { this.boundingSphereRadius = Number.MAX_VALUE; } }; var tempNormal = new Vec3(); var getHeightAt_weights = new Vec3(); var getHeightAt_a = new Vec3(); var getHeightAt_b = new Vec3(); var getHeightAt_c = new Vec3(); var getNormalAt_a = new Vec3(); var getNormalAt_b = new Vec3(); var getNormalAt_c = new Vec3(); var getNormalAt_e0 = new Vec3(); var getNormalAt_e1 = new Vec3(); var halfDiagonal = new Vec3(); var tmpAABB = new AABB(); var computeNormals_n = new Vec3(); var unscaledAABB = new AABB(); var getEdgeVector_va = new Vec3(); var getEdgeVector_vb = new Vec3(); var cb = new Vec3(); var ab = new Vec3(); var va = new Vec3(); var vb = new Vec3(); var vc = new Vec3(); var cli_aabb = new AABB(); var computeLocalAABB_worldVert = new Vec3(); var calculateWorldAABB_frame = new Transform(); var calculateWorldAABB_aabb = new AABB(); var Solver = class { constructor() { this.equations = void 0; this.equations = []; } solve(dt, world) { return 0; } addEquation(eq) { if (eq.enabled && !eq.bi.isTrigger && !eq.bj.isTrigger) { this.equations.push(eq); } } removeEquation(eq) { const eqs = this.equations; const i = eqs.indexOf(eq); if (i !== -1) { eqs.splice(i, 1); } } removeAllEquations() { this.equations.length = 0; } }; var GSSolver = class extends Solver { constructor() { super(); this.iterations = void 0; this.tolerance = void 0; this.iterations = 10; this.tolerance = 1e-7; } solve(dt, world) { let iter = 0; const maxIter = this.iterations; const tolSquared = this.tolerance * this.tolerance; const equations = this.equations; const Neq = equations.length; const bodies = world.bodies; const Nbodies = bodies.length; const h = dt; let B; let invC; let deltalambda; let deltalambdaTot; let GWlambda; let lambdaj; if (Neq !== 0) { for (let i = 0; i !== Nbodies; i++) { bodies[i].updateSolveMassProperties(); } } const invCs = GSSolver_solve_invCs; const Bs = GSSolver_solve_Bs; const lambda = GSSolver_solve_lambda; invCs.length = Neq; Bs.length = Neq; lambda.length = Neq; for (let i = 0; i !== Neq; i++) { const c2 = equations[i]; lambda[i] = 0; Bs[i] = c2.computeB(h); invCs[i] = 1 / c2.computeC(); } if (Neq !== 0) { for (let i = 0; i !== Nbodies; i++) { const b2 = bodies[i]; const vlambda = b2.vlambda; const wlambda = b2.wlambda; vlambda.set(0, 0, 0); wlambda.set(0, 0, 0); } for (iter = 0; iter !== maxIter; iter++) { deltalambdaTot = 0; for (let j = 0; j !== Neq; j++) { const c2 = equations[j]; B = Bs[j]; invC = invCs[j]; lambdaj = lambda[j]; GWlambda = c2.computeGWlambda(); deltalambda = invC * (B - GWlambda - c2.eps * lambdaj); if (lambdaj + deltalambda < c2.minForce) { deltalambda = c2.minForce - lambdaj; } else if (lambdaj + deltalambda > c2.maxForce) { deltalambda = c2.maxForce - lambdaj; } lambda[j] += deltalambda; deltalambdaTot += deltalambda > 0 ? deltalambda : -deltalambda; c2.addToWlambda(deltalambda); } if (deltalambdaTot * deltalambdaTot < tolSquared) { break; } } for (let i = 0; i !== Nbodies; i++) { const b2 = bodies[i]; const v = b2.velocity; const w2 = b2.angularVelocity; b2.vlambda.vmul(b2.linearFactor, b2.vlambda); v.vadd(b2.vlambda, v); b2.wlambda.vmul(b2.angularFactor, b2.wlambda); w2.vadd(b2.wlambda, w2); } let l = equations.length; const invDt = 1 / h; while (l--) { equations[l].multiplier = lambda[l] * invDt; } } return iter; } }; var GSSolver_solve_lambda = []; var GSSolver_solve_invCs = []; var GSSolver_solve_Bs = []; var STATIC = Body.STATIC; var Pool = class { constructor() { this.objects = []; this.type = Object; } release(...args) { const Nargs = args.length; for (let i = 0; i !== Nargs; i++) { this.objects.push(args[i]); } return this; } get() { if (this.objects.length === 0) { return this.constructObject(); } else { return this.objects.pop(); } } constructObject() { throw new Error("constructObject() not implemented in this Pool subclass yet!"); } resize(size) { const objects = this.objects; while (objects.length > size) { objects.pop(); } while (objects.length < size) { objects.push(this.constructObject()); } return this; } }; var Vec3Pool = class extends Pool { constructor(...args) { super(...args); this.type = Vec3; } constructObject() { return new Vec3(); } }; var _COLLISION_TYPES$sphe; var _COLLISION_TYPES$sphe2; var _COLLISION_TYPES$boxB; var _COLLISION_TYPES$sphe3; var _COLLISION_TYPES$plan; var _COLLISION_TYPES$conv; var _COLLISION_TYPES$sphe4; var _COLLISION_TYPES$plan2; var _COLLISION_TYPES$boxC; var _COLLISION_TYPES$sphe5; var _COLLISION_TYPES$boxH; var _COLLISION_TYPES$conv2; var _COLLISION_TYPES$sphe6; var _COLLISION_TYPES$plan3; var _COLLISION_TYPES$boxP; var _COLLISION_TYPES$conv3; var _COLLISION_TYPES$cyli; var _COLLISION_TYPES$sphe7; var _COLLISION_TYPES$plan4; var _COLLISION_TYPES$boxC2; var _COLLISION_TYPES$conv4; var _COLLISION_TYPES$heig; var _COLLISION_TYPES$part; var _COLLISION_TYPES$sphe8; var _COLLISION_TYPES$plan5; var COLLISION_TYPES = { sphereSphere: Shape2.types.SPHERE, spherePlane: Shape2.types.SPHERE | Shape2.types.PLANE, boxBox: Shape2.types.BOX | Shape2.types.BOX, sphereBox: Shape2.types.SPHERE | Shape2.types.BOX, planeBox: Shape2.types.PLANE | Shape2.types.BOX, convexConvex: Shape2.types.CONVEXPOLYHEDRON, sphereConvex: Shape2.types.SPHERE | Shape2.types.CONVEXPOLYHEDRON, planeConvex: Shape2.types.PLANE | Shape2.types.CONVEXPOLYHEDRON, boxConvex: Shape2.types.BOX | Shape2.types.CONVEXPOLYHEDRON, sphereHeightfield: Shape2.types.SPHERE | Shape2.types.HEIGHTFIELD, boxHeightfield: Shape2.types.BOX | Shape2.types.HEIGHTFIELD, convexHeightfield: Shape2.types.CONVEXPOLYHEDRON | Shape2.types.HEIGHTFIELD, sphereParticle: Shape2.types.PARTICLE | Shape2.types.SPHERE, planeParticle: Shape2.types.PLANE | Shape2.types.PARTICLE, boxParticle: Shape2.types.BOX | Shape2.types.PARTICLE, convexParticle: Shape2.types.PARTICLE | Shape2.types.CONVEXPOLYHEDRON, cylinderCylinder: Shape2.types.CYLINDER, sphereCylinder: Shape2.types.SPHERE | Shape2.types.CYLINDER, planeCylinder: Shape2.types.PLANE | Shape2.types.CYLINDER, boxCylinder: Shape2.types.BOX | Shape2.types.CYLINDER, convexCylinder: Shape2.types.CONVEXPOLYHEDRON | Shape2.types.CYLINDER, heightfieldCylinder: Shape2.types.HEIGHTFIELD | Shape2.types.CYLINDER, particleCylinder: Shape2.types.PARTICLE | Shape2.types.CYLINDER, sphereTrimesh: Shape2.types.SPHERE | Shape2.types.TRIMESH, planeTrimesh: Shape2.types.PLANE | Shape2.types.TRIMESH }; _COLLISION_TYPES$sphe = COLLISION_TYPES.sphereSphere; _COLLISION_TYPES$sphe2 = COLLISION_TYPES.spherePlane; _COLLISION_TYPES$boxB = COLLISION_TYPES.boxBox; _COLLISION_TYPES$sphe3 = COLLISION_TYPES.sphereBox; _COLLISION_TYPES$plan = COLLISION_TYPES.planeBox; _COLLISION_TYPES$conv = COLLISION_TYPES.convexConvex; _COLLISION_TYPES$sphe4 = COLLISION_TYPES.sphereConvex; _COLLISION_TYPES$plan2 = COLLISION_TYPES.planeConvex; _COLLISION_TYPES$boxC = COLLISION_TYPES.boxConvex; _COLLISION_TYPES$sphe5 = COLLISION_TYPES.sphereHeightfield; _COLLISION_TYPES$boxH = COLLISION_TYPES.boxHeightfield; _COLLISION_TYPES$conv2 = COLLISION_TYPES.convexHeightfield; _COLLISION_TYPES$sphe6 = COLLISION_TYPES.sphereParticle; _COLLISION_TYPES$plan3 = COLLISION_TYPES.planeParticle; _COLLISION_TYPES$boxP = COLLISION_TYPES.boxParticle; _COLLISION_TYPES$conv3 = COLLISION_TYPES.convexParticle; _COLLISION_TYPES$cyli = COLLISION_TYPES.cylinderCylinder; _COLLISION_TYPES$sphe7 = COLLISION_TYPES.sphereCylinder; _COLLISION_TYPES$plan4 = COLLISION_TYPES.planeCylinder; _COLLISION_TYPES$boxC2 = COLLISION_TYPES.boxCylinder; _COLLISION_TYPES$conv4 = COLLISION_TYPES.convexCylinder; _COLLISION_TYPES$heig = COLLISION_TYPES.heightfieldCylinder; _COLLISION_TYPES$part = COLLISION_TYPES.particleCylinder; _COLLISION_TYPES$sphe8 = COLLISION_TYPES.sphereTrimesh; _COLLISION_TYPES$plan5 = COLLISION_TYPES.planeTrimesh; var Narrowphase = class { get [_COLLISION_TYPES$sphe]() { return this.sphereSphere; } get [_COLLISION_TYPES$sphe2]() { return this.spherePlane; } get [_COLLISION_TYPES$boxB]() { return this.boxBox; } get [_COLLISION_TYPES$sphe3]() { return this.sphereBox; } get [_COLLISION_TYPES$plan]() { return this.planeBox; } get [_COLLISION_TYPES$conv]() { return this.convexConvex; } get [_COLLISION_TYPES$sphe4]() { return this.sphereConvex; } get [_COLLISION_TYPES$plan2]() { return this.planeConvex; } get [_COLLISION_TYPES$boxC]() { return this.boxConvex; } get [_COLLISION_TYPES$sphe5]() { return this.sphereHeightfield; } get [_COLLISION_TYPES$boxH]() { return this.boxHeightfield; } get [_COLLISION_TYPES$conv2]() { return this.convexHeightfield; } get [_COLLISION_TYPES$sphe6]() { return this.sphereParticle; } get [_COLLISION_TYPES$plan3]() { return this.planeParticle; } get [_COLLISION_TYPES$boxP]() { return this.boxParticle; } get [_COLLISION_TYPES$conv3]() { return this.convexParticle; } get [_COLLISION_TYPES$cyli]() { return this.convexConvex; } get [_COLLISION_TYPES$sphe7]() { return this.sphereConvex; } get [_COLLISION_TYPES$plan4]() { return this.planeConvex; } get [_COLLISION_TYPES$boxC2]() { return this.boxConvex; } get [_COLLISION_TYPES$conv4]() { return this.convexConvex; } get [_COLLISION_TYPES$heig]() { return this.heightfieldCylinder; } get [_COLLISION_TYPES$part]() { return this.particleCylinder; } get [_COLLISION_TYPES$sphe8]() { return this.sphereTrimesh; } get [_COLLISION_TYPES$plan5]() { return this.planeTrimesh; } constructor(world) { this.contactPointPool = void 0; this.frictionEquationPool = void 0; this.result = void 0; this.frictionResult = void 0; this.v3pool = void 0; this.world = void 0; this.currentContactMaterial = void 0; this.enableFrictionReduction = void 0; this.contactPointPool = []; this.frictionEquationPool = []; this.result = []; this.frictionResult = []; this.v3pool = new Vec3Pool(); this.world = world; this.currentContactMaterial = world.defaultContactMaterial; this.enableFrictionReduction = false; } createContactEquation(bi, bj, si, sj, overrideShapeA, overrideShapeB) { let c2; if (this.contactPointPool.length) { c2 = this.contactPointPool.pop(); c2.bi = bi; c2.bj = bj; } else { c2 = new ContactEquation(bi, bj); } c2.enabled = bi.collisionResponse && bj.collisionResponse && si.collisionResponse && sj.collisionResponse; const cm = this.currentContactMaterial; c2.restitution = cm.restitution; c2.setSpookParams(cm.contactEquationStiffness, cm.contactEquationRelaxation, this.world.dt); const matA = si.material || bi.material; const matB = sj.material || bj.material; if (matA && matB && matA.restitution >= 0 && matB.restitution >= 0) { c2.restitution = matA.restitution * matB.restitution; } c2.si = overrideShapeA || si; c2.sj = overrideShapeB || sj; return c2; } createFrictionEquationsFromContact(contactEquation, outArray) { const bodyA = contactEquation.bi; const bodyB = contactEquation.bj; const shapeA = contactEquation.si; const shapeB = contactEquation.sj; const world = this.world; const cm = this.currentContactMaterial; let friction = cm.friction; const matA = shapeA.material || bodyA.material; const matB = shapeB.material || bodyB.material; if (matA && matB && matA.friction >= 0 && matB.friction >= 0) { friction = matA.friction * matB.friction; } if (friction > 0) { const mug = friction * world.gravity.length(); let reducedMass = bodyA.invMass + bodyB.invMass; if (reducedMass > 0) { reducedMass = 1 / reducedMass; } const pool = this.frictionEquationPool; const c1 = pool.length ? pool.pop() : new FrictionEquation(bodyA, bodyB, mug * reducedMass); const c2 = pool.length ? pool.pop() : new FrictionEquation(bodyA, bodyB, mug * reducedMass); c1.bi = c2.bi = bodyA; c1.bj = c2.bj = bodyB; c1.minForce = c2.minForce = -mug * reducedMass; c1.maxForce = c2.maxForce = mug * reducedMass; c1.ri.copy(contactEquation.ri); c1.rj.copy(contactEquation.rj); c2.ri.copy(contactEquation.ri); c2.rj.copy(contactEquation.rj); contactEquation.ni.tangents(c1.t, c2.t); c1.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, world.dt); c2.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, world.dt); c1.enabled = c2.enabled = contactEquation.enabled; outArray.push(c1, c2); return true; } return false; } createFrictionFromAverage(numContacts) { let c2 = this.result[this.result.length - 1]; if (!this.createFrictionEquationsFromContact(c2, this.frictionResult) || numContacts === 1) { return; } const f1 = this.frictionResult[this.frictionResult.length - 2]; const f2 = this.frictionResult[this.frictionResult.length - 1]; averageNormal.setZero(); averageContactPointA.setZero(); averageContactPointB.setZero(); const bodyA = c2.bi; c2.bj; for (let i = 0; i !== numContacts; i++) { c2 = this.result[this.result.length - 1 - i]; if (c2.bi !== bodyA) { averageNormal.vadd(c2.ni, averageNormal); averageContactPointA.vadd(c2.ri, averageContactPointA); averageContactPointB.vadd(c2.rj, averageContactPointB); } else { averageNormal.vsub(c2.ni, averageNormal); averageContactPointA.vadd(c2.rj, averageContactPointA); averageContactPointB.vadd(c2.ri, averageContactPointB); } } const invNumContacts = 1 / numContacts; averageContactPointA.scale(invNumContacts, f1.ri); averageContactPointB.scale(invNumContacts, f1.rj); f2.ri.copy(f1.ri); f2.rj.copy(f1.rj); averageNormal.normalize(); averageNormal.tangents(f1.t, f2.t); } getContacts(p1, p2, world, result, oldcontacts, frictionResult, frictionPool) { this.contactPointPool = oldcontacts; this.frictionEquationPool = frictionPool; this.result = result; this.frictionResult = frictionResult; const qi = tmpQuat1; const qj = tmpQuat2; const xi = tmpVec1; const xj = tmpVec2; for (let k = 0, N = p1.length; k !== N; k++) { const bi = p1[k]; const bj = p2[k]; let bodyContactMaterial = null; if (bi.material && bj.material) { bodyContactMaterial = world.getContactMaterial(bi.material, bj.material) || null; } const justTest = bi.type & Body.KINEMATIC && bj.type & Body.STATIC || bi.type & Body.STATIC && bj.type & Body.KINEMATIC || bi.type & Body.KINEMATIC && bj.type & Body.KINEMATIC; for (let i = 0; i < bi.shapes.length; i++) { bi.quaternion.mult(bi.shapeOrientations[i], qi); bi.quaternion.vmult(bi.shapeOffsets[i], xi); xi.vadd(bi.position, xi); const si = bi.shapes[i]; for (let j = 0; j < bj.shapes.length; j++) { bj.quaternion.mult(bj.shapeOrientations[j], qj); bj.quaternion.vmult(bj.shapeOffsets[j], xj); xj.vadd(bj.position, xj); const sj = bj.shapes[j]; if (!(si.collisionFilterMask & sj.collisionFilterGroup && sj.collisionFilterMask & si.collisionFilterGroup)) { continue; } if (xi.distanceTo(xj) > si.boundingSphereRadius + sj.boundingSphereRadius) { continue; } let shapeContactMaterial = null; if (si.material && sj.material) { shapeContactMaterial = world.getContactMaterial(si.material, sj.material) || null; } this.currentContactMaterial = shapeContactMaterial || bodyContactMaterial || world.defaultContactMaterial; const resolverIndex = si.type | sj.type; const resolver = this[resolverIndex]; if (resolver) { let retval = false; if (si.type < sj.type) { retval = resolver.call(this, si, sj, xi, xj, qi, qj, bi, bj, si, sj, justTest); } else { retval = resolver.call(this, sj, si, xj, xi, qj, qi, bj, bi, si, sj, justTest); } if (retval && justTest) { world.shapeOverlapKeeper.set(si.id, sj.id); world.bodyOverlapKeeper.set(bi.id, bj.id); } } } } } } sphereSphere(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest) { if (justTest) { return xi.distanceSquared(xj) < (si.radius + sj.radius) ** 2; } const contactEq = this.createContactEquation(bi, bj, si, sj, rsi, rsj); xj.vsub(xi, contactEq.ni); contactEq.ni.normalize(); contactEq.ri.copy(contactEq.ni); contactEq.rj.copy(contactEq.ni); contactEq.ri.scale(si.radius, contactEq.ri); contactEq.rj.scale(-sj.radius, contactEq.rj); contactEq.ri.vadd(xi, contactEq.ri); contactEq.ri.vsub(bi.position, contactEq.ri); contactEq.rj.vadd(xj, contactEq.rj); contactEq.rj.vsub(bj.position, contactEq.rj); this.result.push(contactEq); this.createFrictionEquationsFromContact(contactEq, this.frictionResult); } spherePlane(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest) { const r = this.createContactEquation(bi, bj, si, sj, rsi, rsj); r.ni.set(0, 0, 1); qj.vmult(r.ni, r.ni); r.ni.negate(r.ni); r.ni.normalize(); r.ni.scale(si.radius, r.ri); xi.vsub(xj, point_on_plane_to_sphere); r.ni.scale(r.ni.dot(point_on_plane_to_sphere), plane_to_sphere_ortho); point_on_plane_to_sphere.vsub(plane_to_sphere_ortho, r.rj); if (-point_on_plane_to_sphere.dot(r.ni) <= si.radius) { if (justTest) { return true; } const ri = r.ri; const rj = r.rj; ri.vadd(xi, ri); ri.vsub(bi.position, ri); rj.vadd(xj, rj); rj.vsub(bj.position, rj); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); } } boxBox(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest) { si.convexPolyhedronRepresentation.material = si.material; sj.convexPolyhedronRepresentation.material = sj.material; si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse; sj.convexPolyhedronRepresentation.collisionResponse = sj.collisionResponse; return this.convexConvex(si.convexPolyhedronRepresentation, sj.convexPolyhedronRepresentation, xi, xj, qi, qj, bi, bj, si, sj, justTest); } sphereBox(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest) { const v3pool = this.v3pool; const sides = sphereBox_sides; xi.vsub(xj, box_to_sphere); sj.getSideNormals(sides, qj); const R = si.radius; let found = false; const side_ns = sphereBox_side_ns; const side_ns1 = sphereBox_side_ns1; const side_ns2 = sphereBox_side_ns2; let side_h = null; let side_penetrations = 0; let side_dot1 = 0; let side_dot2 = 0; let side_distance = null; for (let idx = 0, nsides = sides.length; idx !== nsides && found === false; idx++) { const ns = sphereBox_ns; ns.copy(sides[idx]); const h = ns.length(); ns.normalize(); const dot = box_to_sphere.dot(ns); if (dot < h + R && dot > 0) { const ns1 = sphereBox_ns1; const ns2 = sphereBox_ns2; ns1.copy(sides[(idx + 1) % 3]); ns2.copy(sides[(idx + 2) % 3]); const h1 = ns1.length(); const h2 = ns2.length(); ns1.normalize(); ns2.normalize(); const dot1 = box_to_sphere.dot(ns1); const dot2 = box_to_sphere.dot(ns2); if (dot1 < h1 && dot1 > -h1 && dot2 < h2 && dot2 > -h2) { const dist2 = Math.abs(dot - h - R); if (side_distance === null || dist2 < side_distance) { side_distance = dist2; side_dot1 = dot1; side_dot2 = dot2; side_h = h; side_ns.copy(ns); side_ns1.copy(ns1); side_ns2.copy(ns2); side_penetrations++; if (justTest) { return true; } } } } } if (side_penetrations) { found = true; const r2 = this.createContactEquation(bi, bj, si, sj, rsi, rsj); side_ns.scale(-R, r2.ri); r2.ni.copy(side_ns); r2.ni.negate(r2.ni); side_ns.scale(side_h, side_ns); side_ns1.scale(side_dot1, side_ns1); side_ns.vadd(side_ns1, side_ns); side_ns2.scale(side_dot2, side_ns2); side_ns.vadd(side_ns2, r2.rj); r2.ri.vadd(xi, r2.ri); r2.ri.vsub(bi.position, r2.ri); r2.rj.vadd(xj, r2.rj); r2.rj.vsub(bj.position, r2.rj); this.result.push(r2); this.createFrictionEquationsFromContact(r2, this.frictionResult); } let rj = v3pool.get(); const sphere_to_corner = sphereBox_sphere_to_corner; for (let j = 0; j !== 2 && !found; j++) { for (let k = 0; k !== 2 && !found; k++) { for (let l = 0; l !== 2 && !found; l++) { rj.set(0, 0, 0); if (j) { rj.vadd(sides[0], rj); } else { rj.vsub(sides[0], rj); } if (k) { rj.vadd(sides[1], rj); } else { rj.vsub(sides[1], rj); } if (l) { rj.vadd(sides[2], rj); } else { rj.vsub(sides[2], rj); } xj.vadd(rj, sphere_to_corner); sphere_to_corner.vsub(xi, sphere_to_corner); if (sphere_to_corner.lengthSquared() < R * R) { if (justTest) { return true; } found = true; const r2 = this.createContactEquation(bi, bj, si, sj, rsi, rsj); r2.ri.copy(sphere_to_corner); r2.ri.normalize(); r2.ni.copy(r2.ri); r2.ri.scale(R, r2.ri); r2.rj.copy(rj); r2.ri.vadd(xi, r2.ri); r2.ri.vsub(bi.position, r2.ri); r2.rj.vadd(xj, r2.rj); r2.rj.vsub(bj.position, r2.rj); this.result.push(r2); this.createFrictionEquationsFromContact(r2, this.frictionResult); } } } } v3pool.release(rj); rj = null; const edgeTangent = v3pool.get(); const edgeCenter = v3pool.get(); const r = v3pool.get(); const orthogonal = v3pool.get(); const dist = v3pool.get(); const Nsides = sides.length; for (let j = 0; j !== Nsides && !found; j++) { for (let k = 0; k !== Nsides && !found; k++) { if (j % 3 !== k % 3) { sides[k].cross(sides[j], edgeTangent); edgeTangent.normalize(); sides[j].vadd(sides[k], edgeCenter); r.copy(xi); r.vsub(edgeCenter, r); r.vsub(xj, r); const orthonorm = r.dot(edgeTangent); edgeTangent.scale(orthonorm, orthogonal); let l = 0; while (l === j % 3 || l === k % 3) { l++; } dist.copy(xi); dist.vsub(orthogonal, dist); dist.vsub(edgeCenter, dist); dist.vsub(xj, dist); const tdist = Math.abs(orthonorm); const ndist = dist.length(); if (tdist < sides[l].length() && ndist < R) { if (justTest) { return true; } found = true; const res = this.createContactEquation(bi, bj, si, sj, rsi, rsj); edgeCenter.vadd(orthogonal, res.rj); res.rj.copy(res.rj); dist.negate(res.ni); res.ni.normalize(); res.ri.copy(res.rj); res.ri.vadd(xj, res.ri); res.ri.vsub(xi, res.ri); res.ri.normalize(); res.ri.scale(R, res.ri); res.ri.vadd(xi, res.ri); res.ri.vsub(bi.position, res.ri); res.rj.vadd(xj, res.rj); res.rj.vsub(bj.position, res.rj); this.result.push(res); this.createFrictionEquationsFromContact(res, this.frictionResult); } } } } v3pool.release(edgeTangent, edgeCenter, r, orthogonal, dist); } planeBox(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest) { sj.convexPolyhedronRepresentation.material = sj.material; sj.convexPolyhedronRepresentation.collisionResponse = sj.collisionResponse; sj.convexPolyhedronRepresentation.id = sj.id; return this.planeConvex(si, sj.convexPolyhedronRepresentation, xi, xj, qi, qj, bi, bj, si, sj, justTest); } convexConvex(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest, faceListA, faceListB) { const sepAxis = convexConvex_sepAxis; if (xi.distanceTo(xj) > si.boundingSphereRadius + sj.boundingSphereRadius) { return; } if (si.findSeparatingAxis(sj, xi, qi, xj, qj, sepAxis, faceListA, faceListB)) { const res = []; const q = convexConvex_q; si.clipAgainstHull(xi, qi, sj, xj, qj, sepAxis, -100, 100, res); let numContacts = 0; for (let j = 0; j !== res.length; j++) { if (justTest) { return true; } const r = this.createContactEquation(bi, bj, si, sj, rsi, rsj); const ri = r.ri; const rj = r.rj; sepAxis.negate(r.ni); res[j].normal.negate(q); q.scale(res[j].depth, q); res[j].point.vadd(q, ri); rj.copy(res[j].point); ri.vsub(xi, ri); rj.vsub(xj, rj); ri.vadd(xi, ri); ri.vsub(bi.position, ri); rj.vadd(xj, rj); rj.vsub(bj.position, rj); this.result.push(r); numContacts++; if (!this.enableFrictionReduction) { this.createFrictionEquationsFromContact(r, this.frictionResult); } } if (this.enableFrictionReduction && numContacts) { this.createFrictionFromAverage(numContacts); } } } sphereConvex(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest) { const v3pool = this.v3pool; xi.vsub(xj, convex_to_sphere); const normals = sj.faceNormals; const faces = sj.faces; const verts = sj.vertices; const R = si.radius; let found = false; for (let i = 0; i !== verts.length; i++) { const v = verts[i]; const worldCorner = sphereConvex_worldCorner; qj.vmult(v, worldCorner); xj.vadd(worldCorner, worldCorner); const sphere_to_corner = sphereConvex_sphereToCorner; worldCorner.vsub(xi, sphere_to_corner); if (sphere_to_corner.lengthSquared() < R * R) { if (justTest) { return true; } found = true; const r = this.createContactEquation(bi, bj, si, sj, rsi, rsj); r.ri.copy(sphere_to_corner); r.ri.normalize(); r.ni.copy(r.ri); r.ri.scale(R, r.ri); worldCorner.vsub(xj, r.rj); r.ri.vadd(xi, r.ri); r.ri.vsub(bi.position, r.ri); r.rj.vadd(xj, r.rj); r.rj.vsub(bj.position, r.rj); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); return; } } for (let i = 0, nfaces = faces.length; i !== nfaces && found === false; i++) { const normal = normals[i]; const face = faces[i]; const worldNormal = sphereConvex_worldNormal; qj.vmult(normal, worldNormal); const worldPoint = sphereConvex_worldPoint; qj.vmult(verts[face[0]], worldPoint); worldPoint.vadd(xj, worldPoint); const worldSpherePointClosestToPlane = sphereConvex_worldSpherePointClosestToPlane; worldNormal.scale(-R, worldSpherePointClosestToPlane); xi.vadd(worldSpherePointClosestToPlane, worldSpherePointClosestToPlane); const penetrationVec = sphereConvex_penetrationVec; worldSpherePointClosestToPlane.vsub(worldPoint, penetrationVec); const penetration = penetrationVec.dot(worldNormal); const worldPointToSphere = sphereConvex_sphereToWorldPoint; xi.vsub(worldPoint, worldPointToSphere); if (penetration < 0 && worldPointToSphere.dot(worldNormal) > 0) { const faceVerts = []; for (let j = 0, Nverts = face.length; j !== Nverts; j++) { const worldVertex = v3pool.get(); qj.vmult(verts[face[j]], worldVertex); xj.vadd(worldVertex, worldVertex); faceVerts.push(worldVertex); } if (pointInPolygon(faceVerts, worldNormal, xi)) { if (justTest) { return true; } found = true; const r = this.createContactEquation(bi, bj, si, sj, rsi, rsj); worldNormal.scale(-R, r.ri); worldNormal.negate(r.ni); const penetrationVec2 = v3pool.get(); worldNormal.scale(-penetration, penetrationVec2); const penetrationSpherePoint = v3pool.get(); worldNormal.scale(-R, penetrationSpherePoint); xi.vsub(xj, r.rj); r.rj.vadd(penetrationSpherePoint, r.rj); r.rj.vadd(penetrationVec2, r.rj); r.rj.vadd(xj, r.rj); r.rj.vsub(bj.position, r.rj); r.ri.vadd(xi, r.ri); r.ri.vsub(bi.position, r.ri); v3pool.release(penetrationVec2); v3pool.release(penetrationSpherePoint); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); for (let j = 0, Nfaceverts = faceVerts.length; j !== Nfaceverts; j++) { v3pool.release(faceVerts[j]); } return; } else { for (let j = 0; j !== face.length; j++) { const v12 = v3pool.get(); const v22 = v3pool.get(); qj.vmult(verts[face[(j + 1) % face.length]], v12); qj.vmult(verts[face[(j + 2) % face.length]], v22); xj.vadd(v12, v12); xj.vadd(v22, v22); const edge = sphereConvex_edge; v22.vsub(v12, edge); const edgeUnit = sphereConvex_edgeUnit; edge.unit(edgeUnit); const p2 = v3pool.get(); const v1_to_xi = v3pool.get(); xi.vsub(v12, v1_to_xi); const dot = v1_to_xi.dot(edgeUnit); edgeUnit.scale(dot, p2); p2.vadd(v12, p2); const xi_to_p = v3pool.get(); p2.vsub(xi, xi_to_p); if (dot > 0 && dot * dot < edge.lengthSquared() && xi_to_p.lengthSquared() < R * R) { if (justTest) { return true; } const r = this.createContactEquation(bi, bj, si, sj, rsi, rsj); p2.vsub(xj, r.rj); p2.vsub(xi, r.ni); r.ni.normalize(); r.ni.scale(R, r.ri); r.rj.vadd(xj, r.rj); r.rj.vsub(bj.position, r.rj); r.ri.vadd(xi, r.ri); r.ri.vsub(bi.position, r.ri); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); for (let j2 = 0, Nfaceverts = faceVerts.length; j2 !== Nfaceverts; j2++) { v3pool.release(faceVerts[j2]); } v3pool.release(v12); v3pool.release(v22); v3pool.release(p2); v3pool.release(xi_to_p); v3pool.release(v1_to_xi); return; } v3pool.release(v12); v3pool.release(v22); v3pool.release(p2); v3pool.release(xi_to_p); v3pool.release(v1_to_xi); } } for (let j = 0, Nfaceverts = faceVerts.length; j !== Nfaceverts; j++) { v3pool.release(faceVerts[j]); } } } } planeConvex(planeShape, convexShape, planePosition, convexPosition, planeQuat, convexQuat, planeBody, convexBody, si, sj, justTest) { const worldVertex = planeConvex_v; const worldNormal = planeConvex_normal; worldNormal.set(0, 0, 1); planeQuat.vmult(worldNormal, worldNormal); let numContacts = 0; const relpos2 = planeConvex_relpos; for (let i = 0; i !== convexShape.vertices.length; i++) { worldVertex.copy(convexShape.vertices[i]); convexQuat.vmult(worldVertex, worldVertex); convexPosition.vadd(worldVertex, worldVertex); worldVertex.vsub(planePosition, relpos2); const dot = worldNormal.dot(relpos2); if (dot <= 0) { if (justTest) { return true; } const r = this.createContactEquation(planeBody, convexBody, planeShape, convexShape, si, sj); const projected = planeConvex_projected; worldNormal.scale(worldNormal.dot(relpos2), projected); worldVertex.vsub(projected, projected); projected.vsub(planePosition, r.ri); r.ni.copy(worldNormal); worldVertex.vsub(convexPosition, r.rj); r.ri.vadd(planePosition, r.ri); r.ri.vsub(planeBody.position, r.ri); r.rj.vadd(convexPosition, r.rj); r.rj.vsub(convexBody.position, r.rj); this.result.push(r); numContacts++; if (!this.enableFrictionReduction) { this.createFrictionEquationsFromContact(r, this.frictionResult); } } } if (this.enableFrictionReduction && numContacts) { this.createFrictionFromAverage(numContacts); } } boxConvex(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest) { si.convexPolyhedronRepresentation.material = si.material; si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse; return this.convexConvex(si.convexPolyhedronRepresentation, sj, xi, xj, qi, qj, bi, bj, si, sj, justTest); } sphereHeightfield(sphereShape, hfShape, spherePos, hfPos, sphereQuat, hfQuat, sphereBody, hfBody, rsi, rsj, justTest) { const data = hfShape.data; const radius = sphereShape.radius; const w2 = hfShape.elementSize; const worldPillarOffset2 = sphereHeightfield_tmp2; const localSpherePos = sphereHeightfield_tmp1; Transform.pointToLocalFrame(hfPos, hfQuat, spherePos, localSpherePos); let iMinX = Math.floor((localSpherePos.x - radius) / w2) - 1; let iMaxX = Math.ceil((localSpherePos.x + radius) / w2) + 1; let iMinY = Math.floor((localSpherePos.y - radius) / w2) - 1; let iMaxY = Math.ceil((localSpherePos.y + radius) / w2) + 1; if (iMaxX < 0 || iMaxY < 0 || iMinX > data.length || iMinY > data[0].length) { return; } if (iMinX < 0) { iMinX = 0; } if (iMaxX < 0) { iMaxX = 0; } if (iMinY < 0) { iMinY = 0; } if (iMaxY < 0) { iMaxY = 0; } if (iMinX >= data.length) { iMinX = data.length - 1; } if (iMaxX >= data.length) { iMaxX = data.length - 1; } if (iMaxY >= data[0].length) { iMaxY = data[0].length - 1; } if (iMinY >= data[0].length) { iMinY = data[0].length - 1; } const minMax = []; hfShape.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax); const min = minMax[0]; const max = minMax[1]; if (localSpherePos.z - radius > max || localSpherePos.z + radius < min) { return; } const result = this.result; for (let i = iMinX; i < iMaxX; i++) { for (let j = iMinY; j < iMaxY; j++) { const numContactsBefore = result.length; let intersecting = false; hfShape.getConvexTrianglePillar(i, j, false); Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset2); if (spherePos.distanceTo(worldPillarOffset2) < hfShape.pillarConvex.boundingSphereRadius + sphereShape.boundingSphereRadius) { intersecting = this.sphereConvex(sphereShape, hfShape.pillarConvex, spherePos, worldPillarOffset2, sphereQuat, hfQuat, sphereBody, hfBody, sphereShape, hfShape, justTest); } if (justTest && intersecting) { return true; } hfShape.getConvexTrianglePillar(i, j, true); Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset2); if (spherePos.distanceTo(worldPillarOffset2) < hfShape.pillarConvex.boundingSphereRadius + sphereShape.boundingSphereRadius) { intersecting = this.sphereConvex(sphereShape, hfShape.pillarConvex, spherePos, worldPillarOffset2, sphereQuat, hfQuat, sphereBody, hfBody, sphereShape, hfShape, justTest); } if (justTest && intersecting) { return true; } const numContacts = result.length - numContactsBefore; if (numContacts > 2) { return; } } } } boxHeightfield(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest) { si.convexPolyhedronRepresentation.material = si.material; si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse; return this.convexHeightfield(si.convexPolyhedronRepresentation, sj, xi, xj, qi, qj, bi, bj, si, sj, justTest); } convexHeightfield(convexShape, hfShape, convexPos, hfPos, convexQuat, hfQuat, convexBody, hfBody, rsi, rsj, justTest) { const data = hfShape.data; const w2 = hfShape.elementSize; const radius = convexShape.boundingSphereRadius; const worldPillarOffset2 = convexHeightfield_tmp2; const faceList = convexHeightfield_faceList; const localConvexPos = convexHeightfield_tmp1; Transform.pointToLocalFrame(hfPos, hfQuat, convexPos, localConvexPos); let iMinX = Math.floor((localConvexPos.x - radius) / w2) - 1; let iMaxX = Math.ceil((localConvexPos.x + radius) / w2) + 1; let iMinY = Math.floor((localConvexPos.y - radius) / w2) - 1; let iMaxY = Math.ceil((localConvexPos.y + radius) / w2) + 1; if (iMaxX < 0 || iMaxY < 0 || iMinX > data.length || iMinY > data[0].length) { return; } if (iMinX < 0) { iMinX = 0; } if (iMaxX < 0) { iMaxX = 0; } if (iMinY < 0) { iMinY = 0; } if (iMaxY < 0) { iMaxY = 0; } if (iMinX >= data.length) { iMinX = data.length - 1; } if (iMaxX >= data.length) { iMaxX = data.length - 1; } if (iMaxY >= data[0].length) { iMaxY = data[0].length - 1; } if (iMinY >= data[0].length) { iMinY = data[0].length - 1; } const minMax = []; hfShape.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax); const min = minMax[0]; const max = minMax[1]; if (localConvexPos.z - radius > max || localConvexPos.z + radius < min) { return; } for (let i = iMinX; i < iMaxX; i++) { for (let j = iMinY; j < iMaxY; j++) { let intersecting = false; hfShape.getConvexTrianglePillar(i, j, false); Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset2); if (convexPos.distanceTo(worldPillarOffset2) < hfShape.pillarConvex.boundingSphereRadius + convexShape.boundingSphereRadius) { intersecting = this.convexConvex(convexShape, hfShape.pillarConvex, convexPos, worldPillarOffset2, convexQuat, hfQuat, convexBody, hfBody, null, null, justTest, faceList, null); } if (justTest && intersecting) { return true; } hfShape.getConvexTrianglePillar(i, j, true); Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset2); if (convexPos.distanceTo(worldPillarOffset2) < hfShape.pillarConvex.boundingSphereRadius + convexShape.boundingSphereRadius) { intersecting = this.convexConvex(convexShape, hfShape.pillarConvex, convexPos, worldPillarOffset2, convexQuat, hfQuat, convexBody, hfBody, null, null, justTest, faceList, null); } if (justTest && intersecting) { return true; } } } } sphereParticle(sj, si, xj, xi, qj, qi, bj, bi, rsi, rsj, justTest) { const normal = particleSphere_normal; normal.set(0, 0, 1); xi.vsub(xj, normal); const lengthSquared = normal.lengthSquared(); if (lengthSquared <= sj.radius * sj.radius) { if (justTest) { return true; } const r = this.createContactEquation(bi, bj, si, sj, rsi, rsj); normal.normalize(); r.rj.copy(normal); r.rj.scale(sj.radius, r.rj); r.ni.copy(normal); r.ni.negate(r.ni); r.ri.set(0, 0, 0); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); } } planeParticle(sj, si, xj, xi, qj, qi, bj, bi, rsi, rsj, justTest) { const normal = particlePlane_normal; normal.set(0, 0, 1); bj.quaternion.vmult(normal, normal); const relpos2 = particlePlane_relpos; xi.vsub(bj.position, relpos2); const dot = normal.dot(relpos2); if (dot <= 0) { if (justTest) { return true; } const r = this.createContactEquation(bi, bj, si, sj, rsi, rsj); r.ni.copy(normal); r.ni.negate(r.ni); r.ri.set(0, 0, 0); const projected = particlePlane_projected; normal.scale(normal.dot(xi), projected); xi.vsub(projected, projected); r.rj.copy(projected); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); } } boxParticle(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest) { si.convexPolyhedronRepresentation.material = si.material; si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse; return this.convexParticle(si.convexPolyhedronRepresentation, sj, xi, xj, qi, qj, bi, bj, si, sj, justTest); } convexParticle(sj, si, xj, xi, qj, qi, bj, bi, rsi, rsj, justTest) { let penetratedFaceIndex = -1; const penetratedFaceNormal = convexParticle_penetratedFaceNormal; const worldPenetrationVec = convexParticle_worldPenetrationVec; let minPenetration = null; const local = convexParticle_local; local.copy(xi); local.vsub(xj, local); qj.conjugate(cqj); cqj.vmult(local, local); if (sj.pointIsInside(local)) { if (sj.worldVerticesNeedsUpdate) { sj.computeWorldVertices(xj, qj); } if (sj.worldFaceNormalsNeedsUpdate) { sj.computeWorldFaceNormals(qj); } for (let i = 0, nfaces = sj.faces.length; i !== nfaces; i++) { const verts = [sj.worldVertices[sj.faces[i][0]]]; const normal = sj.worldFaceNormals[i]; xi.vsub(verts[0], convexParticle_vertexToParticle); const penetration = -normal.dot(convexParticle_vertexToParticle); if (minPenetration === null || Math.abs(penetration) < Math.abs(minPenetration)) { if (justTest) { return true; } minPenetration = penetration; penetratedFaceIndex = i; penetratedFaceNormal.copy(normal); } } if (penetratedFaceIndex !== -1) { const r = this.createContactEquation(bi, bj, si, sj, rsi, rsj); penetratedFaceNormal.scale(minPenetration, worldPenetrationVec); worldPenetrationVec.vadd(xi, worldPenetrationVec); worldPenetrationVec.vsub(xj, worldPenetrationVec); r.rj.copy(worldPenetrationVec); penetratedFaceNormal.negate(r.ni); r.ri.set(0, 0, 0); const ri = r.ri; const rj = r.rj; ri.vadd(xi, ri); ri.vsub(bi.position, ri); rj.vadd(xj, rj); rj.vsub(bj.position, rj); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); } else { console.warn("Point found inside convex, but did not find penetrating face!"); } } } heightfieldCylinder(hfShape, convexShape, hfPos, convexPos, hfQuat, convexQuat, hfBody, convexBody, rsi, rsj, justTest) { return this.convexHeightfield(convexShape, hfShape, convexPos, hfPos, convexQuat, hfQuat, convexBody, hfBody, rsi, rsj, justTest); } particleCylinder(si, sj, xi, xj, qi, qj, bi, bj, rsi, rsj, justTest) { return this.convexParticle(sj, si, xj, xi, qj, qi, bj, bi, rsi, rsj, justTest); } sphereTrimesh(sphereShape, trimeshShape, spherePos, trimeshPos, sphereQuat, trimeshQuat, sphereBody, trimeshBody, rsi, rsj, justTest) { const edgeVertexA = sphereTrimesh_edgeVertexA; const edgeVertexB = sphereTrimesh_edgeVertexB; const edgeVector = sphereTrimesh_edgeVector; const edgeVectorUnit = sphereTrimesh_edgeVectorUnit; const localSpherePos = sphereTrimesh_localSpherePos; const tmp3 = sphereTrimesh_tmp; const localSphereAABB = sphereTrimesh_localSphereAABB; const v22 = sphereTrimesh_v2; const relpos2 = sphereTrimesh_relpos; const triangles = sphereTrimesh_triangles; Transform.pointToLocalFrame(trimeshPos, trimeshQuat, spherePos, localSpherePos); const sphereRadius = sphereShape.radius; localSphereAABB.lowerBound.set(localSpherePos.x - sphereRadius, localSpherePos.y - sphereRadius, localSpherePos.z - sphereRadius); localSphereAABB.upperBound.set(localSpherePos.x + sphereRadius, localSpherePos.y + sphereRadius, localSpherePos.z + sphereRadius); trimeshShape.getTrianglesInAABB(localSphereAABB, triangles); const v = sphereTrimesh_v; const radiusSquared = sphereShape.radius * sphereShape.radius; for (let i = 0; i < triangles.length; i++) { for (let j = 0; j < 3; j++) { trimeshShape.getVertex(trimeshShape.indices[triangles[i] * 3 + j], v); v.vsub(localSpherePos, relpos2); if (relpos2.lengthSquared() <= radiusSquared) { v22.copy(v); Transform.pointToWorldFrame(trimeshPos, trimeshQuat, v22, v); v.vsub(spherePos, relpos2); if (justTest) { return true; } let r = this.createContactEquation(sphereBody, trimeshBody, sphereShape, trimeshShape, rsi, rsj); r.ni.copy(relpos2); r.ni.normalize(); r.ri.copy(r.ni); r.ri.scale(sphereShape.radius, r.ri); r.ri.vadd(spherePos, r.ri); r.ri.vsub(sphereBody.position, r.ri); r.rj.copy(v); r.rj.vsub(trimeshBody.position, r.rj); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); } } } for (let i = 0; i < triangles.length; i++) { for (let j = 0; j < 3; j++) { trimeshShape.getVertex(trimeshShape.indices[triangles[i] * 3 + j], edgeVertexA); trimeshShape.getVertex(trimeshShape.indices[triangles[i] * 3 + (j + 1) % 3], edgeVertexB); edgeVertexB.vsub(edgeVertexA, edgeVector); localSpherePos.vsub(edgeVertexB, tmp3); const positionAlongEdgeB = tmp3.dot(edgeVector); localSpherePos.vsub(edgeVertexA, tmp3); let positionAlongEdgeA = tmp3.dot(edgeVector); if (positionAlongEdgeA > 0 && positionAlongEdgeB < 0) { localSpherePos.vsub(edgeVertexA, tmp3); edgeVectorUnit.copy(edgeVector); edgeVectorUnit.normalize(); positionAlongEdgeA = tmp3.dot(edgeVectorUnit); edgeVectorUnit.scale(positionAlongEdgeA, tmp3); tmp3.vadd(edgeVertexA, tmp3); const dist = tmp3.distanceTo(localSpherePos); if (dist < sphereShape.radius) { if (justTest) { return true; } const r = this.createContactEquation(sphereBody, trimeshBody, sphereShape, trimeshShape, rsi, rsj); tmp3.vsub(localSpherePos, r.ni); r.ni.normalize(); r.ni.scale(sphereShape.radius, r.ri); r.ri.vadd(spherePos, r.ri); r.ri.vsub(sphereBody.position, r.ri); Transform.pointToWorldFrame(trimeshPos, trimeshQuat, tmp3, tmp3); tmp3.vsub(trimeshBody.position, r.rj); Transform.vectorToWorldFrame(trimeshQuat, r.ni, r.ni); Transform.vectorToWorldFrame(trimeshQuat, r.ri, r.ri); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); } } } } const va2 = sphereTrimesh_va; const vb2 = sphereTrimesh_vb; const vc2 = sphereTrimesh_vc; const normal = sphereTrimesh_normal; for (let i = 0, N = triangles.length; i !== N; i++) { trimeshShape.getTriangleVertices(triangles[i], va2, vb2, vc2); trimeshShape.getNormal(triangles[i], normal); localSpherePos.vsub(va2, tmp3); let dist = tmp3.dot(normal); normal.scale(dist, tmp3); localSpherePos.vsub(tmp3, tmp3); dist = tmp3.distanceTo(localSpherePos); if (Ray2.pointInTriangle(tmp3, va2, vb2, vc2) && dist < sphereShape.radius) { if (justTest) { return true; } let r = this.createContactEquation(sphereBody, trimeshBody, sphereShape, trimeshShape, rsi, rsj); tmp3.vsub(localSpherePos, r.ni); r.ni.normalize(); r.ni.scale(sphereShape.radius, r.ri); r.ri.vadd(spherePos, r.ri); r.ri.vsub(sphereBody.position, r.ri); Transform.pointToWorldFrame(trimeshPos, trimeshQuat, tmp3, tmp3); tmp3.vsub(trimeshBody.position, r.rj); Transform.vectorToWorldFrame(trimeshQuat, r.ni, r.ni); Transform.vectorToWorldFrame(trimeshQuat, r.ri, r.ri); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); } } triangles.length = 0; } planeTrimesh(planeShape, trimeshShape, planePos, trimeshPos, planeQuat, trimeshQuat, planeBody, trimeshBody, rsi, rsj, justTest) { const v = new Vec3(); const normal = planeTrimesh_normal; normal.set(0, 0, 1); planeQuat.vmult(normal, normal); for (let i = 0; i < trimeshShape.vertices.length / 3; i++) { trimeshShape.getVertex(i, v); const v22 = new Vec3(); v22.copy(v); Transform.pointToWorldFrame(trimeshPos, trimeshQuat, v22, v); const relpos2 = planeTrimesh_relpos; v.vsub(planePos, relpos2); const dot = normal.dot(relpos2); if (dot <= 0) { if (justTest) { return true; } const r = this.createContactEquation(planeBody, trimeshBody, planeShape, trimeshShape, rsi, rsj); r.ni.copy(normal); const projected = planeTrimesh_projected; normal.scale(relpos2.dot(normal), projected); v.vsub(projected, projected); r.ri.copy(projected); r.ri.vsub(planeBody.position, r.ri); r.rj.copy(v); r.rj.vsub(trimeshBody.position, r.rj); this.result.push(r); this.createFrictionEquationsFromContact(r, this.frictionResult); } } } }; var averageNormal = new Vec3(); var averageContactPointA = new Vec3(); var averageContactPointB = new Vec3(); var tmpVec1 = new Vec3(); var tmpVec2 = new Vec3(); var tmpQuat1 = new Quaternion2(); var tmpQuat2 = new Quaternion2(); var planeTrimesh_normal = new Vec3(); var planeTrimesh_relpos = new Vec3(); var planeTrimesh_projected = new Vec3(); var sphereTrimesh_normal = new Vec3(); var sphereTrimesh_relpos = new Vec3(); var sphereTrimesh_v = new Vec3(); var sphereTrimesh_v2 = new Vec3(); var sphereTrimesh_edgeVertexA = new Vec3(); var sphereTrimesh_edgeVertexB = new Vec3(); var sphereTrimesh_edgeVector = new Vec3(); var sphereTrimesh_edgeVectorUnit = new Vec3(); var sphereTrimesh_localSpherePos = new Vec3(); var sphereTrimesh_tmp = new Vec3(); var sphereTrimesh_va = new Vec3(); var sphereTrimesh_vb = new Vec3(); var sphereTrimesh_vc = new Vec3(); var sphereTrimesh_localSphereAABB = new AABB(); var sphereTrimesh_triangles = []; var point_on_plane_to_sphere = new Vec3(); var plane_to_sphere_ortho = new Vec3(); var pointInPolygon_edge = new Vec3(); var pointInPolygon_edge_x_normal = new Vec3(); var pointInPolygon_vtp = new Vec3(); function pointInPolygon(verts, normal, p2) { let positiveResult = null; const N = verts.length; for (let i = 0; i !== N; i++) { const v = verts[i]; const edge = pointInPolygon_edge; verts[(i + 1) % N].vsub(v, edge); const edge_x_normal = pointInPolygon_edge_x_normal; edge.cross(normal, edge_x_normal); const vertex_to_p = pointInPolygon_vtp; p2.vsub(v, vertex_to_p); const r = edge_x_normal.dot(vertex_to_p); if (positiveResult === null || r > 0 && positiveResult === true || r <= 0 && positiveResult === false) { if (positiveResult === null) { positiveResult = r > 0; } continue; } else { return false; } } return true; } var box_to_sphere = new Vec3(); var sphereBox_ns = new Vec3(); var sphereBox_ns1 = new Vec3(); var sphereBox_ns2 = new Vec3(); var sphereBox_sides = [new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3(), new Vec3()]; var sphereBox_sphere_to_corner = new Vec3(); var sphereBox_side_ns = new Vec3(); var sphereBox_side_ns1 = new Vec3(); var sphereBox_side_ns2 = new Vec3(); var convex_to_sphere = new Vec3(); var sphereConvex_edge = new Vec3(); var sphereConvex_edgeUnit = new Vec3(); var sphereConvex_sphereToCorner = new Vec3(); var sphereConvex_worldCorner = new Vec3(); var sphereConvex_worldNormal = new Vec3(); var sphereConvex_worldPoint = new Vec3(); var sphereConvex_worldSpherePointClosestToPlane = new Vec3(); var sphereConvex_penetrationVec = new Vec3(); var sphereConvex_sphereToWorldPoint = new Vec3(); var planeConvex_v = new Vec3(); var planeConvex_normal = new Vec3(); var planeConvex_relpos = new Vec3(); var planeConvex_projected = new Vec3(); var convexConvex_sepAxis = new Vec3(); var convexConvex_q = new Vec3(); var particlePlane_normal = new Vec3(); var particlePlane_relpos = new Vec3(); var particlePlane_projected = new Vec3(); var particleSphere_normal = new Vec3(); var cqj = new Quaternion2(); var convexParticle_local = new Vec3(); var convexParticle_penetratedFaceNormal = new Vec3(); var convexParticle_vertexToParticle = new Vec3(); var convexParticle_worldPenetrationVec = new Vec3(); var convexHeightfield_tmp1 = new Vec3(); var convexHeightfield_tmp2 = new Vec3(); var convexHeightfield_faceList = [0]; var sphereHeightfield_tmp1 = new Vec3(); var sphereHeightfield_tmp2 = new Vec3(); var OverlapKeeper = class { constructor() { this.current = void 0; this.previous = void 0; this.current = []; this.previous = []; } getKey(i, j) { if (j < i) { const temp = j; j = i; i = temp; } return i << 16 | j; } set(i, j) { const key = this.getKey(i, j); const current = this.current; let index = 0; while (key > current[index]) { index++; } if (key === current[index]) { return; } for (let j2 = current.length - 1; j2 >= index; j2--) { current[j2 + 1] = current[j2]; } current[index] = key; } tick() { const tmp3 = this.current; this.current = this.previous; this.previous = tmp3; this.current.length = 0; } getDiff(additions2, removals2) { const a2 = this.current; const b2 = this.previous; const al = a2.length; const bl = b2.length; let j = 0; for (let i = 0; i < al; i++) { let found = false; const keyA = a2[i]; while (keyA > b2[j]) { j++; } found = keyA === b2[j]; if (!found) { unpackAndPush(additions2, keyA); } } j = 0; for (let i = 0; i < bl; i++) { let found = false; const keyB = b2[i]; while (keyB > a2[j]) { j++; } found = a2[j] === keyB; if (!found) { unpackAndPush(removals2, keyB); } } } }; function unpackAndPush(array, key) { array.push((key & 4294901760) >> 16, key & 65535); } var TupleDictionary = class { constructor() { this.data = { keys: [] }; } get(i, j) { if (i > j) { const temp = j; j = i; i = temp; } return this.data[i + "-" + j]; } set(i, j, value) { if (i > j) { const temp = j; j = i; i = temp; } const key = i + "-" + j; if (!this.get(i, j)) { this.data.keys.push(key); } this.data[key] = value; } reset() { const data = this.data; const keys = data.keys; while (keys.length > 0) { const key = keys.pop(); delete data[key]; } } }; var World = class extends EventTarget { constructor(options = {}) { super(); this.dt = void 0; this.allowSleep = void 0; this.contacts = void 0; this.frictionEquations = void 0; this.quatNormalizeSkip = void 0; this.quatNormalizeFast = void 0; this.time = void 0; this.stepnumber = void 0; this.default_dt = void 0; this.nextId = void 0; this.gravity = void 0; this.broadphase = void 0; this.bodies = void 0; this.hasActiveBodies = void 0; this.solver = void 0; this.constraints = void 0; this.narrowphase = void 0; this.collisionMatrix = void 0; this.collisionMatrixPrevious = void 0; this.bodyOverlapKeeper = void 0; this.shapeOverlapKeeper = void 0; this.materials = void 0; this.contactmaterials = void 0; this.contactMaterialTable = void 0; this.defaultMaterial = void 0; this.defaultContactMaterial = void 0; this.doProfiling = void 0; this.profile = void 0; this.accumulator = void 0; this.subsystems = void 0; this.addBodyEvent = void 0; this.removeBodyEvent = void 0; this.idToBodyMap = void 0; this.dt = -1; this.allowSleep = !!options.allowSleep; this.contacts = []; this.frictionEquations = []; this.quatNormalizeSkip = options.quatNormalizeSkip !== void 0 ? options.quatNormalizeSkip : 0; this.quatNormalizeFast = options.quatNormalizeFast !== void 0 ? options.quatNormalizeFast : false; this.time = 0; this.stepnumber = 0; this.default_dt = 1 / 60; this.nextId = 0; this.gravity = new Vec3(); if (options.gravity) { this.gravity.copy(options.gravity); } this.broadphase = options.broadphase !== void 0 ? options.broadphase : new NaiveBroadphase(); this.bodies = []; this.hasActiveBodies = false; this.solver = options.solver !== void 0 ? options.solver : new GSSolver(); this.constraints = []; this.narrowphase = new Narrowphase(this); this.collisionMatrix = new ArrayCollisionMatrix(); this.collisionMatrixPrevious = new ArrayCollisionMatrix(); this.bodyOverlapKeeper = new OverlapKeeper(); this.shapeOverlapKeeper = new OverlapKeeper(); this.materials = []; this.contactmaterials = []; this.contactMaterialTable = new TupleDictionary(); this.defaultMaterial = new Material2("default"); this.defaultContactMaterial = new ContactMaterial(this.defaultMaterial, this.defaultMaterial, { friction: 0.3, restitution: 0 }); this.doProfiling = false; this.profile = { solve: 0, makeContactConstraints: 0, broadphase: 0, integrate: 0, narrowphase: 0 }; this.accumulator = 0; this.subsystems = []; this.addBodyEvent = { type: "addBody", body: null }; this.removeBodyEvent = { type: "removeBody", body: null }; this.idToBodyMap = {}; this.broadphase.setWorld(this); } getContactMaterial(m1, m2) { return this.contactMaterialTable.get(m1.id, m2.id); } numObjects() { return this.bodies.length; } collisionMatrixTick() { const temp = this.collisionMatrixPrevious; this.collisionMatrixPrevious = this.collisionMatrix; this.collisionMatrix = temp; this.collisionMatrix.reset(); this.bodyOverlapKeeper.tick(); this.shapeOverlapKeeper.tick(); } addConstraint(c2) { this.constraints.push(c2); } removeConstraint(c2) { const idx = this.constraints.indexOf(c2); if (idx !== -1) { this.constraints.splice(idx, 1); } } rayTest(from, to, result) { if (result instanceof RaycastResult) { this.raycastClosest(from, to, { skipBackfaces: true }, result); } else { this.raycastAll(from, to, { skipBackfaces: true }, result); } } raycastAll(from, to, options = {}, callback) { options.mode = Ray2.ALL; options.from = from; options.to = to; options.callback = callback; return tmpRay.intersectWorld(this, options); } raycastAny(from, to, options = {}, result) { options.mode = Ray2.ANY; options.from = from; options.to = to; options.result = result; return tmpRay.intersectWorld(this, options); } raycastClosest(from, to, options = {}, result) { options.mode = Ray2.CLOSEST; options.from = from; options.to = to; options.result = result; return tmpRay.intersectWorld(this, options); } addBody(body) { if (this.bodies.includes(body)) { return; } body.index = this.bodies.length; this.bodies.push(body); body.world = this; body.initPosition.copy(body.position); body.initVelocity.copy(body.velocity); body.timeLastSleepy = this.time; if (body instanceof Body) { body.initAngularVelocity.copy(body.angularVelocity); body.initQuaternion.copy(body.quaternion); } this.collisionMatrix.setNumObjects(this.bodies.length); this.addBodyEvent.body = body; this.idToBodyMap[body.id] = body; this.dispatchEvent(this.addBodyEvent); } removeBody(body) { body.world = null; const n = this.bodies.length - 1; const bodies = this.bodies; const idx = bodies.indexOf(body); if (idx !== -1) { bodies.splice(idx, 1); for (let i = 0; i !== bodies.length; i++) { bodies[i].index = i; } this.collisionMatrix.setNumObjects(n); this.removeBodyEvent.body = body; delete this.idToBodyMap[body.id]; this.dispatchEvent(this.removeBodyEvent); } } getBodyById(id) { return this.idToBodyMap[id]; } getShapeById(id) { const bodies = this.bodies; for (let i = 0; i < bodies.length; i++) { const shapes = bodies[i].shapes; for (let j = 0; j < shapes.length; j++) { const shape = shapes[j]; if (shape.id === id) { return shape; } } } return null; } addMaterial(m) { this.materials.push(m); } addContactMaterial(cmat) { this.contactmaterials.push(cmat); this.contactMaterialTable.set(cmat.materials[0].id, cmat.materials[1].id, cmat); } step(dt, timeSinceLastCalled, maxSubSteps = 10) { if (timeSinceLastCalled === void 0) { this.internalStep(dt); this.time += dt; } else { this.accumulator += timeSinceLastCalled; const t0 = performance2.now(); let substeps = 0; while (this.accumulator >= dt && substeps < maxSubSteps) { this.internalStep(dt); this.accumulator -= dt; substeps++; if (performance2.now() - t0 > dt * 1e3) { break; } } this.accumulator = this.accumulator % dt; const t = this.accumulator / dt; for (let j = 0; j !== this.bodies.length; j++) { const b2 = this.bodies[j]; b2.previousPosition.lerp(b2.position, t, b2.interpolatedPosition); b2.previousQuaternion.slerp(b2.quaternion, t, b2.interpolatedQuaternion); b2.previousQuaternion.normalize(); } this.time += timeSinceLastCalled; } } internalStep(dt) { this.dt = dt; const contacts = this.contacts; const p1 = World_step_p1; const p2 = World_step_p2; const N = this.numObjects(); const bodies = this.bodies; const solver = this.solver; const gravity = this.gravity; const doProfiling = this.doProfiling; const profile = this.profile; const DYNAMIC = Body.DYNAMIC; let profilingStart = -Infinity; const constraints = this.constraints; const frictionEquationPool = World_step_frictionEquationPool; gravity.length(); const gx = gravity.x; const gy = gravity.y; const gz = gravity.z; let i = 0; if (doProfiling) { profilingStart = performance2.now(); } for (i = 0; i !== N; i++) { const bi = bodies[i]; if (bi.type === DYNAMIC) { const f = bi.force; const m = bi.mass; f.x += m * gx; f.y += m * gy; f.z += m * gz; } } for (let i2 = 0, Nsubsystems = this.subsystems.length; i2 !== Nsubsystems; i2++) { this.subsystems[i2].update(); } if (doProfiling) { profilingStart = performance2.now(); } p1.length = 0; p2.length = 0; this.broadphase.collisionPairs(this, p1, p2); if (doProfiling) { profile.broadphase = performance2.now() - profilingStart; } let Nconstraints = constraints.length; for (i = 0; i !== Nconstraints; i++) { const c2 = constraints[i]; if (!c2.collideConnected) { for (let j = p1.length - 1; j >= 0; j -= 1) { if (c2.bodyA === p1[j] && c2.bodyB === p2[j] || c2.bodyB === p1[j] && c2.bodyA === p2[j]) { p1.splice(j, 1); p2.splice(j, 1); } } } } this.collisionMatrixTick(); if (doProfiling) { profilingStart = performance2.now(); } const oldcontacts = World_step_oldContacts; const NoldContacts = contacts.length; for (i = 0; i !== NoldContacts; i++) { oldcontacts.push(contacts[i]); } contacts.length = 0; const NoldFrictionEquations = this.frictionEquations.length; for (i = 0; i !== NoldFrictionEquations; i++) { frictionEquationPool.push(this.frictionEquations[i]); } this.frictionEquations.length = 0; this.narrowphase.getContacts(p1, p2, this, contacts, oldcontacts, this.frictionEquations, frictionEquationPool); if (doProfiling) { profile.narrowphase = performance2.now() - profilingStart; } if (doProfiling) { profilingStart = performance2.now(); } for (i = 0; i < this.frictionEquations.length; i++) { solver.addEquation(this.frictionEquations[i]); } const ncontacts = contacts.length; for (let k = 0; k !== ncontacts; k++) { const c2 = contacts[k]; const bi = c2.bi; const bj = c2.bj; const si = c2.si; const sj = c2.sj; let cm; if (bi.material && bj.material) { cm = this.getContactMaterial(bi.material, bj.material) || this.defaultContactMaterial; } else { cm = this.defaultContactMaterial; } cm.friction; if (bi.material && bj.material) { if (bi.material.friction >= 0 && bj.material.friction >= 0) { bi.material.friction * bj.material.friction; } if (bi.material.restitution >= 0 && bj.material.restitution >= 0) { c2.restitution = bi.material.restitution * bj.material.restitution; } } solver.addEquation(c2); if (bi.allowSleep && bi.type === Body.DYNAMIC && bi.sleepState === Body.SLEEPING && bj.sleepState === Body.AWAKE && bj.type !== Body.STATIC) { const speedSquaredB = bj.velocity.lengthSquared() + bj.angularVelocity.lengthSquared(); const speedLimitSquaredB = bj.sleepSpeedLimit ** 2; if (speedSquaredB >= speedLimitSquaredB * 2) { bi.wakeUpAfterNarrowphase = true; } } if (bj.allowSleep && bj.type === Body.DYNAMIC && bj.sleepState === Body.SLEEPING && bi.sleepState === Body.AWAKE && bi.type !== Body.STATIC) { const speedSquaredA = bi.velocity.lengthSquared() + bi.angularVelocity.lengthSquared(); const speedLimitSquaredA = bi.sleepSpeedLimit ** 2; if (speedSquaredA >= speedLimitSquaredA * 2) { bj.wakeUpAfterNarrowphase = true; } } this.collisionMatrix.set(bi, bj, true); if (!this.collisionMatrixPrevious.get(bi, bj)) { World_step_collideEvent.body = bj; World_step_collideEvent.contact = c2; bi.dispatchEvent(World_step_collideEvent); World_step_collideEvent.body = bi; bj.dispatchEvent(World_step_collideEvent); } this.bodyOverlapKeeper.set(bi.id, bj.id); this.shapeOverlapKeeper.set(si.id, sj.id); } this.emitContactEvents(); if (doProfiling) { profile.makeContactConstraints = performance2.now() - profilingStart; profilingStart = performance2.now(); } for (i = 0; i !== N; i++) { const bi = bodies[i]; if (bi.wakeUpAfterNarrowphase) { bi.wakeUp(); bi.wakeUpAfterNarrowphase = false; } } Nconstraints = constraints.length; for (i = 0; i !== Nconstraints; i++) { const c2 = constraints[i]; c2.update(); for (let j = 0, Neq = c2.equations.length; j !== Neq; j++) { const eq = c2.equations[j]; solver.addEquation(eq); } } solver.solve(dt, this); if (doProfiling) { profile.solve = performance2.now() - profilingStart; } solver.removeAllEquations(); const pow = Math.pow; for (i = 0; i !== N; i++) { const bi = bodies[i]; if (bi.type & DYNAMIC) { const ld = pow(1 - bi.linearDamping, dt); const v = bi.velocity; v.scale(ld, v); const av = bi.angularVelocity; if (av) { const ad = pow(1 - bi.angularDamping, dt); av.scale(ad, av); } } } this.dispatchEvent(World_step_preStepEvent); for (i = 0; i !== N; i++) { const bi = bodies[i]; if (bi.preStep) { bi.preStep.call(bi); } } if (doProfiling) { profilingStart = performance2.now(); } const stepnumber = this.stepnumber; const quatNormalize = stepnumber % (this.quatNormalizeSkip + 1) === 0; const quatNormalizeFast = this.quatNormalizeFast; for (i = 0; i !== N; i++) { bodies[i].integrate(dt, quatNormalize, quatNormalizeFast); } this.clearForces(); this.broadphase.dirty = true; if (doProfiling) { profile.integrate = performance2.now() - profilingStart; } this.stepnumber += 1; this.dispatchEvent(World_step_postStepEvent); for (i = 0; i !== N; i++) { const bi = bodies[i]; const postStep = bi.postStep; if (postStep) { postStep.call(bi); } } let hasActiveBodies = true; if (this.allowSleep) { hasActiveBodies = false; for (i = 0; i !== N; i++) { const bi = bodies[i]; bi.sleepTick(this.time); if (bi.sleepState !== Body.SLEEPING) { hasActiveBodies = true; } } } this.hasActiveBodies = hasActiveBodies; } emitContactEvents() { const hasBeginContact = this.hasAnyEventListener("beginContact"); const hasEndContact = this.hasAnyEventListener("endContact"); if (hasBeginContact || hasEndContact) { this.bodyOverlapKeeper.getDiff(additions, removals); } if (hasBeginContact) { for (let i = 0, l = additions.length; i < l; i += 2) { beginContactEvent.bodyA = this.getBodyById(additions[i]); beginContactEvent.bodyB = this.getBodyById(additions[i + 1]); this.dispatchEvent(beginContactEvent); } beginContactEvent.bodyA = beginContactEvent.bodyB = null; } if (hasEndContact) { for (let i = 0, l = removals.length; i < l; i += 2) { endContactEvent.bodyA = this.getBodyById(removals[i]); endContactEvent.bodyB = this.getBodyById(removals[i + 1]); this.dispatchEvent(endContactEvent); } endContactEvent.bodyA = endContactEvent.bodyB = null; } additions.length = removals.length = 0; const hasBeginShapeContact = this.hasAnyEventListener("beginShapeContact"); const hasEndShapeContact = this.hasAnyEventListener("endShapeContact"); if (hasBeginShapeContact || hasEndShapeContact) { this.shapeOverlapKeeper.getDiff(additions, removals); } if (hasBeginShapeContact) { for (let i = 0, l = additions.length; i < l; i += 2) { const shapeA = this.getShapeById(additions[i]); const shapeB = this.getShapeById(additions[i + 1]); beginShapeContactEvent.shapeA = shapeA; beginShapeContactEvent.shapeB = shapeB; if (shapeA) beginShapeContactEvent.bodyA = shapeA.body; if (shapeB) beginShapeContactEvent.bodyB = shapeB.body; this.dispatchEvent(beginShapeContactEvent); } beginShapeContactEvent.bodyA = beginShapeContactEvent.bodyB = beginShapeContactEvent.shapeA = beginShapeContactEvent.shapeB = null; } if (hasEndShapeContact) { for (let i = 0, l = removals.length; i < l; i += 2) { const shapeA = this.getShapeById(removals[i]); const shapeB = this.getShapeById(removals[i + 1]); endShapeContactEvent.shapeA = shapeA; endShapeContactEvent.shapeB = shapeB; if (shapeA) endShapeContactEvent.bodyA = shapeA.body; if (shapeB) endShapeContactEvent.bodyB = shapeB.body; this.dispatchEvent(endShapeContactEvent); } endShapeContactEvent.bodyA = endShapeContactEvent.bodyB = endShapeContactEvent.shapeA = endShapeContactEvent.shapeB = null; } } clearForces() { const bodies = this.bodies; const N = bodies.length; for (let i = 0; i !== N; i++) { const b2 = bodies[i]; b2.force; b2.torque; b2.force.set(0, 0, 0); b2.torque.set(0, 0, 0); } } }; new AABB(); var tmpRay = new Ray2(); var performance2 = globalThis.performance || {}; if (!performance2.now) { let nowOffset = Date.now(); if (performance2.timing && performance2.timing.navigationStart) { nowOffset = performance2.timing.navigationStart; } performance2.now = () => Date.now() - nowOffset; } var World_step_postStepEvent = { type: "postStep" }; var World_step_preStepEvent = { type: "preStep" }; var World_step_collideEvent = { type: Body.COLLIDE_EVENT_NAME, body: null, contact: null }; var World_step_oldContacts = []; var World_step_frictionEquationPool = []; var World_step_p1 = []; var World_step_p2 = []; var additions = []; var removals = []; var beginContactEvent = { type: "beginContact", bodyA: null, bodyB: null }; var endContactEvent = { type: "endContact", bodyA: null, bodyB: null }; var beginShapeContactEvent = { type: "beginShapeContact", bodyA: null, bodyB: null, shapeA: null, shapeB: null }; var endShapeContactEvent = { type: "endShapeContact", bodyA: null, bodyB: null, shapeA: null, shapeB: null }; // src/view/renderer/geometries.ts var MATERIAL_OPTIONS = { specular: 1515554, color: 15790320, shininess: 60, flatShading: true }; var DEFAULT_DICE_OPTIONS = { diceColor: "#202020", textColor: "#ffffff" }; var DiceShape = class { constructor(w2, h, options = { diceColor: "#202020", textColor: "#aaaaaa" }) { this.w = w2; this.h = h; this.options = options; this.scale = 50; this.labels = [ " ", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" ]; this.options = __spreadValues(__spreadValues({}, DEFAULT_DICE_OPTIONS), options); } setColor({ diceColor, textColor }) { this.options.diceColor = diceColor; this.options.textColor = textColor; } get radius() { return this.scale * this.scaleFactor; } get diceColor() { return this.options.diceColor; } get textColor() { return this.options.textColor; } get buffer() { return this.geometry.geometry; } create() { this.geometry = new Mesh(this.getGeometry(), this.getMaterials()); this.geometry.receiveShadow = true; this.geometry.castShadow = true; this.body.position.set(0 + this.radius * 2 * Math.random(), 0 + this.radius * 2 * Math.random(), 0 + this.radius * 4); this.body.velocity.x = 500 * Math.random() * 2 - 1; this.body.velocity.y = 500 * Math.random() * 2 - 1; this.body.angularVelocity.x = 100 * Math.random(); this.body.angularVelocity.y = 100 * Math.random(); } getGeometry() { let vectors = new Array(this.vertices.length); for (let i = 0; i < this.vertices.length; ++i) { vectors[i] = new Vector3().fromArray(this.vertices[i]).normalize(); } this.chamferGeometry = this.getChamferGeometry(vectors); let geometry = this.makeGeometry(this.chamferGeometry.vectors, this.chamferGeometry.faces); this.shape = this.makeShape(vectors); this.body = new Body({ mass: this.mass, shape: this.shape }); return geometry; } makeShape(vertices) { let cv = new Array(vertices.length), cf = new Array(this.faces.length); for (let i = 0; i < vertices.length; ++i) { let v = vertices[i]; cv[i] = new Vec3(v.x * this.radius, v.y * this.radius, v.z * this.radius); } for (let i = 0; i < this.faces.length; ++i) { cf[i] = this.faces[i].slice(0, this.faces[i].length - 1); } this.shapeData = { vertices: cv, faces: cf }; return new ConvexPolyhedron({ vertices: cv, faces: cf }); } getChamferGeometry(vectors) { let chamfer_vectors = [], chamfer_faces = [], corner_faces = new Array(vectors.length); for (let i = 0; i < vectors.length; ++i) corner_faces[i] = []; for (let i = 0; i < this.faces.length; ++i) { let ii = this.faces[i], fl = ii.length - 1; let center_point = new Vector3(); let face = new Array(fl); for (let j = 0; j < fl; ++j) { let vv = vectors[ii[j]].clone(); center_point.add(vv); corner_faces[ii[j]].push(face[j] = chamfer_vectors.push(vv) - 1); } center_point.divideScalar(fl); for (let j = 0; j < fl; ++j) { let vv = chamfer_vectors[face[j]]; vv.subVectors(vv, center_point).multiplyScalar(this.chamfer).addVectors(vv, center_point); } face.push(ii[fl]); chamfer_faces.push(face); } for (let i = 0; i < this.faces.length - 1; ++i) { for (let j = i + 1; j < this.faces.length; ++j) { let pairs = [], lastm = -1; for (let m = 0; m < this.faces[i].length - 1; ++m) { let n = this.faces[j].indexOf(this.faces[i][m]); if (n >= 0 && n < this.faces[j].length - 1) { if (lastm >= 0 && m !== lastm + 1) pairs.unshift([i, m], [j, n]); else pairs.push([i, m], [j, n]); lastm = m; } } if (pairs.length !== 4) continue; chamfer_faces.push([ chamfer_faces[pairs[0][0]][pairs[0][1]], chamfer_faces[pairs[1][0]][pairs[1][1]], chamfer_faces[pairs[3][0]][pairs[3][1]], chamfer_faces[pairs[2][0]][pairs[2][1]], -1 ]); } } for (let i = 0; i < corner_faces.length; ++i) { let cf = corner_faces[i], face = [cf[0]], count = cf.length - 1; while (count) { for (let m = this.faces.length; m < chamfer_faces.length; ++m) { let index = chamfer_faces[m].indexOf(face[face.length - 1]); if (index >= 0 && index < 4) { if (--index === -1) index = 3; let next_vertex = chamfer_faces[m][index]; if (cf.indexOf(next_vertex) >= 0) { face.push(next_vertex); break; } } } --count; } face.push(-1); chamfer_faces.push(face); } return { vectors: chamfer_vectors, faces: chamfer_faces }; } makeGeometry(vertices, faces) { let geom = new BufferGeometry(); for (let i = 0; i < vertices.length; ++i) { vertices[i] = vertices[i].multiplyScalar(this.radius); } let positions = []; const normals = []; const uvs = []; const cb2 = new Vector3(); const ab2 = new Vector3(); let materialIndex; let faceFirstVertexIndex = 0; for (let i = 0; i < faces.length; ++i) { let ii = faces[i], fl = ii.length - 1; let aa = Math.PI * 2 / fl; materialIndex = ii[fl] + 1; for (let j = 0; j < fl - 2; ++j) { positions.push(...vertices[ii[0]].toArray()); positions.push(...vertices[ii[j + 1]].toArray()); positions.push(...vertices[ii[j + 2]].toArray()); cb2.subVectors(vertices[ii[j + 2]], vertices[ii[j + 1]]); ab2.subVectors(vertices[ii[0]], vertices[ii[j + 1]]); cb2.cross(ab2); cb2.normalize(); normals.push(...cb2.toArray()); normals.push(...cb2.toArray()); normals.push(...cb2.toArray()); uvs.push((Math.cos(this.af) + 1 + this.tab) / 2 / (1 + this.tab), (Math.sin(this.af) + 1 + this.tab) / 2 / (1 + this.tab)); uvs.push((Math.cos(aa * (j + 1) + this.af) + 1 + this.tab) / 2 / (1 + this.tab), (Math.sin(aa * (j + 1) + this.af) + 1 + this.tab) / 2 / (1 + this.tab)); uvs.push((Math.cos(aa * (j + 2) + this.af) + 1 + this.tab) / 2 / (1 + this.tab), (Math.sin(aa * (j + 2) + this.af) + 1 + this.tab) / 2 / (1 + this.tab)); } let numOfVertices = (fl - 2) * 3; for (let i2 = 0; i2 < numOfVertices / 3; i2++) { geom.addGroup(faceFirstVertexIndex, 3, materialIndex); faceFirstVertexIndex += 3; } } geom.setAttribute("position", new Float32BufferAttribute(positions, 3)); geom.setAttribute("normal", new Float32BufferAttribute(normals, 3)); geom.setAttribute("uv", new Float32BufferAttribute(uvs, 2)); geom.boundingSphere = new Sphere(new Vector3(), this.radius); return geom; } getMaterials() { let materials = []; for (let i = 0; i < this.labels.length; ++i) { let texture = null; texture = this.createTextTexture(i); materials.push(new MeshPhongMaterial(Object.assign({}, MATERIAL_OPTIONS, { map: texture }))); } return materials; } calculateTextureSize(approx) { return Math.max(128, Math.pow(2, Math.floor(Math.log(approx) / Math.log(2)))); } createTextTexture(index) { let text = this.labels[index]; if (text == void 0) return null; const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); const ts = this.calculateTextureSize(this.scale / 2 + this.scale * this.margin) * 2; canvas.width = canvas.height = ts; let fontsize = ts / (1 + 2 * this.margin); if (this.sides == 100) { fontsize *= 0.75; } context.font = fontsize + "pt Arial"; context.fillStyle = this.diceColor; context.fillRect(0, 0, canvas.width, canvas.height); context.textAlign = "center"; context.textBaseline = "middle"; if (this.sides == 10 || this.sides == 100) { context.translate(canvas.width / 2, canvas.height / 2); context.rotate(60 * Math.PI / 180); context.translate(-canvas.width / 2, -canvas.height / 2); } context.fillStyle = this.textColor; context.fillText(text, canvas.width / 2, canvas.height / 2); if (this.sides > 6 && (text == "6" || text == "9")) { context.fillText(" .", canvas.width / 2, canvas.height / 2); } var texture = new Texture(canvas); texture.needsUpdate = true; return texture; } clone() { return { body: new Body({ mass: this.mass, shape: this.shape }), geometry: this.geometry.clone() }; } }; var D20DiceShape = class extends DiceShape { constructor(w2, h, options = DEFAULT_DICE_OPTIONS) { super(w2, h, options); this.sides = 20; this.tab = -0.2; this.af = -Math.PI / 4 / 2; this.chamfer = 0.955; this.vertices = []; this.faces = [ [0, 11, 5, 1], [0, 5, 1, 2], [0, 1, 7, 3], [0, 7, 10, 4], [0, 10, 11, 5], [1, 5, 9, 6], [5, 11, 4, 7], [11, 10, 2, 8], [10, 7, 6, 9], [7, 1, 8, 10], [3, 9, 4, 11], [3, 4, 2, 12], [3, 2, 6, 13], [3, 6, 8, 14], [3, 8, 9, 15], [4, 9, 5, 16], [2, 4, 11, 17], [6, 2, 10, 18], [8, 6, 7, 19], [9, 8, 1, 20] ]; this.scaleFactor = 1; this.values = [...Array(20).keys()]; this.margin = 1; this.mass = 400; let t = (1 + Math.sqrt(5)) / 2; this.vertices = [ [-1, t, 0], [1, t, 0], [-1, -t, 0], [1, -t, 0], [0, -1, t], [0, 1, t], [0, -1, -t], [0, 1, -t], [t, 0, -1], [t, 0, 1], [-t, 0, -1], [-t, 0, 1] ]; this.create(); } }; var D12DiceShape = class extends DiceShape { constructor(w2, h, options = DEFAULT_DICE_OPTIONS) { super(w2, h, options); this.mass = 350; this.sides = 12; this.tab = 0.2; this.af = -Math.PI / 4 / 2; this.chamfer = 0.968; this.vertices = []; this.faces = [ [2, 14, 4, 12, 0, 1], [15, 9, 11, 19, 3, 2], [16, 10, 17, 7, 6, 3], [6, 7, 19, 11, 18, 4], [6, 18, 2, 0, 16, 5], [18, 11, 9, 14, 2, 6], [1, 17, 10, 8, 13, 7], [1, 13, 5, 15, 3, 8], [13, 8, 12, 4, 5, 9], [5, 4, 14, 9, 15, 10], [0, 12, 8, 10, 16, 11], [3, 19, 7, 17, 1, 12] ]; this.scaleFactor = 0.9; this.values = [...Array(12).keys()]; this.margin = 1; let p2 = (1 + Math.sqrt(5)) / 2; let q = 1 / p2; this.vertices = [ [0, q, p2], [0, q, -p2], [0, -q, p2], [0, -q, -p2], [p2, 0, q], [p2, 0, -q], [-p2, 0, q], [-p2, 0, -q], [q, p2, 0], [q, -p2, 0], [-q, p2, 0], [-q, -p2, 0], [1, 1, 1], [1, 1, -1], [1, -1, 1], [1, -1, -1], [-1, 1, 1], [-1, 1, -1], [-1, -1, 1], [-1, -1, -1] ]; this.create(); } }; var D10DiceShape = class extends DiceShape { constructor(w2, h, options = DEFAULT_DICE_OPTIONS) { super(w2, h, options); this.mass = 350; this.sides = 10; this.tab = 0; this.af = -Math.PI * 6 / 5; this.chamfer = 0.945; this.vertices = []; this.faces = [ [5, 7, 11, 0], [4, 2, 10, 1], [1, 3, 11, 2], [0, 8, 10, 3], [7, 9, 11, 4], [8, 6, 10, 5], [9, 1, 11, 6], [2, 0, 10, 7], [3, 5, 11, 8], [6, 4, 10, 9], [1, 0, 2, -1], [1, 2, 3, -1], [3, 2, 4, -1], [3, 4, 5, -1], [5, 4, 6, -1], [5, 6, 7, -1], [7, 6, 8, -1], [7, 8, 9, -1], [9, 8, 0, -1], [9, 0, 1, -1] ]; this.scaleFactor = 0.9; this.values = [...Array(10).keys()]; this.margin = 1; for (let i = 0, b2 = 0; i < 10; ++i, b2 += Math.PI * 2 / 10) { this.vertices.push([ Math.cos(b2), Math.sin(b2), 0.105 * (i % 2 ? 1 : -1) ]); } this.vertices.push([0, 0, -1]); this.vertices.push([0, 0, 1]); this.create(); } }; var D100DiceShape = class extends DiceShape { constructor(w2, h, options = DEFAULT_DICE_OPTIONS) { super(w2, h, options); this.labels = ["", "00", "10", "20", "30", "40", "50", "60", "70", "80", "90"]; this.sides = 100; this.mass = 350; this.tab = 0; this.af = -Math.PI * 6 / 5; this.chamfer = 0.945; this.vertices = []; this.faces = [ [5, 7, 11, 0], [4, 2, 10, 1], [1, 3, 11, 2], [0, 8, 10, 3], [7, 9, 11, 4], [8, 6, 10, 5], [9, 1, 11, 6], [2, 0, 10, 7], [3, 5, 11, 8], [6, 4, 10, 9], [1, 0, 2, -1], [1, 2, 3, -1], [3, 2, 4, -1], [3, 4, 5, -1], [5, 4, 6, -1], [5, 6, 7, -1], [7, 6, 8, -1], [7, 8, 9, -1], [9, 8, 0, -1], [9, 0, 1, -1] ]; this.scaleFactor = 0.9; this.values = [...Array(10).keys()]; this.margin = 1; for (let i = 0, b2 = 0; i < 10; ++i, b2 += Math.PI * 2 / 10) { this.vertices.push([ Math.cos(b2), Math.sin(b2), 0.105 * (i % 2 ? 1 : -1) ]); } this.vertices.push([0, 0, -1]); this.vertices.push([0, 0, 1]); this.create(); } }; var D8DiceShape = class extends DiceShape { constructor(w2, h, options = DEFAULT_DICE_OPTIONS) { super(w2, h, options); this.mass = 340; this.sides = 8; this.tab = 0; this.af = -Math.PI / 4 / 2; this.chamfer = 0.965; this.vertices = [ [1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1] ]; this.faces = [ [0, 2, 4, 1], [0, 4, 3, 2], [0, 3, 5, 3], [0, 5, 2, 4], [1, 3, 4, 5], [1, 4, 2, 6], [1, 2, 5, 7], [1, 5, 3, 8] ]; this.scaleFactor = 1; this.values = [...Array(8).keys()]; this.margin = 1.2; this.create(); } }; var D6DiceShape = class extends DiceShape { constructor(w2, h, options = DEFAULT_DICE_OPTIONS) { super(w2, h, options); this.mass = 300; this.tab = 0.1; this.af = Math.PI / 4; this.chamfer = 0.96; this.vertices = [ [-1, -1, -1], [1, -1, -1], [1, 1, -1], [-1, 1, -1], [-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1] ]; this.faces = [ [0, 3, 2, 1, 1], [1, 2, 6, 5, 2], [0, 1, 5, 4, 3], [3, 7, 6, 2, 4], [0, 4, 7, 3, 5], [4, 5, 6, 7, 6] ]; this.scaleFactor = 0.9; this.sides = 6; this.margin = 1; this.values = [...Array(6).keys()]; this.create(); } }; var D4DiceShape = class extends DiceShape { constructor(w2, h, options = DEFAULT_DICE_OPTIONS) { super(w2, h, options); this.mass = 300; this.tab = -0.1; this.af = Math.PI * 7 / 6; this.chamfer = 0.96; this.vertices = [ [1, 1, 1], [-1, -1, 1], [-1, 1, -1], [1, -1, -1] ]; this.faces = [ [1, 0, 2, 1], [0, 1, 3, 2], [0, 3, 2, 3], [1, 2, 3, 4] ]; this.scaleFactor = 1.2; this.sides = 4; this.margin = 1; this.d4FaceTexts = [ [[], [0, 0, 0], [2, 4, 3], [1, 3, 4], [2, 1, 4], [1, 2, 3]], [[], [0, 0, 0], [2, 3, 4], [3, 1, 4], [2, 4, 1], [3, 2, 1]], [[], [0, 0, 0], [4, 3, 2], [3, 4, 1], [4, 2, 1], [3, 1, 2]], [[], [0, 0, 0], [4, 2, 3], [1, 4, 3], [4, 1, 2], [1, 3, 2]] ]; this.faceTexts = this.d4FaceTexts[0]; this.values = [...Array(4).keys()]; this.create(); } getMaterials() { let materials = []; for (let i = 0; i < this.d4FaceTexts[0].length; ++i) { let texture = null; texture = this.createTextTexture(i); materials.push(new MeshPhongMaterial(Object.assign({}, MATERIAL_OPTIONS, { map: texture }))); } return materials; } createTextTexture(index) { let canvas = document.createElement("canvas"); let ctx = canvas.getContext("2d"); let ts = this.calculateTextureSize(this.radius / 2 + this.radius * 2) * 2; canvas.width = canvas.height = ts; ctx.font = ts / 5 + "pt Arial"; ctx.fillStyle = this.diceColor; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillStyle = this.textColor; for (let i in this.faceTexts[index]) { ctx.fillText(`${this.faceTexts[index][i]}`, canvas.width / 2, canvas.height / 2 - ts * 0.3); ctx.translate(canvas.width / 2, canvas.height / 2); ctx.rotate(Math.PI * 2 / 3); ctx.translate(-canvas.width / 2, -canvas.height / 2); } let texture = new Texture(canvas); texture.needsUpdate = true; return texture; } updateMaterialsForValue(diceValue) { if (diceValue < 0) diceValue += 4; this.faceTexts = this.d4FaceTexts[diceValue]; this.geometry.material = this.getMaterials(); } }; // src/view/renderer.ts var _DiceRenderer = class extends import_obsidian7.Component { constructor(plugin) { super(); this.plugin = plugin; this.event = new import_obsidian7.Events(); this.container = createDiv("renderer-container"); this.shadows = true; this.iterations = 0; this.factory = new DiceFactory(this.WIDTH, this.HEIGHT, this.plugin); this.frame_rate = 1 / 60; this.animating = false; this.colors = { ambient: 16777215, spotlight: 16777215 }; this.display = { currentWidth: null, currentHeight: null, containerWidth: null, containerHeight: null, aspect: null, scale: null }; this.cameraHeight = { max: null, close: null, medium: null, far: null }; this.extraFrames = _DiceRenderer.DEFAULT_EXTRA_FRAMES; this.renderer = new WebGLRenderer({ alpha: true, antialias: true }); this.addChild(this.factory); } get WIDTH() { return this.container.clientWidth / 2; } get HEIGHT() { return this.container.clientHeight / 2; } get ASPECT() { return this.WIDTH / this.HEIGHT; } get scale() { return (this.WIDTH * this.WIDTH + this.HEIGHT * this.HEIGHT) / 13; } get canvasEl() { if (!this.renderer) return null; return this.renderer.domElement; } setDice(stack) { if (this.animating) { this.unload(); this.load(); } this.stack = stack; this.current = this.factory.getDice(this.stack, { x: (Math.random() * 2 - 1) * this.WIDTH, y: -(Math.random() * 2 - 1) * this.HEIGHT }); this.scene.add(...[...this.current.values()].flat().map((d) => d.geometry)); this.world.add(...[...this.current.values()].flat()); } onload() { this.container.empty(); this.container.style.opacity = `1`; document.body.appendChild(this.container); this.renderer.shadowMap.enabled = this.shadows; this.renderer.shadowMap.type = PCFSoftShadowMap; this.container.appendChild(this.renderer.domElement); this.renderer.setClearColor(0, 0); this.scene = new Scene(); this.initScene(); this.registerDomEvent(window, "resize", () => { this.initScene(); }); this.initWorld(); } start() { return __async(this, null, function* () { return new Promise((resolve2, reject2) => __async(this, null, function* () { if (!this.current.size) reject2(); this.event.on("throw-finished", (result) => { resolve2(result); }); this.event.on("error", (e) => { reject2(e); }); this.animating = true; this.extraFrames = _DiceRenderer.DEFAULT_EXTRA_FRAMES; this.render(); })); }); } enableShadows() { this.shadows = true; if (this.renderer) this.renderer.shadowMap.enabled = this.shadows; if (this.light) this.light.castShadow = this.shadows; if (this.desk) this.desk.receiveShadow = this.shadows; } disableShadows() { this.shadows = false; if (this.renderer) this.renderer.shadowMap.enabled = this.shadows; if (this.light) this.light.castShadow = this.shadows; if (this.desk) this.desk.receiveShadow = this.shadows; } get mw() { return Math.max(this.WIDTH, this.HEIGHT); } setDimensions(dimensions) { this.display.currentWidth = this.container.clientWidth / 2; this.display.currentHeight = this.container.clientHeight / 2; if (dimensions) { this.display.containerWidth = dimensions.w; this.display.containerHeight = dimensions.h; } else { this.display.containerWidth = this.display.currentWidth; this.display.containerHeight = this.display.currentHeight; } this.display.aspect = Math.min(this.display.currentWidth / this.display.containerWidth, this.display.currentHeight / this.display.containerHeight); this.display.scale = Math.sqrt(this.display.containerWidth * this.display.containerWidth + this.display.containerHeight * this.display.containerHeight) / 13; this.renderer.setSize(this.display.currentWidth * 2, this.display.currentHeight * 2); this.cameraHeight.max = this.display.currentHeight / this.display.aspect / Math.tan(10 * Math.PI / 180); this.factory.width = this.display.currentWidth; this.factory.height = this.display.currentHeight; this.cameraHeight.medium = this.cameraHeight.max / 1.5; this.cameraHeight.far = this.cameraHeight.max; this.cameraHeight.close = this.cameraHeight.max / 2; } initCamera() { if (this.camera) this.scene.remove(this.camera); this.camera = new PerspectiveCamera(20, this.display.currentWidth / this.display.currentHeight, 1, this.cameraHeight.max * 1.3); this.camera.position.z = this.cameraHeight.far; this.camera.lookAt(new Vector3(0, 0, 0)); } initLighting() { const maxwidth = Math.max(this.display.containerWidth, this.display.containerHeight); if (this.light) this.scene.remove(this.light); if (this.ambientLight) this.scene.remove(this.ambientLight); this.light = new SpotLight(this.colors.spotlight, 0.25); this.light.position.set(-maxwidth / 2, maxwidth / 2, maxwidth * 3); this.light.target.position.set(0, 0, 0); this.light.distance = maxwidth * 5; this.light.angle = Math.PI / 4; this.light.castShadow = this.shadows; this.light.shadow.camera.near = maxwidth / 10; this.light.shadow.camera.far = maxwidth * 5; this.light.shadow.camera.fov = 50; this.light.shadow.bias = 1e-3; this.light.shadow.mapSize.width = 1024; this.light.shadow.mapSize.height = 1024; this.scene.add(this.light); this.ambientLight = new AmbientLight(16777215, 0.9); this.scene.add(this.ambientLight); } initDesk() { if (this.desk) this.scene.remove(this.desk); let shadowplane = new ShadowMaterial(); shadowplane.opacity = 0.5; this.desk = new Mesh(new PlaneGeometry(this.display.containerWidth * 6, this.display.containerHeight * 6, 1, 1), shadowplane); this.desk.receiveShadow = this.shadows; this.scene.add(this.desk); } initScene() { this.setDimensions(); this.initCamera(); this.initLighting(); this.initDesk(); this.camera.updateProjectionMatrix(); this.renderer.render(this.scene, this.camera); } initWorld() { this.world = new World2(this.WIDTH, this.HEIGHT); this.iterations = 0; } returnResult() { for (const roller of this.stack.dynamic) { if (!this.current.has(roller)) { continue; } const diceArray = this.current.get(roller); const percentile = diceArray.filter((d) => d instanceof D10Dice && d.isPercentile); const chunked = []; for (let i = 0; i < percentile.length; i += 2) { chunked.push(percentile.slice(i, i + 2)); } let results = [ ...diceArray.filter((d) => !(d instanceof D10Dice && d.isPercentile)).map((dice) => { return dice.getUpsideValue(); }).filter((r) => r), ...chunked.map(([tensDice, onesDice]) => { let tens = tensDice.getUpsideValue(); if (!onesDice) return tens; let ones = onesDice.getUpsideValue(); if (tens === 10 && ones == 10) { return 100; } else { if (ones == 10) ones = 0; if (tens == 10) tens = 0; return tens * 10 + ones; } }).filter((r) => r) ]; roller.setResults(results); } this.event.trigger("throw-finished", this.stack); } render() { if (this.throwFinished()) { if (this.extraFrames > 10) { this.extraFrames--; } else { try { this.returnResult(); this.registerInterval(window.setTimeout(() => { this.container.style.opacity = `0`; this.registerInterval(window.setTimeout(() => { this.animating = false; this.unload(); }, 1e3)); }, 2e3)); } catch (e) { this.event.trigger("error", e); } return; } } this.animation = requestAnimationFrame(() => this.render()); this.world.step(this.frame_rate); this.iterations++; this.current.forEach((dice) => { dice.map((d) => d.set()); }); this.renderer.render(this.scene, this.camera); } dispose(...children) { children.forEach((child) => { if ("dispose" in child) child.dispose(); if (child.children) this.dispose(...child.children); }); } detach() { } onunload() { cancelAnimationFrame(this.animation); this.container.detach(); this.container.empty(); this.renderer.domElement.detach(); this.renderer.dispose(); this.factory.dispose(); this.ambientLight.dispose(); this.light.dispose(); this.scene.children.forEach((child) => this.dispose(child)); this.scene.remove(this.scene, ...this.scene.children, ...[...this.current.values()].flat().map((d) => d.geometry)); this.current.forEach((arr) => { arr.forEach((dice) => { let materials = [ ...Array.isArray(dice.geometry.material) ? dice.geometry.material : [dice.geometry.material] ]; materials.forEach((material) => material && material.dispose()); this.world.world.removeBody(dice.body); }); }); this.current = /* @__PURE__ */ new Map(); } onThrowFinished() { } throwFinished() { let res = true; const threshold = 4; if (this.iterations < 10 / this.frame_rate) { for (const diceArray of this.current.values()) { for (const dice of diceArray) { if (dice.stopped === true) continue; const a2 = dice.body.angularVelocity, v = dice.body.velocity; if (Math.abs(a2.x) < threshold && Math.abs(a2.y) < threshold && Math.abs(a2.z) < threshold && Math.abs(v.x) < threshold && Math.abs(v.y) < threshold && Math.abs(v.z) < threshold) { if (dice.stopped) { if (this.iterations - dice.stopped > 3) { dice.stopped = true; continue; } } else { dice.stopped = this.iterations; } res = false; } else { dice.stopped = void 0; res = false; } } } } return res; } }; var DiceRenderer = _DiceRenderer; DiceRenderer.DEFAULT_EXTRA_FRAMES = 30; var World2 = class { constructor(WIDTH, HEIGHT) { this.WIDTH = WIDTH; this.HEIGHT = HEIGHT; this.world = new World({ gravity: new Vec3(0, 0, -9.82 * 400) }); this.ground = this.getPlane(); this.diceMaterial = new Material2(); this.deskMaterial = new Material2(); this.barrierMaterial = new Material2(); this.world.broadphase = new NaiveBroadphase(); this.world.allowSleep = true; this.ground.position.set(0, 0, 0); this.world.addBody(this.ground); this.buildWalls(); } add(...dice) { dice.forEach((die) => { this.world.addBody(die.body); }); } step(step = 1 / 60) { const time = performance.now() / 1e3; if (!this.lastCallTime) { this.world.step(step); } else { const dt = time - this.lastCallTime; this.world.step(step, dt); } this.lastCallTime = time; } buildWalls() { this.world.addContactMaterial(new ContactMaterial(this.deskMaterial, this.diceMaterial, { friction: 0.01, restitution: 0.5, contactEquationRelaxation: 3, contactEquationStiffness: 1e8 })); this.world.addContactMaterial(new ContactMaterial(this.barrierMaterial, this.diceMaterial, { friction: 0.01, restitution: 1, contactEquationRelaxation: 3, contactEquationStiffness: 1e8 })); this.world.addContactMaterial(new ContactMaterial(this.diceMaterial, this.diceMaterial, { friction: 0.1, restitution: 0.5, contactEquationRelaxation: 3, contactEquationStiffness: 1e8 })); this.world.addBody(new Body({ allowSleep: false, mass: 0, shape: new Plane2(), material: this.deskMaterial })); let barrier = new Body({ allowSleep: false, mass: 0, shape: new Plane2(), material: this.barrierMaterial }); barrier.quaternion.setFromAxisAngle(new Vec3(1, 0, 0), Math.PI / 2); barrier.position.set(0, this.HEIGHT * 0.93, 0); this.world.addBody(barrier); barrier = new Body({ allowSleep: false, mass: 0, shape: new Plane2(), material: this.barrierMaterial }); barrier.quaternion.setFromAxisAngle(new Vec3(1, 0, 0), -Math.PI / 2); barrier.position.set(0, -this.HEIGHT * 0.93, 0); this.world.addBody(barrier); barrier = new Body({ allowSleep: false, mass: 0, shape: new Plane2(), material: this.barrierMaterial }); barrier.quaternion.setFromAxisAngle(new Vec3(0, 1, 0), -Math.PI / 2); barrier.position.set(this.WIDTH * 0.93, 0, 0); this.world.addBody(barrier); barrier = new Body({ allowSleep: false, mass: 0, shape: new Plane2(), material: this.barrierMaterial }); barrier.quaternion.setFromAxisAngle(new Vec3(0, 1, 0), Math.PI / 2); barrier.position.set(-this.WIDTH * 0.93, 0, 0); this.world.addBody(barrier); } getPlane() { return new Body({ type: Body.STATIC, shape: new Plane2() }); } }; var DEFAULT_VECTOR = { pos: { x: 0 + 100 * Math.random(), y: 0 + 100 * Math.random(), z: 0 + 250 }, velocity: { x: 600 * (Math.random() * 2 + 1), y: 750 * (Math.random() * 2 + 1), z: 0 }, angular: { x: 200 * Math.random(), y: 200 * Math.random(), z: 100 * Math.random() }, axis: { x: Math.random(), y: Math.random(), z: Math.random(), w: Math.random() } }; var Dice = class { constructor(w2, h, data) { this.w = w2; this.h = h; this.data = data; this.scale = 50; this.stopped = false; this.iteration = 0; this.vector = __spreadValues({}, DEFAULT_VECTOR); this.geometry = data.geometry; this.body = data.body; } generateVector(v) { const dist = Math.sqrt(v.x * v.x + v.y * v.y); const boost = (Math.random() + 3) * dist; const vector = { x: v.x / dist, y: v.y / dist }; const vec = this.makeRandomVector(vector); const pos = { x: this.w * (vec.x > 0 ? -1 : 1) * 0.9, y: this.h * (vec.y > 0 ? -1 : 1) * 0.9, z: Math.random() * 200 + 200 }; const projector = Math.abs(vec.x / vec.y); if (projector > 1) pos.y /= projector; else pos.x *= projector; const velvec = this.makeRandomVector(vector); const velocity = { x: velvec.x * boost, y: velvec.y * boost, z: -10 }; const angular = { x: -(Math.random() * vec.y * 5 + this.inertia * vec.y), y: Math.random() * vec.x * 5 + this.inertia * vec.x, z: 0 }; const axis = { x: Math.random(), y: Math.random(), z: Math.random(), w: Math.random() }; return { pos, velocity, angular, axis }; } makeRandomVector(vector) { const random_angle = Math.random() * Math.PI / 5 - Math.PI / 5 / 2; const vec = { x: vector.x * Math.cos(random_angle) - vector.y * Math.sin(random_angle), y: vector.x * Math.sin(random_angle) + vector.y * Math.cos(random_angle) }; if (vec.x == 0) vec.x = 0.01; if (vec.y == 0) vec.y = 0.01; return vec; } get buffer() { return this.geometry.geometry; } getUpsideValue() { let vector = new Vector3(0, 0, this.sides == 4 ? -1 : 1); let closest_face, closest_angle = Math.PI * 2; const normals = this.buffer.getAttribute("normal").array; for (let i = 0, l = this.buffer.groups.length; i < l; ++i) { const face = this.buffer.groups[i]; if (face.materialIndex == 0) continue; let startVertex = i * 9; const normal = new Vector3(normals[startVertex], normals[startVertex + 1], normals[startVertex + 2]); const angle = normal.clone().applyQuaternion(new Quaternion(this.body.quaternion.x, this.body.quaternion.y, this.body.quaternion.z, this.body.quaternion.w)).angleTo(vector); if (angle < closest_angle) { closest_angle = angle; closest_face = face; } } let matindex = closest_face.materialIndex - 1; if (this.sides == 10 && matindex == 0) matindex = 10; return matindex; } shiftUpperValue(to) { let geometry = this.geometry.geometry.clone(); let from = this.getUpsideValue(); for (let i = 0, l = geometry.groups.length; i < l; ++i) { let materialIndex = geometry.groups[i].materialIndex; if (materialIndex === 0) continue; materialIndex += to - from - 1; while (materialIndex > this.sides) materialIndex -= this.sides; while (materialIndex < 1) materialIndex += this.sides; geometry.groups[i].materialIndex = materialIndex + 1; } this.updateMaterialsForValue(to - from); this.geometry.geometry = geometry; } resetBody() { this.body.vlambda = new Vec3(); this.body.position = new Vec3(); this.body.previousPosition = new Vec3(); this.body.initPosition = new Vec3(); this.body.velocity = new Vec3(); this.body.initVelocity = new Vec3(); this.body.force = new Vec3(); this.body.torque = new Vec3(); this.body.quaternion = new Quaternion2(); this.body.initQuaternion = new Quaternion2(); this.body.angularVelocity = new Vec3(); this.body.initAngularVelocity = new Vec3(); this.body.interpolatedPosition = new Vec3(); this.body.interpolatedQuaternion = new Quaternion2(); this.body.inertia = new Vec3(); this.body.invInertia = new Vec3(); this.body.invInertiaWorld = new Mat3(); this.body.invInertiaSolve = new Vec3(); this.body.invInertiaWorldSolve = new Mat3(); this.body.wlambda = new Vec3(); this.body.updateMassProperties(); } updateMaterialsForValue(value) { } set() { this.geometry.position.set(this.body.position.x, this.body.position.y, this.body.position.z); this.geometry.quaternion.set(this.body.quaternion.x, this.body.quaternion.y, this.body.quaternion.z, this.body.quaternion.w); } create() { this.body.position.set(this.vector.pos.x, this.vector.pos.y, this.vector.pos.z); this.body.quaternion.setFromAxisAngle(new Vec3(this.vector.axis.x, this.vector.axis.y, this.vector.axis.z), this.vector.axis.w * Math.PI * 2); this.body.angularVelocity.set(this.vector.angular.x, this.vector.angular.y, this.vector.angular.z); this.body.velocity.set(this.vector.velocity.x, this.vector.velocity.y, this.vector.velocity.z); this.body.linearDamping = 0.1; this.body.angularDamping = 0.1; } }; var DiceFactory = class extends import_obsidian7.Component { constructor(width, height, plugin) { super(); this.width = width; this.height = height; this.plugin = plugin; this.d100 = new D100DiceShape(this.width, this.height, this.colors); this.d20 = new D20DiceShape(this.width, this.height, this.colors); this.d12 = new D12DiceShape(this.width, this.height, this.colors); this.d10 = new D10DiceShape(this.width, this.height, this.colors); this.d8 = new D8DiceShape(this.width, this.height, this.colors); this.d6 = new D6DiceShape(this.width, this.height, this.colors); this.d4 = new D4DiceShape(this.width, this.height, this.colors); } get colors() { return { diceColor: this.plugin.data.diceColor, textColor: this.plugin.data.textColor }; } updateColors() { this.dispose(); this.d100 = new D100DiceShape(this.width, this.height, this.colors); this.d20 = new D20DiceShape(this.width, this.height, this.colors); this.d12 = new D12DiceShape(this.width, this.height, this.colors); this.d10 = new D10DiceShape(this.width, this.height, this.colors); this.d8 = new D8DiceShape(this.width, this.height, this.colors); this.d6 = new D6DiceShape(this.width, this.height, this.colors); this.d4 = new D4DiceShape(this.width, this.height, this.colors); } onunload() { this.dispose(); } disposeChildren(...children) { children.forEach((child) => { if ("dispose" in child) child.dispose(); if (child.children) this.disposeChildren(...child.children); }); } dispose() { this.disposeChildren(this.d100.geometry.children); this.disposeChildren(this.d20.geometry.children); this.disposeChildren(this.d12.geometry.children); this.disposeChildren(this.d10.geometry.children); this.disposeChildren(this.d8.geometry.children); this.disposeChildren(this.d6.geometry.children); this.disposeChildren(this.d4.geometry.children); } getDice(stack, vector) { const map = /* @__PURE__ */ new Map(); for (const roller of stack.dynamic) { const dice = []; switch (roller.faces.max) { case 4: { dice.push(...new Array(roller.rolls).fill(0).map((r) => new D4Dice(this.width, this.height, this.d4.clone(), vector))); break; } case 6: { dice.push(...new Array(roller.rolls).fill(0).map((r) => new D6Dice(this.width, this.height, this.d6.clone(), vector))); break; } case 8: { dice.push(...new Array(roller.rolls).fill(0).map((r) => new D8Dice(this.width, this.height, this.d8.clone(), vector))); break; } case 10: { dice.push(...new Array(roller.rolls).fill(0).map((r) => new D10Dice(this.width, this.height, this.d10.clone(), vector))); break; } case 12: { dice.push(...new Array(roller.rolls).fill(0).map((r) => new D12Dice(this.width, this.height, this.d12.clone(), vector))); break; } case 20: { dice.push(...new Array(roller.rolls).fill(0).map((r) => new D20Dice(this.width, this.height, this.d20.clone(), vector))); break; } case 100: { dice.push(...new Array(roller.rolls).fill(0).map((r) => [ new D10Dice(this.width, this.height, this.d100.clone(), vector, true), new D10Dice(this.width, this.height, this.d10.clone(), vector, true) ]).flat()); break; } } if (dice.length) map.set(roller, dice); } return map; } }; var D20Dice = class extends Dice { constructor(w2, h, data, vector) { super(w2, h, data); this.w = w2; this.h = h; this.data = data; this.sides = 20; this.inertia = 6; if (vector) { this.vector = this.generateVector(vector); } this.create(); } }; var D12Dice = class extends Dice { constructor(w2, h, data, vector) { super(w2, h, data); this.w = w2; this.h = h; this.data = data; this.sides = 12; this.inertia = 8; if (vector) { this.vector = this.generateVector(vector); } this.create(); } }; var D10Dice = class extends Dice { constructor(w2, h, data, vector, isPercentile = false) { super(w2, h, data); this.w = w2; this.h = h; this.data = data; this.isPercentile = isPercentile; this.sides = 10; this.inertia = 9; if (vector) { this.vector = this.generateVector(vector); } this.create(); } }; var D8Dice = class extends Dice { constructor(w2, h, data, vector) { super(w2, h, data); this.w = w2; this.h = h; this.data = data; this.sides = 8; this.inertia = 10; if (vector) { this.vector = this.generateVector(vector); } this.create(); } }; var D6Dice = class extends Dice { constructor(w2, h, data, vector) { super(w2, h, data); this.w = w2; this.h = h; this.data = data; this.sides = 6; this.inertia = 13; if (vector) { this.vector = this.generateVector(vector); } this.create(); } }; var D4Dice = class extends Dice { constructor(w2, h, data, vector) { super(w2, h, data); this.w = w2; this.h = h; this.data = data; this.sides = 4; this.inertia = 5; if (vector) { this.vector = this.generateVector(vector); } this.create(); } }; // src/main.ts String.prototype.matchAll = String.prototype.matchAll || function* matchAll(regexp) { const flags = regexp.global ? regexp.flags : regexp.flags + "g"; const re = new RegExp(regexp, flags); let match; while (match = re.exec(this)) { yield match; } }; var DEFAULT_SETTINGS = { returnAllTags: true, rollLinksForTags: false, copyContentButton: true, customFormulas: [], displayFormulaForMod: true, displayResultsInline: false, displayLookupRoll: true, formulas: {}, persistResults: false, results: {}, defaultRoll: 1, defaultFace: 100, renderer: false, diceColor: "#202020", textColor: "#ffffff", showLeafOnStartup: true, showDice: true }; var DiceRollerPlugin = class extends import_obsidian8.Plugin { constructor() { super(...arguments); this.persistingFiles = /* @__PURE__ */ new Set(); this.fileMap = /* @__PURE__ */ new Map(); this.inline = /* @__PURE__ */ new Map(); this.operators = { "+": (a2, b2) => a2 + b2, "-": (a2, b2) => a2 - b2, "*": (a2, b2) => a2 * b2, "/": (a2, b2) => a2 / b2, "^": (a2, b2) => { return Math.pow(a2, b2); } }; } get canUseDataview() { return this.app.plugins.getPlugin("dataview") != null; } get dataview() { return this.app.plugins.getPlugin("dataview"); } dataviewReady() { return __async(this, null, function* () { return new Promise((resolve2) => { if (!this.canUseDataview) resolve2(false); if (this.dataview.api) { resolve2(true); } this.registerEvent(this.app.metadataCache.on("dataview:api-ready", () => { resolve2(true); })); }); }); } get view() { const leaves = this.app.workspace.getLeavesOfType(VIEW_TYPE); const leaf = leaves.length ? leaves[0] : null; if (leaf && leaf.view && leaf.view instanceof DiceView) return leaf.view; } addDiceView(startup = false) { return __async(this, null, function* () { if (startup && !this.data.showLeafOnStartup) return; if (this.app.workspace.getLeavesOfType(VIEW_TYPE).length) { return; } yield this.app.workspace.getRightLeaf(false).setViewState({ type: VIEW_TYPE }); }); } registerDataviewInlineFields() { return __async(this, null, function* () { if (!this.canUseDataview) return; yield this.dataviewReady(); const pages = this.dataview.index.pages; pages.forEach(({ fields }) => { for (const [key, value] of fields) { if (typeof value !== "number" || Number.isNaN(value) || value == void 0) continue; this.inline.set(key, value); } }); this.registerEvent(this.dataview.index.events.on("dataview:metadata-change", (type, file) => { if (type === "update") { const page = this.dataview.api.page(file.path); if (!page) return; for (let key in page) { let value = page[key]; if (typeof value !== "number" || Number.isNaN(value) || value == void 0) continue; this.inline.set(key, value); } } })); }); } renderRoll(roller) { return __async(this, null, function* () { this.addChild(this.renderer); this.renderer.setDice(roller); yield this.renderer.start(); roller.recalculate(); }); } onload() { return __async(this, null, function* () { console.log("DiceRoller plugin loaded"); this.data = Object.assign(DEFAULT_SETTINGS, yield this.loadData()); this.renderer = new DiceRenderer(this); this.addSettingTab(new SettingTab(this.app, this)); this.registerView(VIEW_TYPE, (leaf) => new DiceView(this, leaf)); this.app.workspace.onLayoutReady(() => this.addDiceView(true)); this.registerEvent(this.app.workspace.on("dice-roller:update-colors", () => { this.renderer.factory.updateColors(); })); this.registerEvent(this.app.workspace.on("dice-roller:render-dice", (roll) => __async(this, null, function* () { const roller = yield this.getRoller(roll, "external"); if (!(roller instanceof StackRoller)) { new import_obsidian8.Notice("The Dice View only supports dice rolls."); return; } yield roller.roll(); if (!roller.dice.length) { new import_obsidian8.Notice("Invalid formula."); return; } try { this.renderRoll(roller); } catch (e) { new import_obsidian8.Notice("There was an error rendering the roll."); console.error(e); } this.app.workspace.trigger("dice-roller:rendered-result", roller.result); }))); this.addCommand({ id: "open-view", name: "Open Dice View", checkCallback: (checking) => { if (!this.view) { if (!checking) { this.addDiceView(); } return true; } } }); this.addCommand({ id: "reroll", name: "Re-roll Dice", checkCallback: (checking) => { const view = this.app.workspace.getActiveViewOfType(import_obsidian8.MarkdownView); if (view && view.getMode() === "preview" && this.fileMap.has(view.file)) { if (!checking) { const dice = this.fileMap.get(view.file); dice.forEach((roller) => { roller.roll(); }); } return true; } } }); const ICON_SVG = icon(faDice).html[0]; (0, import_obsidian8.addIcon)(ICON_DEFINITION, ICON_SVG); const COPY_SVG = icon(faCopy).html[0]; (0, import_obsidian8.addIcon)(COPY_DEFINITION, COPY_SVG); this.registerMarkdownPostProcessor((el, ctx) => __async(this, null, function* () { var _a; let nodeList = el.querySelectorAll("code"); if (!nodeList.length) return; const path = ctx.sourcePath; const info = ctx.getSectionInfo(el); const lineStart = (_a = ctx.getSectionInfo(el)) == null ? void 0 : _a.lineStart; const file = this.app.vault.getAbstractFileByPath(ctx.sourcePath); if (!file || !(file instanceof import_obsidian8.TFile)) return; const toPersist = {}; for (let index = 0; index < nodeList.length; index++) { const node = nodeList.item(index); if (/^dice\-mod:\s*([\s\S]+)\s*?/.test(node.innerText) && info) { try { let [full, content] = node.innerText.match(/^dice\-mod:\s*([\s\S]+)\s*?/); if (!DICE_REGEX.test(content)) { new import_obsidian8.Notice("Replacing note content may only be done with Dice Rolls."); continue; } const showFormula = !content.includes("|noform"); content = content.replace("|noform", ""); const roller = this.getRoller(content, ctx.sourcePath); yield roller.roll(); const fileContent = (yield this.app.vault.cachedRead(file)).split("\n"); let splitContent = fileContent.slice(info.lineStart, info.lineEnd + 1); const rep = showFormula ? `${roller.inlineText} **${roller.result}**` : `**${roller.result}**`; splitContent = splitContent.join("\n").replace(`\`${full}\``, rep).split("\n"); fileContent.splice(info.lineStart, info.lineEnd - info.lineStart + 1, ...splitContent); yield this.app.vault.modify(file, fileContent.join("\n")); continue; } catch (e) { console.error(e); } } if (!/^dice(?:\+|\-|\-mod)?:\s*([\s\S]+)\s*?/.test(node.innerText)) continue; try { let [, content] = node.innerText.match(/^dice(?:\+|\-|\-mod)?:\s*([\s\S]+)\s*?/); const roller = this.getRoller(content, ctx.sourcePath); const load = () => __async(this, null, function* () { var _a2, _b, _c, _d; yield roller.roll(); if (this.data.persistResults && !/dice\-/.test(node.innerText) || /dice\+/.test(node.innerText)) { this.persistingFiles.add(ctx.sourcePath); toPersist[index] = roller; roller.save = true; const result = (_d = (_c = (_b = (_a2 = this.data.results) == null ? void 0 : _a2[path]) == null ? void 0 : _b[lineStart]) == null ? void 0 : _c[index]) != null ? _d : null; if (result) { yield roller.applyResult(result); } } node.replaceWith(roller.containerEl); }); if (roller.loaded) { yield load(); } else { roller.on("loaded", () => __async(this, null, function* () { yield load(); })); } if (!this.fileMap.has(file)) { this.fileMap.set(file, []); } this.fileMap.set(file, [ ...this.fileMap.get(file), roller ]); const view = this.app.workspace.getActiveViewOfType(import_obsidian8.MarkdownView); if (view && this.fileMap.has(file) && this.fileMap.get(file).length === 1) { const self = this; let unregisterOnUnloadFile = around(view, { onUnloadFile: function(next) { return function(unloaded) { return __async(this, null, function* () { if (unloaded == file) { self.fileMap.delete(file); unregisterOnUnloadFile(); } return yield next.call(this, unloaded); }); }; } }); view.register(unregisterOnUnloadFile); view.register(() => this.fileMap.delete(file)); } } catch (e) { console.error(e); new import_obsidian8.Notice(`There was an error parsing the dice string: ${node.innerText}. ${e}`, 5e3); continue; } } if (path in this.data.results) { this.data.results[path][lineStart] = {}; } if (Object.entries(toPersist).length) { const view = this.app.workspace.getActiveViewOfType(import_obsidian8.MarkdownView); if (view) { const self = this; let unregisterOnUnloadFile = around(view, { onUnloadFile: function(next) { return function(unloaded) { return __async(this, null, function* () { var _a2, _b, _c, _d; if (unloaded = file) { if (self.persistingFiles.has(path)) { self.persistingFiles.delete(path); self.data.results[path] = {}; } for (let index in toPersist) { const roller = toPersist[index]; const newLineStart = (_a2 = ctx.getSectionInfo(el)) == null ? void 0 : _a2.lineStart; if (newLineStart == null) continue; const result = { [newLineStart]: __spreadProps(__spreadValues({}, (_c = (_b = self.data.results[path]) == null ? void 0 : _b[newLineStart]) != null ? _c : {}), { [index]: roller.toResult() }) }; self.data.results[path] = __spreadValues(__spreadValues({}, (_d = self.data.results[path]) != null ? _d : {}), result); yield self.saveSettings(); } } unregisterOnUnloadFile(); return yield next.call(this, unloaded); }); }; } }); view.register(unregisterOnUnloadFile); view.register(() => __async(this, null, function* () { var _a2, _b, _c, _d; if (this.persistingFiles.has(path)) { this.persistingFiles.delete(path); this.data.results[path] = {}; } for (let index in toPersist) { const roller = toPersist[index]; const newLineStart = (_a2 = ctx.getSectionInfo(el)) == null ? void 0 : _a2.lineStart; if (newLineStart == null) continue; const result = { [newLineStart]: __spreadProps(__spreadValues({}, (_c = (_b = this.data.results[path]) == null ? void 0 : _b[newLineStart]) != null ? _c : {}), { [index]: roller.toResult() }) }; this.data.results[path] = __spreadValues(__spreadValues({}, (_d = this.data.results[path]) != null ? _d : {}), result); yield this.saveSettings(); } })); } } })); this.lexer = new import_lex.default(); this.addLexerRules(); var exponent = { precedence: 3, associativity: "right" }; var factor = { precedence: 2, associativity: "left" }; var term = { precedence: 1, associativity: "left" }; this.parser = new Parser({ "+": term, "-": term, "*": factor, "/": factor, "^": exponent }); this.app.workspace.onLayoutReady(() => __async(this, null, function* () { yield this.registerDataviewInlineFields(); })); }); } parseDice(content, source) { return __async(this, null, function* () { const roller = this.getRoller(content, source); return { result: yield roller.roll(), roller }; }); } clearEmpties(o) { for (var k in o) { if (!o[k] || typeof o[k] !== "object") { continue; } this.clearEmpties(o[k]); if (Object.keys(o[k]).length === 0) { delete o[k]; } } } saveSettings() { return __async(this, null, function* () { this.clearEmpties(this.data.results); yield this.saveData(this.data); }); } get dataview_regex() { const fields = Array.from(this.inline.keys()); if (!fields.length) return null; return new RegExp(`(${fields.join("|")})`, "g"); } getRoller(content, source, icon2 = this.data.showDice) { let showDice = content.includes("|nodice") ? false : icon2; content = (0, import_he.decode)(content.replace("|nodice", "").replace("\\|", "|")); if (content in this.data.formulas) { content = this.data.formulas[content]; } const lexemes = this.parse(content); const type = this.getTypeFromLexemes(lexemes); switch (type) { case "dice": { return new StackRoller(this, content, lexemes, showDice); } case "table": { return new TableRoller(this, content, lexemes[0], source, showDice); } case "section": { return new SectionRoller(this, content, lexemes[0], source, showDice); } case "tag": { if (!this.canUseDataview) { throw new Error("Tags are only supported with the Dataview plugin installed."); } return new TagRoller(this, content, lexemes[0], source, showDice); } case "link": { return new LinkRoller(this, content, lexemes[0], source, showDice); } case "line": { return new LineRoller(this, content, lexemes[0], source, showDice); } } } getTypeFromLexemes(lexemes) { if (lexemes.some(({ type }) => type === "table")) { return "table"; } if (lexemes.some(({ type }) => type === "section")) { return "section"; } if (lexemes.some(({ type }) => type === "tag")) { return "tag"; } if (lexemes.some(({ type }) => type === "link")) { return "link"; } if (lexemes.some(({ type }) => type === "line")) { return "line"; } return "dice"; } addLexerRules() { this.lexer.addRule(/\s+/, function() { }); this.lexer.addRule(/[{}]+/, function() { }); this.lexer.addRule(TABLE_REGEX, function(lexeme) { return { type: "table", data: lexeme, original: lexeme, conditionals: null }; }); this.lexer.addRule(SECTION_REGEX, function(lexeme) { const { groups } = lexeme.match(SECTION_REGEX); let type = "section"; if (groups.types === "line") { type = "line"; } return { type, data: lexeme, original: lexeme, conditionals: null }; }); this.lexer.addRule(TAG_REGEX, (lexeme) => { var _a; const { groups } = lexeme.match(TAG_REGEX); let type = "tag"; if (groups.types === "link" || this.data.rollLinksForTags && !((_a = groups.types) == null ? void 0 : _a.length)) { type = "link"; } return { type, data: lexeme, original: lexeme, conditionals: null }; }); this.lexer.addRule(OMITTED_REGEX, (lexeme) => { const { roll = this.data.defaultRoll, faces = this.data.defaultFace, conditional } = lexeme.match(OMITTED_REGEX).groups; let conditionals = []; if (conditional) { let matches = conditional.matchAll(CONDITIONAL_REGEX); if (matches) { for (let match of matches) { if (!match) continue; const { comparer, operator } = match.groups; conditionals.push({ comparer: Number(comparer), operator }); } } } return { type: "dice", data: `${roll}d${faces}`, original: lexeme, conditionals }; }); this.lexer.addRule(/\d+/, function(lexeme) { return { type: "dice", data: lexeme, original: lexeme, conditionals: [] }; }); this.lexer.addRule(MATH_REGEX, function(lexeme) { return { type: "math", data: lexeme, original: lexeme, conditionals: null }; }); this.lexer.addRule(/1[Dd]S/, function(lexeme) { var _a; const [, dice] = (_a = lexeme.match(/1[Dd]S/)) != null ? _a : [, "1"]; return { type: "stunt", data: dice, original: lexeme, conditionals: [] }; }); this.lexer.addRule(/kh?(?!:l)(\d*)/, function(lexeme) { return { type: "kh", data: lexeme.replace(/^\D+/g, ""), original: lexeme, conditionals: null }; }); this.lexer.addRule(/dl?(?!:h)\d*/, function(lexeme) { return { type: "dl", data: lexeme.replace(/^\D+/g, ""), original: lexeme, conditionals: null }; }); this.lexer.addRule(/kl\d*/, function(lexeme) { return { type: "kl", data: lexeme.replace(/^\D+/g, ""), original: lexeme, conditionals: null }; }); this.lexer.addRule(/dh\d*/, function(lexeme) { return { type: "dh", data: lexeme.replace(/^\D+/g, ""), original: lexeme, conditionals: null }; }); this.lexer.addRule(/!!(i|\d+)?(?:(!?=|=!|>=?|<=?)(-?\d+))*/, function(lexeme) { let [, data = `1`] = lexeme.match(/!!(i|\d+)?(?:(!?=|=!|>=?|<=?)(-?\d+))*/), conditionals = []; if (/(?:(!?=|=!|>=?|<=?)(-?\d+))+/.test(lexeme)) { for (const [, operator, comparer] of lexeme.matchAll(/(?:(!?=|=!|>=?|<=?)(-?\d+))/g)) { conditionals.push({ operator, comparer: Number(comparer) }); } } if (/!!i/.test(lexeme)) { data = `100`; } return { type: "!!", data, original: lexeme, conditionals }; }); this.lexer.addRule(/!(i|\d+)?(?:(!?=|=!?|>=?|<=?)(-?\d+))*/, function(lexeme) { let [, data = `1`] = lexeme.match(/!(i|\d+)?(?:(!?=|=!?|>=?|<=?)(-?\d+))*/), conditionals = []; if (/(?:(!?=|=!|>=?|<=?)(\d+))+/.test(lexeme)) { for (const [, operator, comparer] of lexeme.matchAll(/(?:(!?=|=!?|>=?|<=?)(-?\d+))/g)) { conditionals.push({ operator, comparer: Number(comparer) }); } } if (/!i/.test(lexeme)) { data = `100`; } return { type: "!", data, original: lexeme, conditionals }; }); this.lexer.addRule(/r(i|\d+)?(?:(!?=|=!|>=?|<=?)(-?\d+))*/, function(lexeme) { let [, data = `1`] = lexeme.match(/r(i|\d+)?(?:(!?=|=!|>=?|<=?)(-?\d+))*/), conditionals = []; if (/(?:(!?={1,2}|>=?|<=?)(-?\d+))+/.test(lexeme)) { for (const [, operator, comparer] of lexeme.matchAll(/(?:(!?=|=!|>=?|<=?)(-?\d+))/g)) { conditionals.push({ operator, comparer: Number(comparer) }); } } if (/ri/.test(lexeme)) { data = `100`; } return { type: "r", data, original: lexeme, conditionals }; }); const self = this; this.lexer.addRule(/[A-Za-z][A-Za-z0-9_]+/, function(lexeme) { if (self.inline.has(lexeme.trim())) { return { type: "dice", data: `${self.inline.get(lexeme.trim())}`, original: lexeme, conditionals: [] }; } }); } onunload() { console.log("DiceRoller unloaded"); this.app.workspace.getLeavesOfType(VIEW_TYPE).forEach((leaf) => leaf.detach()); if ("__THREE__" in window) { delete window.__THREE__; } this.renderer.unload(); this.app.workspace.trigger("dice-roller:unload"); } parse(input) { this.lexer.setInput(input); var tokens = [], token; while (token = this.tryLex()) { tokens.push(token); } return this.parser.parse(tokens); } tryLex() { try { return this.lexer.lex(); } catch (e) { } } }; /*! * Font Awesome Free 5.15.3 by @fontawesome - https://fontawesome.com * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) */ /*! * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) */ /*! https://mths.be/he v1.2.0 by @mathias | MIT license */ /** * @license * Copyright 2010-2021 Three.js Authors * SPDX-License-Identifier: MIT */