Connecting external Javascript library
How to make interactive 3D Force-Directed Graphs
There is an amazing Javascript library for building 3D force graphs using THREE.js.
We can build it into a standlone module for our notebooks using ESM cells. But firstly, lets fetch this library using NPM
Download original notebook.sh npm i 3d-force-graph
added 33 packages, and audited 37 packages in 4s found 0 vulnerabilities
Now define our function. WLJS Notebook has a system of shared Javascript libraries, which already provides some of the dependencies.
.esm import ForceGraph3D from '3d-force-graph'; core.ForceGraph3D = async (args, env) => { //load shared library from WLJS Notebook store await interpretate.shared.SpriteText.load(); //interprete input data const data = await interpretate(args[0], env); const SpriteText = interpretate.shared.SpriteText.SpriteText; const opts = await core._getRules(args, env); // Build labels mapping const labels = (opts.VertexLabels || []).reduce((acc, { lhs, rhs }) => { acc[lhs] = rhs; return acc; }, {}); // Collect node IDs and construct links const nodeIds = new Set(); const links = data.map(({ lhs, rhs }) => { nodeIds.add(lhs); nodeIds.add(rhs); return { source: String(rhs), target: String(lhs) }; }); // Create nodes with labels const nodes = Array.from(nodeIds).map(id => ({ id: String(id), label: labels[id] || String(id), })); let imageSize = (opts.ImageSize) || 350; if (!Array.isArray(imageSize)) { imageSize = [imageSize, imageSize * 0.7]; } // Initialize the 3D force graph const Graph = ForceGraph3D({})(env.element) .width(imageSize[0]) .height(imageSize[1]) .cooldownTicks(100) .graphData({ nodes, links }) .nodeThreeObject(node => { const sprite = new SpriteText(node.label); sprite.material.depthWrite = true; // Make sprite background transparent sprite.color = 'white'; sprite.textHeight = 12; return sprite; }) .nodeThreeObjectExtend(false); // Apply optional charge strength if ('Charge' in opts) { Graph.d3Force('charge').strength(opts.Charge); } Graph.onEngineStop(() => Graph.zoomToFit(400)); env.local.Graph = Graph; }; core.ForceGraph3D.destroy = () => { console.warn('3D graph was removed'); } //make each instance unique core.ForceGraph3D.virtual = true
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod2) => function __require() { return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports; }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target, mod2 )); // ../../node_modules/ngraph.events/index.js var require_ngraph = __commonJS({ "../../node_modules/ngraph.events/index.js"(exports, module) { module.exports = function eventify(subject) { validateSubject(subject); var eventsStorage = createEventsStorage(subject); subject.on = eventsStorage.on; subject.off = eventsStorage.off; subject.fire = eventsStorage.fire; return subject; }; function createEventsStorage(subject) { var registeredEvents = /* @__PURE__ */ Object.create(null); return { on: function(eventName, callback, ctx) { if (typeof callback !== "function") { throw new Error("callback is expected to be a function"); } var handlers = registeredEvents[eventName]; if (!handlers) { handlers = registeredEvents[eventName] = []; } handlers.push({ callback, ctx }); return subject; }, off: function(eventName, callback) { var wantToRemoveAll = typeof eventName === "undefined"; if (wantToRemoveAll) { registeredEvents = /* @__PURE__ */ Object.create(null); return subject; } if (registeredEvents[eventName]) { var deleteAllCallbacksForEvent = typeof callback !== "function"; if (deleteAllCallbacksForEvent) { delete registeredEvents[eventName]; } else { var callbacks = registeredEvents[eventName]; for (var i = 0; i < callbacks.length; ++i) { if (callbacks[i].callback === callback) { callbacks.splice(i, 1); } } } } return subject; }, fire: function(eventName) { var callbacks = registeredEvents[eventName]; if (!callbacks) { return subject; } var fireArguments; if (arguments.length > 1) { fireArguments = Array.prototype.splice.call(arguments, 1); } for (var i = 0; i < callbacks.length; ++i) { var callbackInfo = callbacks[i]; callbackInfo.callback.apply(callbackInfo.ctx, fireArguments); } return subject; } }; } function validateSubject(subject) { if (!subject) { throw new Error("Eventify cannot use falsy object as events subject"); } var reservedWords = ["on", "fire", "off"]; for (var i = 0; i < reservedWords.length; ++i) { if (subject.hasOwnProperty(reservedWords[i])) { throw new Error("Subject cannot be eventified, since it already has property '" + reservedWords[i] + "'"); } } } } }); // ../../node_modules/ngraph.graph/index.js var require_ngraph2 = __commonJS({ "../../node_modules/ngraph.graph/index.js"(exports, module) { module.exports = createGraph; var eventify = require_ngraph(); function createGraph(options) { options = options || {}; if ("uniqueLinkId" in options) { console.warn( "ngraph.graph: Starting from version 0.14 `uniqueLinkId` is deprecated.\nUse `multigraph` option instead\n", "\n", "Note: there is also change in default behavior: From now on each graph\nis considered to be not a multigraph by default (each edge is unique)." ); options.multigraph = options.uniqueLinkId; } if (options.multigraph === void 0) options.multigraph = false; if (typeof Map !== "function") { throw new Error("ngraph.graph requires `Map` to be defined. Please polyfill it before using ngraph"); } var nodes = /* @__PURE__ */ new Map(); var links = /* @__PURE__ */ new Map(); var multiEdges = {}; var suspendEvents = 0; var createLink = options.multigraph ? createUniqueLink : createSingleLink, changes = [], recordLinkChange = noop2, recordNodeChange = noop2, enterModification = noop2, exitModification = noop2; var graphPart = { /** * Sometimes duck typing could be slow. Giving clients a hint about data structure * via explicit version number here: */ version: 20, /** * Adds node to the graph. If node with given id already exists in the graph * its data is extended with whatever comes in 'data' argument. * * @param nodeId the node's identifier. A string or number is preferred. * @param [data] additional data for the node being added. If node already * exists its data object is augmented with the new one. * * @return {node} The newly added node or node with given id if it already exists. */ addNode, /** * Adds a link to the graph. The function always create a new * link between two nodes. If one of the nodes does not exists * a new node is created. * * @param fromId link start node id; * @param toId link end node id; * @param [data] additional data to be set on the new link; * * @return {link} The newly created link */ addLink, /** * Removes link from the graph. If link does not exist does nothing. * * @param link - object returned by addLink() or getLinks() methods. * * @returns true if link was removed; false otherwise. */ removeLink, /** * Removes node with given id from the graph. If node does not exist in the graph * does nothing. * * @param nodeId node's identifier passed to addNode() function. * * @returns true if node was removed; false otherwise. */ removeNode, /** * Gets node with given identifier. If node does not exist undefined value is returned. * * @param nodeId requested node identifier; * * @return {node} in with requested identifier or undefined if no such node exists. */ getNode, /** * Gets number of nodes in this graph. * * @return number of nodes in the graph. */ getNodeCount, /** * Gets total number of links in the graph. */ getLinkCount, /** * Gets total number of links in the graph. */ getEdgeCount: getLinkCount, /** * Synonym for `getLinkCount()` */ getLinksCount: getLinkCount, /** * Synonym for `getNodeCount()` */ getNodesCount: getNodeCount, /** * Gets all links (inbound and outbound) from the node with given id. * If node with given id is not found null is returned. * * @param nodeId requested node identifier. * * @return Set of links from and to requested node if such node exists; * otherwise null is returned. */ getLinks, /** * Invokes callback on each node of the graph. * * @param {Function(node)} callback Function to be invoked. The function * is passed one argument: visited node. */ forEachNode, /** * Invokes callback on every linked (adjacent) node to the given one. * * @param nodeId Identifier of the requested node. * @param {Function(node, link)} callback Function to be called on all linked nodes. * The function is passed two parameters: adjacent node and link object itself. * @param oriented if true graph treated as oriented. */ forEachLinkedNode, /** * Enumerates all links in the graph * * @param {Function(link)} callback Function to be called on all links in the graph. * The function is passed one parameter: graph's link object. * * Link object contains at least the following fields: * fromId - node id where link starts; * toId - node id where link ends, * data - additional data passed to graph.addLink() method. */ forEachLink, /** * Suspend all notifications about graph changes until * endUpdate is called. */ beginUpdate: enterModification, /** * Resumes all notifications about graph changes and fires * graph 'changed' event in case there are any pending changes. */ endUpdate: exitModification, /** * Removes all nodes and links from the graph. */ clear, /** * Detects whether there is a link between two nodes. * Operation complexity is O(n) where n - number of links of a node. * NOTE: this function is synonym for getLink() * * @returns link if there is one. null otherwise. */ hasLink: getLink, /** * Detects whether there is a node with given id * * Operation complexity is O(1) * NOTE: this function is synonym for getNode() * * @returns node if there is one; Falsy value otherwise. */ hasNode: getNode, /** * Gets an edge between two nodes. * Operation complexity is O(n) where n - number of links of a node. * * @param {string} fromId link start identifier * @param {string} toId link end identifier * * @returns link if there is one; undefined otherwise. */ getLink }; eventify(graphPart); monitorSubscribers(); return graphPart; function monitorSubscribers() { var realOn = graphPart.on; graphPart.on = on; function on() { graphPart.beginUpdate = enterModification = enterModificationReal; graphPart.endUpdate = exitModification = exitModificationReal; recordLinkChange = recordLinkChangeReal; recordNodeChange = recordNodeChangeReal; graphPart.on = realOn; return realOn.apply(graphPart, arguments); } } function recordLinkChangeReal(link, changeType) { changes.push({ link, changeType }); } function recordNodeChangeReal(node, changeType) { changes.push({ node, changeType }); } function addNode(nodeId, data) { if (nodeId === void 0) { throw new Error("Invalid node identifier"); } enterModification(); var node = getNode(nodeId); if (!node) { node = new Node2(nodeId, data); recordNodeChange(node, "add"); } else { node.data = data; recordNodeChange(node, "update"); } nodes.set(nodeId, node); exitModification(); return node; } function getNode(nodeId) { return nodes.get(nodeId); } function removeNode(nodeId) { var node = getNode(nodeId); if (!node) { return false; } enterModification(); var prevLinks = node.links; if (prevLinks) { prevLinks.forEach(removeLinkInstance); node.links = null; } nodes.delete(nodeId); recordNodeChange(node, "remove"); exitModification(); return true; } function addLink(fromId, toId, data) { enterModification(); var fromNode = getNode(fromId) || addNode(fromId); var toNode = getNode(toId) || addNode(toId); var link = createLink(fromId, toId, data); var isUpdate = links.has(link.id); links.set(link.id, link); addLinkToNode(fromNode, link); if (fromId !== toId) { addLinkToNode(toNode, link); } recordLinkChange(link, isUpdate ? "update" : "add"); exitModification(); return link; } function createSingleLink(fromId, toId, data) { var linkId = makeLinkId(fromId, toId); var prevLink = links.get(linkId); if (prevLink) { prevLink.data = data; return prevLink; } return new Link(fromId, toId, data, linkId); } function createUniqueLink(fromId, toId, data) { var linkId = makeLinkId(fromId, toId); var isMultiEdge = multiEdges.hasOwnProperty(linkId); if (isMultiEdge || getLink(fromId, toId)) { if (!isMultiEdge) { multiEdges[linkId] = 0; } var suffix = "@" + ++multiEdges[linkId]; linkId = makeLinkId(fromId + suffix, toId + suffix); } return new Link(fromId, toId, data, linkId); } function getNodeCount() { return nodes.size; } function getLinkCount() { return links.size; } function getLinks(nodeId) { var node = getNode(nodeId); return node ? node.links : null; } function removeLink(link, otherId) { if (otherId !== void 0) { link = getLink(link, otherId); } return removeLinkInstance(link); } function removeLinkInstance(link) { if (!link) { return false; } if (!links.get(link.id)) return false; enterModification(); links.delete(link.id); var fromNode = getNode(link.fromId); var toNode = getNode(link.toId); if (fromNode) { fromNode.links.delete(link); } if (toNode) { toNode.links.delete(link); } recordLinkChange(link, "remove"); exitModification(); return true; } function getLink(fromNodeId, toNodeId) { if (fromNodeId === void 0 || toNodeId === void 0) return void 0; return links.get(makeLinkId(fromNodeId, toNodeId)); } function clear() { enterModification(); forEachNode(function(node) { removeNode(node.id); }); exitModification(); } function forEachLink(callback) { if (typeof callback === "function") { var valuesIterator = links.values(); var nextValue = valuesIterator.next(); while (!nextValue.done) { if (callback(nextValue.value)) { return true; } nextValue = valuesIterator.next(); } } } function forEachLinkedNode(nodeId, callback, oriented) { var node = getNode(nodeId); if (node && node.links && typeof callback === "function") { if (oriented) { return forEachOrientedLink(node.links, nodeId, callback); } else { return forEachNonOrientedLink(node.links, nodeId, callback); } } } function forEachNonOrientedLink(links2, nodeId, callback) { var quitFast; var valuesIterator = links2.values(); var nextValue = valuesIterator.next(); while (!nextValue.done) { var link = nextValue.value; var linkedNodeId = link.fromId === nodeId ? link.toId : link.fromId; quitFast = callback(nodes.get(linkedNodeId), link); if (quitFast) { return true; } nextValue = valuesIterator.next(); } } function forEachOrientedLink(links2, nodeId, callback) { var quitFast; var valuesIterator = links2.values(); var nextValue = valuesIterator.next(); while (!nextValue.done) { var link = nextValue.value; if (link.fromId === nodeId) { quitFast = callback(nodes.get(link.toId), link); if (quitFast) { return true; } } nextValue = valuesIterator.next(); } } function noop2() { } function enterModificationReal() { suspendEvents += 1; } function exitModificationReal() { suspendEvents -= 1; if (suspendEvents === 0 && changes.length > 0) { graphPart.fire("changed", changes); changes.length = 0; } } function forEachNode(callback) { if (typeof callback !== "function") { throw new Error("Function is expected to iterate over graph nodes. You passed " + callback); } var valuesIterator = nodes.values(); var nextValue = valuesIterator.next(); while (!nextValue.done) { if (callback(nextValue.value)) { return true; } nextValue = valuesIterator.next(); } } } function Node2(id2, data) { this.id = id2; this.links = null; this.data = data; } function addLinkToNode(node, link) { if (node.links) { node.links.add(link); } else { node.links = /* @__PURE__ */ new Set([link]); } } function Link(fromId, toId, data, id2) { this.fromId = fromId; this.toId = toId; this.data = data; this.id = id2; } function makeLinkId(fromId, toId) { return fromId.toString() + "\u{1F449} " + toId.toString(); } } }); // ../../node_modules/ngraph.forcelayout/lib/codeGenerators/getVariableName.js var require_getVariableName = __commonJS({ "../../node_modules/ngraph.forcelayout/lib/codeGenerators/getVariableName.js"(exports, module) { module.exports = function getVariableName(index5) { if (index5 === 0) return "x"; if (index5 === 1) return "y"; if (index5 === 2) return "z"; return "c" + (index5 + 1); }; } }); // ../../node_modules/ngraph.forcelayout/lib/codeGenerators/createPatternBuilder.js var require_createPatternBuilder = __commonJS({ "../../node_modules/ngraph.forcelayout/lib/codeGenerators/createPatternBuilder.js"(exports, module) { var getVariableName = require_getVariableName(); module.exports = function createPatternBuilder(dimension) { return pattern; function pattern(template, config) { let indent = config && config.indent || 0; let join = config && config.join !== void 0 ? config.join : "\n"; let indentString = Array(indent + 1).join(" "); let buffer2 = []; for (let i = 0; i < dimension; ++i) { let variableName = getVariableName(i); let prefix = i === 0 ? "" : indentString; buffer2.push(prefix + template.replace(/{var}/g, variableName)); } return buffer2.join(join); } }; } }); // ../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateBody.js var require_generateCreateBody = __commonJS({ "../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateBody.js"(exports, module) { var createPatternBuilder = require_createPatternBuilder(); module.exports = generateCreateBodyFunction; module.exports.generateCreateBodyFunctionBody = generateCreateBodyFunctionBody; module.exports.getVectorCode = getVectorCode; module.exports.getBodyCode = getBodyCode; function generateCreateBodyFunction(dimension, debugSetters) { let code = generateCreateBodyFunctionBody(dimension, debugSetters); let { Body } = new Function(code)(); return Body; } function generateCreateBodyFunctionBody(dimension, debugSetters) { let code = ` ${getVectorCode(dimension, debugSetters)} ${getBodyCode(dimension, debugSetters)} return {Body: Body, Vector: Vector}; `; return code; } function getBodyCode(dimension) { let pattern = createPatternBuilder(dimension); let variableList = pattern("{var}", { join: ", " }); return ` function Body(${variableList}) { this.isPinned = false; this.pos = new Vector(${variableList}); this.force = new Vector(); this.velocity = new Vector(); this.mass = 1; this.springCount = 0; this.springLength = 0; } Body.prototype.reset = function() { this.force.reset(); this.springCount = 0; this.springLength = 0; } Body.prototype.setPosition = function (${variableList}) { ${pattern("this.pos.{var} = {var} || 0;", { indent: 2 })} };`; } function getVectorCode(dimension, debugSetters) { let pattern = createPatternBuilder(dimension); let setters = ""; if (debugSetters) { setters = `${pattern("\n var v{var};\nObject.defineProperty(this, '{var}', {\n set: function(v) { \n if (!Number.isFinite(v)) throw new Error('Cannot set non-numbers to {var}');\n v{var} = v; \n },\n get: function() { return v{var}; }\n});")}`; } let variableList = pattern("{var}", { join: ", " }); return `function Vector(${variableList}) { ${setters} if (typeof arguments[0] === 'object') { // could be another vector let v = arguments[0]; ${pattern('if (!Number.isFinite(v.{var})) throw new Error("Expected value is not a finite number at Vector constructor ({var})");', { indent: 4 })} ${pattern("this.{var} = v.{var};", { indent: 4 })} } else { ${pattern('this.{var} = typeof {var} === "number" ? {var} : 0;', { indent: 4 })} } } Vector.prototype.reset = function () { ${pattern("this.{var} = ", { join: "" })}0; };`; } } }); // ../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateQuadTree.js var require_generateQuadTree = __commonJS({ "../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateQuadTree.js"(exports, module) { var createPatternBuilder = require_createPatternBuilder(); var getVariableName = require_getVariableName(); module.exports = generateQuadTreeFunction; module.exports.generateQuadTreeFunctionBody = generateQuadTreeFunctionBody; module.exports.getInsertStackCode = getInsertStackCode; module.exports.getQuadNodeCode = getQuadNodeCode; module.exports.isSamePosition = isSamePosition; module.exports.getChildBodyCode = getChildBodyCode; module.exports.setChildBodyCode = setChildBodyCode; function generateQuadTreeFunction(dimension) { let code = generateQuadTreeFunctionBody(dimension); return new Function(code)(); } function generateQuadTreeFunctionBody(dimension) { let pattern = createPatternBuilder(dimension); let quadCount = Math.pow(2, dimension); let code = ` ${getInsertStackCode()} ${getQuadNodeCode(dimension)} ${isSamePosition(dimension)} ${getChildBodyCode(dimension)} ${setChildBodyCode(dimension)} function createQuadTree(options, random) { options = options || {}; options.gravity = typeof options.gravity === 'number' ? options.gravity : -1; options.theta = typeof options.theta === 'number' ? options.theta : 0.8; var gravity = options.gravity; var updateQueue = []; var insertStack = new InsertStack(); var theta = options.theta; var nodesCache = []; var currentInCache = 0; var root = newNode(); return { insertBodies: insertBodies, /** * Gets root node if it is present */ getRoot: function() { return root; }, updateBodyForce: update, options: function(newOptions) { if (newOptions) { if (typeof newOptions.gravity === 'number') { gravity = newOptions.gravity; } if (typeof newOptions.theta === 'number') { theta = newOptions.theta; } return this; } return { gravity: gravity, theta: theta }; } }; function newNode() { // To avoid pressure on GC we reuse nodes. var node = nodesCache[currentInCache]; if (node) { ${assignQuads(" node.")} node.body = null; node.mass = ${pattern("node.mass_{var} = ", { join: "" })}0; ${pattern("node.min_{var} = node.max_{var} = ", { join: "" })}0; } else { node = new QuadNode(); nodesCache[currentInCache] = node; } ++currentInCache; return node; } function update(sourceBody) { var queue = updateQueue; var v; ${pattern("var d{var};", { indent: 4 })} var r; ${pattern("var f{var} = 0;", { indent: 4 })} var queueLength = 1; var shiftIdx = 0; var pushIdx = 1; queue[0] = root; while (queueLength) { var node = queue[shiftIdx]; var body = node.body; queueLength -= 1; shiftIdx += 1; var differentBody = (body !== sourceBody); if (body && differentBody) { // If the current node is a leaf node (and it is not source body), // calculate the force exerted by the current node on body, and add this // amount to body's net force. ${pattern("d{var} = body.pos.{var} - sourceBody.pos.{var};", { indent: 8 })} r = Math.sqrt(${pattern("d{var} * d{var}", { join: " + " })}); if (r === 0) { // Poor man's protection against zero distance. ${pattern("d{var} = (random.nextDouble() - 0.5) / 50;", { indent: 10 })} r = Math.sqrt(${pattern("d{var} * d{var}", { join: " + " })}); } // This is standard gravitation force calculation but we divide // by r^3 to save two operations when normalizing force vector. v = gravity * body.mass * sourceBody.mass / (r * r * r); ${pattern("f{var} += v * d{var};", { indent: 8 })} } else if (differentBody) { // Otherwise, calculate the ratio s / r, where s is the width of the region // represented by the internal node, and r is the distance between the body // and the node's center-of-mass ${pattern("d{var} = node.mass_{var} / node.mass - sourceBody.pos.{var};", { indent: 8 })} r = Math.sqrt(${pattern("d{var} * d{var}", { join: " + " })}); if (r === 0) { // Sorry about code duplication. I don't want to create many functions // right away. Just want to see performance first. ${pattern("d{var} = (random.nextDouble() - 0.5) / 50;", { indent: 10 })} r = Math.sqrt(${pattern("d{var} * d{var}", { join: " + " })}); } // If s / r < \u03B8, treat this internal node as a single body, and calculate the // force it exerts on sourceBody, and add this amount to sourceBody's net force. if ((node.max_${getVariableName(0)} - node.min_${getVariableName(0)}) / r < theta) { // in the if statement above we consider node's width only // because the region was made into square during tree creation. // Thus there is no difference between using width or height. v = gravity * node.mass * sourceBody.mass / (r * r * r); ${pattern("f{var} += v * d{var};", { indent: 10 })} } else { // Otherwise, run the procedure recursively on each of the current node's children. // I intentionally unfolded this loop, to save several CPU cycles. ${runRecursiveOnChildren()} } } } ${pattern("sourceBody.force.{var} += f{var};", { indent: 4 })} } function insertBodies(bodies) { ${pattern("var {var}min = Number.MAX_VALUE;", { indent: 4 })} ${pattern("var {var}max = Number.MIN_VALUE;", { indent: 4 })} var i = bodies.length; // To reduce quad tree depth we are looking for exact bounding box of all particles. while (i--) { var pos = bodies[i].pos; ${pattern("if (pos.{var} < {var}min) {var}min = pos.{var};", { indent: 6 })} ${pattern("if (pos.{var} > {var}max) {var}max = pos.{var};", { indent: 6 })} } // Makes the bounds square. var maxSideLength = -Infinity; ${pattern("if ({var}max - {var}min > maxSideLength) maxSideLength = {var}max - {var}min ;", { indent: 4 })} currentInCache = 0; root = newNode(); ${pattern("root.min_{var} = {var}min;", { indent: 4 })} ${pattern("root.max_{var} = {var}min + maxSideLength;", { indent: 4 })} i = bodies.length - 1; if (i >= 0) { root.body = bodies[i]; } while (i--) { insert(bodies[i], root); } } function insert(newBody) { insertStack.reset(); insertStack.push(root, newBody); while (!insertStack.isEmpty()) { var stackItem = insertStack.pop(); var node = stackItem.node; var body = stackItem.body; if (!node.body) { // This is internal node. Update the total mass of the node and center-of-mass. ${pattern("var {var} = body.pos.{var};", { indent: 8 })} node.mass += body.mass; ${pattern("node.mass_{var} += body.mass * {var};", { indent: 8 })} // Recursively insert the body in the appropriate quadrant. // But first find the appropriate quadrant. var quadIdx = 0; // Assume we are in the 0's quad. ${pattern("var min_{var} = node.min_{var};", { indent: 8 })} ${pattern("var max_{var} = (min_{var} + node.max_{var}) / 2;", { indent: 8 })} ${assignInsertionQuadIndex(8)} var child = getChild(node, quadIdx); if (!child) { // The node is internal but this quadrant is not taken. Add // subnode to it. child = newNode(); ${pattern("child.min_{var} = min_{var};", { indent: 10 })} ${pattern("child.max_{var} = max_{var};", { indent: 10 })} child.body = body; setChild(node, quadIdx, child); } else { // continue searching in this quadrant. insertStack.push(child, body); } } else { // We are trying to add to the leaf node. // We have to convert current leaf into internal node // and continue adding two nodes. var oldBody = node.body; node.body = null; // internal nodes do not cary bodies if (isSamePosition(oldBody.pos, body.pos)) { // Prevent infinite subdivision by bumping one node // anywhere in this quadrant var retriesCount = 3; do { var offset = random.nextDouble(); ${pattern("var d{var} = (node.max_{var} - node.min_{var}) * offset;", { indent: 12 })} ${pattern("oldBody.pos.{var} = node.min_{var} + d{var};", { indent: 12 })} retriesCount -= 1; // Make sure we don't bump it out of the box. If we do, next iteration should fix it } while (retriesCount > 0 && isSamePosition(oldBody.pos, body.pos)); if (retriesCount === 0 && isSamePosition(oldBody.pos, body.pos)) { // This is very bad, we ran out of precision. // if we do not return from the method we'll get into // infinite loop here. So we sacrifice correctness of layout, and keep the app running // Next layout iteration should get larger bounding box in the first step and fix this return; } } // Next iteration should subdivide node further. insertStack.push(node, oldBody); insertStack.push(node, body); } } } } return createQuadTree; `; return code; function assignInsertionQuadIndex(indentCount) { let insertionCode = []; let indent = Array(indentCount + 1).join(" "); for (let i = 0; i < dimension; ++i) { insertionCode.push(indent + `if (${getVariableName(i)} > max_${getVariableName(i)}) {`); insertionCode.push(indent + ` quadIdx = quadIdx + ${Math.pow(2, i)};`); insertionCode.push(indent + ` min_${getVariableName(i)} = max_${getVariableName(i)};`); insertionCode.push(indent + ` max_${getVariableName(i)} = node.max_${getVariableName(i)};`); insertionCode.push(indent + `}`); } return insertionCode.join("\n"); } function runRecursiveOnChildren() { let indent = Array(11).join(" "); let recursiveCode = []; for (let i = 0; i < quadCount; ++i) { recursiveCode.push(indent + `if (node.quad${i}) {`); recursiveCode.push(indent + ` queue[pushIdx] = node.quad${i};`); recursiveCode.push(indent + ` queueLength += 1;`); recursiveCode.push(indent + ` pushIdx += 1;`); recursiveCode.push(indent + `}`); } return recursiveCode.join("\n"); } function assignQuads(indent) { let quads = []; for (let i = 0; i < quadCount; ++i) { quads.push(`${indent}quad${i} = null;`); } return quads.join("\n"); } } function isSamePosition(dimension) { let pattern = createPatternBuilder(dimension); return ` function isSamePosition(point1, point2) { ${pattern("var d{var} = Math.abs(point1.{var} - point2.{var});", { indent: 2 })} return ${pattern("d{var} < 1e-8", { join: " && " })}; } `; } function setChildBodyCode(dimension) { var quadCount = Math.pow(2, dimension); return ` function setChild(node, idx, child) { ${setChildBody()} }`; function setChildBody() { let childBody = []; for (let i = 0; i < quadCount; ++i) { let prefix = i === 0 ? " " : " else "; childBody.push(`${prefix}if (idx === ${i}) node.quad${i} = child;`); } return childBody.join("\n"); } } function getChildBodyCode(dimension) { return `function getChild(node, idx) { ${getChildBody()} return null; }`; function getChildBody() { let childBody = []; let quadCount = Math.pow(2, dimension); for (let i = 0; i < quadCount; ++i) { childBody.push(` if (idx === ${i}) return node.quad${i};`); } return childBody.join("\n"); } } function getQuadNodeCode(dimension) { let pattern = createPatternBuilder(dimension); let quadCount = Math.pow(2, dimension); var quadNodeCode = ` function QuadNode() { // body stored inside this node. In quad tree only leaf nodes (by construction) // contain bodies: this.body = null; // Child nodes are stored in quads. Each quad is presented by number: // 0 | 1 // ----- // 2 | 3 ${assignQuads(" this.")} // Total mass of current node this.mass = 0; // Center of mass coordinates ${pattern("this.mass_{var} = 0;", { indent: 2 })} // bounding box coordinates ${pattern("this.min_{var} = 0;", { indent: 2 })} ${pattern("this.max_{var} = 0;", { indent: 2 })} } `; return quadNodeCode; function assignQuads(indent) { let quads = []; for (let i = 0; i < quadCount; ++i) { quads.push(`${indent}quad${i} = null;`); } return quads.join("\n"); } } function getInsertStackCode() { return ` /** * Our implementation of QuadTree is non-recursive to avoid GC hit * This data structure represent stack of elements * which we are trying to insert into quad tree. */ function InsertStack () { this.stack = []; this.popIdx = 0; } InsertStack.prototype = { isEmpty: function() { return this.popIdx === 0; }, push: function (node, body) { var item = this.stack[this.popIdx]; if (!item) { // we are trying to avoid memory pressure: create new element // only when absolutely necessary this.stack[this.popIdx] = new InsertStackElement(node, body); } else { item.node = node; item.body = body; } ++this.popIdx; }, pop: function () { if (this.popIdx > 0) { return this.stack[--this.popIdx]; } }, reset: function () { this.popIdx = 0; } }; function InsertStackElement(node, body) { this.node = node; // QuadTree node this.body = body; // physical body which needs to be inserted to node } `; } } }); // ../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateBounds.js var require_generateBounds = __commonJS({ "../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateBounds.js"(exports, module) { module.exports = generateBoundsFunction; module.exports.generateFunctionBody = generateBoundsFunctionBody; var createPatternBuilder = require_createPatternBuilder(); function generateBoundsFunction(dimension) { let code = generateBoundsFunctionBody(dimension); return new Function("bodies", "settings", "random", code); } function generateBoundsFunctionBody(dimension) { let pattern = createPatternBuilder(dimension); let code = ` var boundingBox = { ${pattern("min_{var}: 0, max_{var}: 0,", { indent: 4 })} }; return { box: boundingBox, update: updateBoundingBox, reset: resetBoundingBox, getBestNewPosition: function (neighbors) { var ${pattern("base_{var} = 0", { join: ", " })}; if (neighbors.length) { for (var i = 0; i < neighbors.length; ++i) { let neighborPos = neighbors[i].pos; ${pattern("base_{var} += neighborPos.{var};", { indent: 10 })} } ${pattern("base_{var} /= neighbors.length;", { indent: 8 })} } else { ${pattern("base_{var} = (boundingBox.min_{var} + boundingBox.max_{var}) / 2;", { indent: 8 })} } var springLength = settings.springLength; return { ${pattern("{var}: base_{var} + (random.nextDouble() - 0.5) * springLength,", { indent: 8 })} }; } }; function updateBoundingBox() { var i = bodies.length; if (i === 0) return; // No bodies - no borders. ${pattern("var max_{var} = -Infinity;", { indent: 4 })} ${pattern("var min_{var} = Infinity;", { indent: 4 })} while(i--) { // this is O(n), it could be done faster with quadtree, if we check the root node bounds var bodyPos = bodies[i].pos; ${pattern("if (bodyPos.{var} < min_{var}) min_{var} = bodyPos.{var};", { indent: 6 })} ${pattern("if (bodyPos.{var} > max_{var}) max_{var} = bodyPos.{var};", { indent: 6 })} } ${pattern("boundingBox.min_{var} = min_{var};", { indent: 4 })} ${pattern("boundingBox.max_{var} = max_{var};", { indent: 4 })} } function resetBoundingBox() { ${pattern("boundingBox.min_{var} = boundingBox.max_{var} = 0;", { indent: 4 })} } `; return code; } } }); // ../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateDragForce.js var require_generateCreateDragForce = __commonJS({ "../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateDragForce.js"(exports, module) { var createPatternBuilder = require_createPatternBuilder(); module.exports = generateCreateDragForceFunction; module.exports.generateCreateDragForceFunctionBody = generateCreateDragForceFunctionBody; function generateCreateDragForceFunction(dimension) { let code = generateCreateDragForceFunctionBody(dimension); return new Function("options", code); } function generateCreateDragForceFunctionBody(dimension) { let pattern = createPatternBuilder(dimension); let code = ` if (!Number.isFinite(options.dragCoefficient)) throw new Error('dragCoefficient is not a finite number'); return { update: function(body) { ${pattern("body.force.{var} -= options.dragCoefficient * body.velocity.{var};", { indent: 6 })} } }; `; return code; } } }); // ../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateSpringForce.js var require_generateCreateSpringForce = __commonJS({ "../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateSpringForce.js"(exports, module) { var createPatternBuilder = require_createPatternBuilder(); module.exports = generateCreateSpringForceFunction; module.exports.generateCreateSpringForceFunctionBody = generateCreateSpringForceFunctionBody; function generateCreateSpringForceFunction(dimension) { let code = generateCreateSpringForceFunctionBody(dimension); return new Function("options", "random", code); } function generateCreateSpringForceFunctionBody(dimension) { let pattern = createPatternBuilder(dimension); let code = ` if (!Number.isFinite(options.springCoefficient)) throw new Error('Spring coefficient is not a number'); if (!Number.isFinite(options.springLength)) throw new Error('Spring length is not a number'); return { /** * Updates forces acting on a spring */ update: function (spring) { var body1 = spring.from; var body2 = spring.to; var length = spring.length < 0 ? options.springLength : spring.length; ${pattern("var d{var} = body2.pos.{var} - body1.pos.{var};", { indent: 6 })} var r = Math.sqrt(${pattern("d{var} * d{var}", { join: " + " })}); if (r === 0) { ${pattern("d{var} = (random.nextDouble() - 0.5) / 50;", { indent: 8 })} r = Math.sqrt(${pattern("d{var} * d{var}", { join: " + " })}); } var d = r - length; var coefficient = ((spring.coefficient > 0) ? spring.coefficient : options.springCoefficient) * d / r; ${pattern("body1.force.{var} += coefficient * d{var}", { indent: 6 })}; body1.springCount += 1; body1.springLength += r; ${pattern("body2.force.{var} -= coefficient * d{var}", { indent: 6 })}; body2.springCount += 1; body2.springLength += r; } }; `; return code; } } }); // ../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateIntegrator.js var require_generateIntegrator = __commonJS({ "../../node_modules/ngraph.forcelayout/lib/codeGenerators/generateIntegrator.js"(exports, module) { var createPatternBuilder = require_createPatternBuilder(); module.exports = generateIntegratorFunction; module.exports.generateIntegratorFunctionBody = generateIntegratorFunctionBody; function generateIntegratorFunction(dimension) { let code = generateIntegratorFunctionBody(dimension); return new Function("bodies", "timeStep", "adaptiveTimeStepWeight", code); } function generateIntegratorFunctionBody(dimension) { let pattern = createPatternBuilder(dimension); let code = ` var length = bodies.length; if (length === 0) return 0; ${pattern("var d{var} = 0, t{var} = 0;", { indent: 2 })} for (var i = 0; i < length; ++i) { var body = bodies[i]; if (body.isPinned) continue; if (adaptiveTimeStepWeight && body.springCount) { timeStep = (adaptiveTimeStepWeight * body.springLength/body.springCount); } var coeff = timeStep / body.mass; ${pattern("body.velocity.{var} += coeff * body.force.{var};", { indent: 4 })} ${pattern("var v{var} = body.velocity.{var};", { indent: 4 })} var v = Math.sqrt(${pattern("v{var} * v{var}", { join: " + " })}); if (v > 1) { // We normalize it so that we move within timeStep range. // for the case when v <= 1 - we let velocity to fade out. ${pattern("body.velocity.{var} = v{var} / v;", { indent: 6 })} } ${pattern("d{var} = timeStep * body.velocity.{var};", { indent: 4 })} ${pattern("body.pos.{var} += d{var};", { indent: 4 })} ${pattern("t{var} += Math.abs(d{var});", { indent: 4 })} } return (${pattern("t{var} * t{var}", { join: " + " })})/length; `; return code; } } }); // ../../node_modules/ngraph.forcelayout/lib/spring.js var require_spring = __commonJS({ "../../node_modules/ngraph.forcelayout/lib/spring.js"(exports, module) { module.exports = Spring; function Spring(fromBody, toBody, length2, springCoefficient) { this.from = fromBody; this.to = toBody; this.length = length2; this.coefficient = springCoefficient; } } }); // ../../node_modules/ngraph.merge/index.js var require_ngraph3 = __commonJS({ "../../node_modules/ngraph.merge/index.js"(exports, module) { module.exports = merge; function merge(target, options) { var key; if (!target) { target = {}; } if (options) { for (key in options) { if (options.hasOwnProperty(key)) { var targetHasIt = target.hasOwnProperty(key), optionsValueType = typeof options[key], shouldReplace = !targetHasIt || typeof target[key] !== optionsValueType; if (shouldReplace) { target[key] = options[key]; } else if (optionsValueType === "object") { target[key] = merge(target[key], options[key]); } } } } return target; } } }); // ../../node_modules/ngraph.random/index.js var require_ngraph4 = __commonJS({ "../../node_modules/ngraph.random/index.js"(exports, module) { module.exports = random; module.exports.random = random, module.exports.randomIterator = randomIterator; function random(inputSeed) { var seed = typeof inputSeed === "number" ? inputSeed : +/* @__PURE__ */ new Date(); return new Generator(seed); } function Generator(seed) { this.seed = seed; } Generator.prototype.next = next; Generator.prototype.nextDouble = nextDouble; Generator.prototype.uniform = nextDouble; Generator.prototype.gaussian = gaussian; function gaussian() { var r, x2, y2; do { x2 = this.nextDouble() * 2 - 1; y2 = this.nextDouble() * 2 - 1; r = x2 * x2 + y2 * y2; } while (r >= 1 || r === 0); return x2 * Math.sqrt(-2 * Math.log(r) / r); } Generator.prototype.levy = levy; function levy() { var beta = 3 / 2; var sigma = Math.pow( gamma(1 + beta) * Math.sin(Math.PI * beta / 2) / (gamma((1 + beta) / 2) * beta * Math.pow(2, (beta - 1) / 2)), 1 / beta ); return this.gaussian() * sigma / Math.pow(Math.abs(this.gaussian()), 1 / beta); } function gamma(z2) { return Math.sqrt(2 * Math.PI / z2) * Math.pow(1 / Math.E * (z2 + 1 / (12 * z2 - 1 / (10 * z2))), z2); } function nextDouble() { var seed = this.seed; seed = seed + 2127912214 + (seed << 12) & 4294967295; seed = (seed ^ 3345072700 ^ seed >>> 19) & 4294967295; seed = seed + 374761393 + (seed << 5) & 4294967295; seed = (seed + 3550635116 ^ seed << 9) & 4294967295; seed = seed + 4251993797 + (seed << 3) & 4294967295; seed = (seed ^ 3042594569 ^ seed >>> 16) & 4294967295; this.seed = seed; return (seed & 268435455) / 268435456; } function next(maxValue) { return Math.floor(this.nextDouble() * maxValue); } function randomIterator(array, customRandom) { var localRandom = customRandom || random(); if (typeof localRandom.next !== "function") { throw new Error("customRandom does not match expected API: next() function is missing"); } return { forEach, /** * Shuffles array randomly, in place. */ shuffle }; function shuffle() { var i, j, t; for (i = array.length - 1; i > 0; --i) { j = localRandom.next(i + 1); t = array[j]; array[j] = array[i]; array[i] = t; } return array; } function forEach(callback) { var i, j, t; for (i = array.length - 1; i > 0; --i) { j = localRandom.next(i + 1); t = array[j]; array[j] = array[i]; array[i] = t; callback(t); } if (array.length) { callback(array[0]); } } } } }); // ../../node_modules/ngraph.forcelayout/lib/createPhysicsSimulator.js var require_createPhysicsSimulator = __commonJS({ "../../node_modules/ngraph.forcelayout/lib/createPhysicsSimulator.js"(exports, module) { module.exports = createPhysicsSimulator; var generateCreateBodyFunction = require_generateCreateBody(); var generateQuadTreeFunction = require_generateQuadTree(); var generateBoundsFunction = require_generateBounds(); var generateCreateDragForceFunction = require_generateCreateDragForce(); var generateCreateSpringForceFunction = require_generateCreateSpringForce(); var generateIntegratorFunction = require_generateIntegrator(); var dimensionalCache = {}; function createPhysicsSimulator(settings) { var Spring = require_spring(); var merge = require_ngraph3(); var eventify = require_ngraph(); if (settings) { if (settings.springCoeff !== void 0) throw new Error("springCoeff was renamed to springCoefficient"); if (settings.dragCoeff !== void 0) throw new Error("dragCoeff was renamed to dragCoefficient"); } settings = merge(settings, { /** * Ideal length for links (springs in physical model). */ springLength: 10, /** * Hook's law coefficient. 1 - solid spring. */ springCoefficient: 0.8, /** * Coulomb's law coefficient. It's used to repel nodes thus should be negative * if you make it positive nodes start attract each other :). */ gravity: -12, /** * Theta coefficient from Barnes Hut simulation. Ranged between (0, 1). * The closer it's to 1 the more nodes algorithm will have to go through. * Setting it to one makes Barnes Hut simulation no different from * brute-force forces calculation (each node is considered). */ theta: 0.8, /** * Drag force coefficient. Used to slow down system, thus should be less than 1. * The closer it is to 0 the less tight system will be. */ dragCoefficient: 0.9, // TODO: Need to rename this to something better. E.g. `dragCoefficient` /** * Default time step (dt) for forces integration */ timeStep: 0.5, /** * Adaptive time step uses average spring length to compute actual time step: * See: https://twitter.com/anvaka/status/1293067160755957760 */ adaptiveTimeStepWeight: 0, /** * This parameter defines number of dimensions of the space where simulation * is performed. */ dimensions: 2, /** * In debug mode more checks are performed, this will help you catch errors * quickly, however for production build it is recommended to turn off this flag * to speed up computation. */ debug: false }); var factory = dimensionalCache[settings.dimensions]; if (!factory) { var dimensions = settings.dimensions; factory = { Body: generateCreateBodyFunction(dimensions, settings.debug), createQuadTree: generateQuadTreeFunction(dimensions), createBounds: generateBoundsFunction(dimensions), createDragForce: generateCreateDragForceFunction(dimensions), createSpringForce: generateCreateSpringForceFunction(dimensions), integrate: generateIntegratorFunction(dimensions) }; dimensionalCache[dimensions] = factory; } var Body = factory.Body; var createQuadTree = factory.createQuadTree; var createBounds = factory.createBounds; var createDragForce = factory.createDragForce; var createSpringForce = factory.createSpringForce; var integrate = factory.integrate; var createBody = (pos) => new Body(pos); var random = require_ngraph4().random(42); var bodies = []; var springs = []; var quadTree = createQuadTree(settings, random); var bounds = createBounds(bodies, settings, random); var springForce = createSpringForce(settings, random); var dragForce = createDragForce(settings); var totalMovement = 0; var forces = []; var forceMap = /* @__PURE__ */ new Map(); var iterationNumber = 0; addForce("nbody", nbodyForce); addForce("spring", updateSpringForce); var publicApi = { /** * Array of bodies, registered with current simulator * * Note: To add new body, use addBody() method. This property is only * exposed for testing/performance purposes. */ bodies, quadTree, /** * Array of springs, registered with current simulator * * Note: To add new spring, use addSpring() method. This property is only * exposed for testing/performance purposes. */ springs, /** * Returns settings with which current simulator was initialized */ settings, /** * Adds a new force to simulation */ addForce, /** * Removes a force from the simulation. */ removeForce, /** * Returns a map of all registered forces. */ getForces, /** * Performs one step of force simulation. * * @returns {boolean} true if system is considered stable; False otherwise. */ step: function() { for (var i = 0; i < forces.length; ++i) { forces[i](iterationNumber); } var movement = integrate(bodies, settings.timeStep, settings.adaptiveTimeStepWeight); iterationNumber += 1; return movement; }, /** * Adds body to the system * * @param {ngraph.physics.primitives.Body} body physical body * * @returns {ngraph.physics.primitives.Body} added body */ addBody: function(body) { if (!body) { throw new Error("Body is required"); } bodies.push(body); return body; }, /** * Adds body to the system at given position * * @param {Object} pos position of a body * * @returns {ngraph.physics.primitives.Body} added body */ addBodyAt: function(pos) { if (!pos) { throw new Error("Body position is required"); } var body = createBody(pos); bodies.push(body); return body; }, /** * Removes body from the system * * @param {ngraph.physics.primitives.Body} body to remove * * @returns {Boolean} true if body found and removed. falsy otherwise; */ removeBody: function(body) { if (!body) { return; } var idx = bodies.indexOf(body); if (idx < 0) { return; } bodies.splice(idx, 1); if (bodies.length === 0) { bounds.reset(); } return true; }, /** * Adds a spring to this simulation. * * @returns {Object} - a handle for a spring. If you want to later remove * spring pass it to removeSpring() method. */ addSpring: function(body1, body2, springLength, springCoefficient) { if (!body1 || !body2) { throw new Error("Cannot add null spring to force simulator"); } if (typeof springLength !== "number") { springLength = -1; } var spring = new Spring(body1, body2, springLength, springCoefficient >= 0 ? springCoefficient : -1); springs.push(spring); return spring; }, /** * Returns amount of movement performed on last step() call */ getTotalMovement: function() { return totalMovement; }, /** * Removes spring from the system * * @param {Object} spring to remove. Spring is an object returned by addSpring * * @returns {Boolean} true if spring found and removed. falsy otherwise; */ removeSpring: function(spring) { if (!spring) { return; } var idx = springs.indexOf(spring); if (idx > -1) { springs.splice(idx, 1); return true; } }, getBestNewBodyPosition: function(neighbors) { return bounds.getBestNewPosition(neighbors); }, /** * Returns bounding box which covers all bodies */ getBBox: getBoundingBox, getBoundingBox, invalidateBBox: function() { console.warn("invalidateBBox() is deprecated, bounds always recomputed on `getBBox()` call"); }, // TODO: Move the force specific stuff to force gravity: function(value) { if (value !== void 0) { settings.gravity = value; quadTree.options({ gravity: value }); return this; } else { return settings.gravity; } }, theta: function(value) { if (value !== void 0) { settings.theta = value; quadTree.options({ theta: value }); return this; } else { return settings.theta; } }, /** * Returns pseudo-random number generator instance. */ random }; expose(settings, publicApi); eventify(publicApi); return publicApi; function getBoundingBox() { bounds.update(); return bounds.box; } function addForce(forceName, forceFunction) { if (forceMap.has(forceName)) throw new Error("Force " + forceName + " is already added"); forceMap.set(forceName, forceFunction); forces.push(forceFunction); } function removeForce(forceName) { var forceIndex = forces.indexOf(forceMap.get(forceName)); if (forceIndex < 0) return; forces.splice(forceIndex, 1); forceMap.delete(forceName); } function getForces() { return forceMap; } function nbodyForce() { if (bodies.length === 0) return; quadTree.insertBodies(bodies); var i = bodies.length; while (i--) { var body = bodies[i]; if (!body.isPinned) { body.reset(); quadTree.updateBodyForce(body); dragForce.update(body); } } } function updateSpringForce() { var i = springs.length; while (i--) { springForce.update(springs[i]); } } } function expose(settings, target) { for (var key in settings) { augment(settings, target, key); } } function augment(source, target, key) { if (!source.hasOwnProperty(key)) return; if (typeof target[key] === "function") { return; } var sourceIsNumber = Number.isFinite(source[key]); if (sourceIsNumber) { target[key] = function(value) { if (value !== void 0) { if (!Number.isFinite(value)) throw new Error("Value of " + key + " should be a valid number."); source[key] = value; return target; } return source[key]; }; } else { target[key] = function(value) { if (value !== void 0) { source[key] = value; return target; } return source[key]; }; } } } }); // ../../node_modules/ngraph.forcelayout/index.js var require_ngraph5 = __commonJS({ "../../node_modules/ngraph.forcelayout/index.js"(exports, module) { module.exports = createLayout; module.exports.simulator = require_createPhysicsSimulator(); var eventify = require_ngraph(); function createLayout(graph2, physicsSettings) { if (!graph2) { throw new Error("Graph structure cannot be undefined"); } var createSimulator = physicsSettings && physicsSettings.createSimulator || require_createPhysicsSimulator(); var physicsSimulator = createSimulator(physicsSettings); if (Array.isArray(physicsSettings)) throw new Error("Physics settings is expected to be an object"); var nodeMass = graph2.version > 19 ? defaultSetNodeMass : defaultArrayNodeMass; if (physicsSettings && typeof physicsSettings.nodeMass === "function") { nodeMass = physicsSettings.nodeMass; } var nodeBodies = /* @__PURE__ */ new Map(); var springs = {}; var bodiesCount = 0; var springTransform = physicsSimulator.settings.springTransform || noop2; initPhysics(); listenToEvents(); var wasStable = false; var api = { /** * Performs one step of iterative layout algorithm * * @returns {boolean} true if the system should be considered stable; False otherwise. * The system is stable if no further call to `step()` can improve the layout. */ step: function() { if (bodiesCount === 0) { updateStableStatus(true); return true; } var lastMove = physicsSimulator.step(); api.lastMove = lastMove; api.fire("step"); var ratio = lastMove / bodiesCount; var isStableNow = ratio <= 0.01; updateStableStatus(isStableNow); return isStableNow; }, /** * For a given `nodeId` returns position */ getNodePosition: function(nodeId) { return getInitializedBody(nodeId).pos; }, /** * Sets position of a node to a given coordinates * @param {string} nodeId node identifier * @param {number} x position of a node * @param {number} y position of a node * @param {number=} z position of node (only if applicable to body) */ setNodePosition: function(nodeId) { var body = getInitializedBody(nodeId); body.setPosition.apply(body, Array.prototype.slice.call(arguments, 1)); }, /** * @returns {Object} Link position by link id * @returns {Object.from} {x, y} coordinates of link start * @returns {Object.to} {x, y} coordinates of link end */ getLinkPosition: function(linkId) { var spring = springs[linkId]; if (spring) { return { from: spring.from.pos, to: spring.to.pos }; } }, /** * @returns {Object} area required to fit in the graph. Object contains * `x1`, `y1` - top left coordinates * `x2`, `y2` - bottom right coordinates */ getGraphRect: function() { return physicsSimulator.getBBox(); }, /** * Iterates over each body in the layout simulator and performs a callback(body, nodeId) */ forEachBody, /* * Requests layout algorithm to pin/unpin node to its current position * Pinned nodes should not be affected by layout algorithm and always * remain at their position */ pinNode: function(node, isPinned) { var body = getInitializedBody(node.id); body.isPinned = !!isPinned; }, /** * Checks whether given graph's node is currently pinned */ isNodePinned: function(node) { return getInitializedBody(node.id).isPinned; }, /** * Request to release all resources */ dispose: function() { graph2.off("changed", onGraphChanged); api.fire("disposed"); }, /** * Gets physical body for a given node id. If node is not found undefined * value is returned. */ getBody, /** * Gets spring for a given edge. * * @param {string} linkId link identifer. If two arguments are passed then * this argument is treated as formNodeId * @param {string=} toId when defined this parameter denotes head of the link * and first argument is treated as tail of the link (fromId) */ getSpring, /** * Returns length of cumulative force vector. The closer this to zero - the more stable the system is */ getForceVectorLength, /** * [Read only] Gets current physics simulator */ simulator: physicsSimulator, /** * Gets the graph that was used for layout */ graph: graph2, /** * Gets amount of movement performed during last step operation */ lastMove: 0 }; eventify(api); return api; function updateStableStatus(isStableNow) { if (wasStable !== isStableNow) { wasStable = isStableNow; onStableChanged(isStableNow); } } function forEachBody(cb) { nodeBodies.forEach(cb); } function getForceVectorLength() { var fx = 0, fy = 0; forEachBody(function(body) { fx += Math.abs(body.force.x); fy += Math.abs(body.force.y); }); return Math.sqrt(fx * fx + fy * fy); } function getSpring(fromId, toId) { var linkId; if (toId === void 0) { if (typeof fromId !== "object") { linkId = fromId; } else { linkId = fromId.id; } } else { var link = graph2.hasLink(fromId, toId); if (!link) return; linkId = link.id; } return springs[linkId]; } function getBody(nodeId) { return nodeBodies.get(nodeId); } function listenToEvents() { graph2.on("changed", onGraphChanged); } function onStableChanged(isStable) { api.fire("stable", isStable); } function onGraphChanged(changes) { for (var i = 0; i < changes.length; ++i) { var change = changes[i]; if (change.changeType === "add") { if (change.node) { initBody(change.node.id); } if (change.link) { initLink(change.link); } } else if (change.changeType === "remove") { if (change.node) { releaseNode(change.node); } if (change.link) { releaseLink(change.link); } } } bodiesCount = graph2.getNodesCount(); } function initPhysics() { bodiesCount = 0; graph2.forEachNode(function(node) { initBody(node.id); bodiesCount += 1; }); graph2.forEachLink(initLink); } function initBody(nodeId) { var body = nodeBodies.get(nodeId); if (!body) { var node = graph2.getNode(nodeId); if (!node) { throw new Error("initBody() was called with unknown node id"); } var pos = node.position; if (!pos) { var neighbors = getNeighborBodies(node); pos = physicsSimulator.getBestNewBodyPosition(neighbors); } body = physicsSimulator.addBodyAt(pos); body.id = nodeId; nodeBodies.set(nodeId, body); updateBodyMass(nodeId); if (isNodeOriginallyPinned(node)) { body.isPinned = true; } } } function releaseNode(node) { var nodeId = node.id; var body = nodeBodies.get(nodeId); if (body) { nodeBodies.delete(nodeId); physicsSimulator.removeBody(body); } } function initLink(link) { updateBodyMass(link.fromId); updateBodyMass(link.toId); var fromBody = nodeBodies.get(link.fromId), toBody = nodeBodies.get(link.toId), spring = physicsSimulator.addSpring(fromBody, toBody, link.length); springTransform(link, spring); springs[link.id] = spring; } function releaseLink(link) { var spring = springs[link.id]; if (spring) { var from = graph2.getNode(link.fromId), to = graph2.getNode(link.toId); if (from) updateBodyMass(from.id); if (to) updateBodyMass(to.id); delete springs[link.id]; physicsSimulator.removeSpring(spring); } } function getNeighborBodies(node) { var neighbors = []; if (!node.links) { return neighbors; } var maxNeighbors = Math.min(node.links.length, 2); for (var i = 0; i < maxNeighbors; ++i) { var link = node.links[i]; var otherBody = link.fromId !== node.id ? nodeBodies.get(link.fromId) : nodeBodies.get(link.toId); if (otherBody && otherBody.pos) { neighbors.push(otherBody); } } return neighbors; } function updateBodyMass(nodeId) { var body = nodeBodies.get(nodeId); body.mass = nodeMass(nodeId); if (Number.isNaN(body.mass)) { throw new Error("Node mass should be a number"); } } function isNodeOriginallyPinned(node) { return node && (node.isPinned || node.data && node.data.isPinned); } function getInitializedBody(nodeId) { var body = nodeBodies.get(nodeId); if (!body) { initBody(nodeId); body = nodeBodies.get(nodeId); } return body; } function defaultArrayNodeMass(nodeId) { var links = graph2.getLinks(nodeId); if (!links) return 1; return 1 + links.length / 3; } function defaultSetNodeMass(nodeId) { var links = graph2.getLinks(nodeId); if (!links) return 1; return 1 + links.size / 3; } } function noop2() { } } }); // ../../node_modules/three/build/three.module.js var REVISION = "170"; var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }; var CullFaceNone = 0; var CullFaceBack = 1; var CullFaceFront = 2; var PCFShadowMap = 1; var PCFSoftShadowMap = 2; var VSMShadowMap = 3; var FrontSide = 0; var BackSide = 1; var DoubleSide = 2; var NoBlending = 0; var NormalBlending = 1; var AdditiveBlending = 2; var SubtractiveBlending = 3; var MultiplyBlending = 4; var CustomBlending = 5; var AddEquation = 100; var SubtractEquation = 101; var ReverseSubtractEquation = 102; var MinEquation = 103; var MaxEquation = 104; var ZeroFactor = 200; var OneFactor = 201; var SrcColorFactor = 202; var OneMinusSrcColorFactor = 203; var SrcAlphaFactor = 204; var OneMinusSrcAlphaFactor = 205; var DstAlphaFactor = 206; var OneMinusDstAlphaFactor = 207; var DstColorFactor = 208; var OneMinusDstColorFactor = 209; var SrcAlphaSaturateFactor = 210; var ConstantColorFactor = 211; var OneMinusConstantColorFactor = 212; var ConstantAlphaFactor = 213; var OneMinusConstantAlphaFactor = 214; 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 AgXToneMapping = 6; var NeutralToneMapping = 7; var UVMapping = 300; var CubeReflectionMapping = 301; var CubeRefractionMapping = 302; var EquirectangularReflectionMapping = 303; var EquirectangularRefractionMapping = 304; var CubeUVReflectionMapping = 306; 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 UnsignedInt248Type = 1020; var UnsignedInt5999Type = 35902; var AlphaFormat = 1021; var RGBFormat = 1022; var RGBAFormat = 1023; var LuminanceFormat = 1024; var LuminanceAlphaFormat = 1025; var DepthFormat = 1026; var DepthStencilFormat = 1027; var RedFormat = 1028; var RedIntegerFormat = 1029; var RGFormat = 1030; var RGIntegerFormat = 1031; 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 RGB_BPTC_SIGNED_Format = 36494; var RGB_BPTC_UNSIGNED_Format = 36495; var RED_RGTC1_Format = 36283; var SIGNED_RED_RGTC1_Format = 36284; var RED_GREEN_RGTC2_Format = 36285; var SIGNED_RED_GREEN_RGTC2_Format = 36286; var InterpolateDiscrete = 2300; var InterpolateLinear = 2301; var InterpolateSmooth = 2302; var ZeroCurvatureEnding = 2400; var ZeroSlopeEnding = 2401; var WrapAroundEnding = 2402; var BasicDepthPacking = 3200; var RGBADepthPacking = 3201; var TangentSpaceNormalMap = 0; var ObjectSpaceNormalMap = 1; var NoColorSpace = ""; var SRGBColorSpace = "srgb"; var LinearSRGBColorSpace = "srgb-linear"; var LinearTransfer = "linear"; var SRGBTransfer = "srgb"; var KeepStencilOp = 7680; var AlwaysStencilFunc = 519; var NeverCompare = 512; var LessCompare = 513; var EqualCompare = 514; var LessEqualCompare = 515; var GreaterCompare = 516; var NotEqualCompare = 517; var GreaterEqualCompare = 518; var AlwaysCompare = 519; var StaticDrawUsage = 35044; var GLSL3 = "300 es"; var WebGLCoordinateSystem = 2e3; var WebGPUCoordinateSystem = 2001; var EventDispatcher = class { addEventListener(type, listener) { if (this._listeners === void 0) this._listeners = {}; const listeners = this._listeners; if (listeners[type] === void 0) { listeners[type] = []; } if (listeners[type].indexOf(listener) === -1) { listeners[type].push(listener); } } hasEventListener(type, listener) { if (this._listeners === void 0) return false; const listeners = this._listeners; return listeners[type] !== void 0 && listeners[type].indexOf(listener) !== -1; } removeEventListener(type, listener) { if (this._listeners === void 0) return; const listeners = this._listeners; const listenerArray = listeners[type]; if (listenerArray !== void 0) { const index5 = listenerArray.indexOf(listener); if (index5 !== -1) { listenerArray.splice(index5, 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 = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"]; var _seed = 1234567; 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.toLowerCase(); } function clamp(value, min2, max2) { return Math.max(min2, Math.min(max2, value)); } function euclideanModulo(n, m2) { return (n % m2 + m2) % m2; } function mapLinear(x2, a1, a2, b1, b2) { return b1 + (x2 - a1) * (b2 - b1) / (a2 - a1); } function inverseLerp(x2, y2, value) { if (x2 !== y2) { return (value - x2) / (y2 - x2); } else { return 0; } } function lerp(x2, y2, t) { return (1 - t) * x2 + t * y2; } function damp(x2, y2, lambda, dt) { return lerp(x2, y2, 1 - Math.exp(-lambda * dt)); } function pingpong(x2, length2 = 1) { return length2 - Math.abs(euclideanModulo(x2, length2 * 2) - length2); } function smoothstep(x2, min2, max2) { if (x2 <= min2) return 0; if (x2 >= max2) return 1; x2 = (x2 - min2) / (max2 - min2); return x2 * x2 * (3 - 2 * x2); } function smootherstep(x2, min2, max2) { if (x2 <= min2) return 0; if (x2 >= max2) return 1; x2 = (x2 - min2) / (max2 - min2); return x2 * x2 * x2 * (x2 * (x2 * 6 - 15) + 10); } function randInt(low, high) { return low + Math.floor(Math.random() * (high - low + 1)); } function randFloat(low, high) { return low + Math.random() * (high - low); } function randFloatSpread(range) { return range * (0.5 - Math.random()); } function seededRandom(s) { if (s !== void 0) _seed = s; let t = _seed += 1831565813; t = Math.imul(t ^ t >>> 15, t | 1); t ^= t + Math.imul(t ^ t >>> 7, t | 61); return ((t ^ t >>> 14) >>> 0) / 4294967296; } function degToRad(degrees2) { return degrees2 * DEG2RAD; } function radToDeg(radians2) { return radians2 * RAD2DEG; } function isPowerOfTwo(value) { return (value & value - 1) === 0 && value !== 0; } function ceilPowerOfTwo(value) { return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2)); } function floorPowerOfTwo(value) { return Math.pow(2, Math.floor(Math.log(value) / Math.LN2)); } function setQuaternionFromProperEuler(q, a2, b, c2, order) { const cos2 = Math.cos; const sin2 = Math.sin; const c22 = cos2(b / 2); const s2 = sin2(b / 2); const c13 = cos2((a2 + c2) / 2); const s13 = sin2((a2 + c2) / 2); const c1_3 = cos2((a2 - c2) / 2); const s1_3 = sin2((a2 - c2) / 2); const c3_1 = cos2((c2 - a2) / 2); const s3_1 = sin2((c2 - a2) / 2); switch (order) { case "XYX": q.set(c22 * s13, s2 * c1_3, s2 * s1_3, c22 * c13); break; case "YZY": q.set(s2 * s1_3, c22 * s13, s2 * c1_3, c22 * c13); break; case "ZXZ": q.set(s2 * c1_3, s2 * s1_3, c22 * s13, c22 * c13); break; case "XZX": q.set(c22 * s13, s2 * s3_1, s2 * c3_1, c22 * c13); break; case "YXY": q.set(s2 * c3_1, c22 * s13, s2 * s3_1, c22 * c13); break; case "ZYZ": q.set(s2 * s3_1, s2 * c3_1, c22 * s13, c22 * c13); break; default: console.warn("THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: " + order); } } function denormalize(value, array) { switch (array.constructor) { case Float32Array: return value; case Uint32Array: return value / 4294967295; case Uint16Array: return value / 65535; case Uint8Array: return value / 255; case Int32Array: return Math.max(value / 2147483647, -1); case Int16Array: return Math.max(value / 32767, -1); case Int8Array: return Math.max(value / 127, -1); default: throw new Error("Invalid component type."); } } function normalize(value, array) { switch (array.constructor) { case Float32Array: return value; case Uint32Array: return Math.round(value * 4294967295); case Uint16Array: return Math.round(value * 65535); case Uint8Array: return Math.round(value * 255); case Int32Array: return Math.round(value * 2147483647); case Int16Array: return Math.round(value * 32767); case Int8Array: return Math.round(value * 127); default: throw new Error("Invalid component type."); } } var MathUtils = { DEG2RAD, RAD2DEG, generateUUID, clamp, euclideanModulo, mapLinear, inverseLerp, lerp, damp, pingpong, smoothstep, smootherstep, randInt, randFloat, randFloatSpread, seededRandom, degToRad, radToDeg, isPowerOfTwo, ceilPowerOfTwo, floorPowerOfTwo, setQuaternionFromProperEuler, normalize, denormalize }; var Vector2 = class _Vector2 { constructor(x2 = 0, y2 = 0) { _Vector2.prototype.isVector2 = true; this.x = x2; this.y = y2; } get width() { return this.x; } set width(value) { this.x = value; } get height() { return this.y; } set height(value) { this.y = value; } set(x2, y2) { this.x = x2; this.y = y2; return this; } setScalar(scalar) { this.x = scalar; this.y = scalar; return this; } setX(x2) { this.x = x2; return this; } setY(y2) { this.y = y2; return this; } setComponent(index5, value) { switch (index5) { case 0: this.x = value; break; case 1: this.y = value; break; default: throw new Error("index is out of range: " + index5); } return this; } getComponent(index5) { switch (index5) { case 0: return this.x; case 1: return this.y; default: throw new Error("index is out of range: " + index5); } } clone() { return new this.constructor(this.x, this.y); } copy(v) { this.x = v.x; this.y = v.y; return this; } add(v) { this.x += v.x; this.y += v.y; return this; } addScalar(s) { this.x += s; this.y += s; return this; } addVectors(a2, b) { this.x = a2.x + b.x; this.y = a2.y + b.y; return this; } addScaledVector(v, s) { this.x += v.x * s; this.y += v.y * s; return this; } sub(v) { this.x -= v.x; this.y -= v.y; return this; } subScalar(s) { this.x -= s; this.y -= s; return this; } subVectors(a2, b) { this.x = a2.x - b.x; this.y = a2.y - b.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(m2) { const x2 = this.x, y2 = this.y; const e = m2.elements; this.x = e[0] * x2 + e[3] * y2 + e[6]; this.y = e[1] * x2 + e[4] * y2 + 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(min2, max2) { this.x = Math.max(min2.x, Math.min(max2.x, this.x)); this.y = Math.max(min2.y, Math.min(max2.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(min2, max2) { const length2 = this.length(); return this.divideScalar(length2 || 1).multiplyScalar(Math.max(min2, Math.min(max2, length2))); } 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 = Math.trunc(this.x); this.y = Math.trunc(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; } 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; return dx * dx + dy * dy; } manhattanDistanceTo(v) { return Math.abs(this.x - v.x) + Math.abs(this.y - v.y); } setLength(length2) { return this.normalize().multiplyScalar(length2); } lerp(v, alpha) { this.x += (v.x - this.x) * alpha; this.y += (v.y - this.y) * alpha; return this; } lerpVectors(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.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(attribute2, index5) { this.x = attribute2.getX(index5); this.y = attribute2.getY(index5); return this; } rotateAround(center, angle) { const c2 = Math.cos(angle), s = Math.sin(angle); const x2 = this.x - center.x; const y2 = this.y - center.y; this.x = x2 * c2 - y2 * s + center.x; this.y = x2 * s + y2 * c2 + center.y; return this; } random() { this.x = Math.random(); this.y = Math.random(); return this; } *[Symbol.iterator]() { yield this.x; yield this.y; } }; var Matrix3 = class _Matrix3 { constructor(n11, n12, n13, n21, n22, n23, n31, n32, n33) { _Matrix3.prototype.isMatrix3 = true; this.elements = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; if (n11 !== void 0) { this.set(n11, n12, n13, n21, n22, n23, n31, n32, n33); } } 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(m2) { const te = this.elements; const me = m2.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(m2) { const me = m2.elements; this.set( me[0], me[4], me[8], me[1], me[5], me[9], me[2], me[6], me[10] ); return this; } multiply(m2) { return this.multiplyMatrices(this, m2); } premultiply(m2) { return this.multiplyMatrices(m2, this); } multiplyMatrices(a2, b) { const ae = a2.elements; const be = b.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], b = 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 - b * d * i + b * 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 tmp2; const m2 = this.elements; tmp2 = m2[1]; m2[1] = m2[3]; m2[3] = tmp2; tmp2 = m2[2]; m2[2] = m2[6]; m2[6] = tmp2; tmp2 = m2[5]; m2[5] = m2[7]; m2[7] = tmp2; return this; } getNormalMatrix(matrix4) { return this.setFromMatrix4(matrix4).invert().transpose(); } transposeIntoArray(r) { const m2 = this.elements; r[0] = m2[0]; r[1] = m2[3]; r[2] = m2[6]; r[3] = m2[1]; r[4] = m2[4]; r[5] = m2[7]; r[6] = m2[2]; r[7] = m2[5]; r[8] = m2[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) { this.premultiply(_m3.makeScale(sx, sy)); return this; } rotate(theta) { this.premultiply(_m3.makeRotation(-theta)); return this; } translate(tx, ty) { this.premultiply(_m3.makeTranslation(tx, ty)); return this; } // for 2D Transforms makeTranslation(x2, y2) { if (x2.isVector2) { this.set( 1, 0, x2.x, 0, 1, x2.y, 0, 0, 1 ); } else { this.set( 1, 0, x2, 0, 1, y2, 0, 0, 1 ); } return this; } makeRotation(theta) { const c2 = Math.cos(theta); const s = Math.sin(theta); this.set( c2, -s, 0, s, c2, 0, 0, 0, 1 ); return this; } makeScale(x2, y2) { this.set( x2, 0, 0, 0, y2, 0, 0, 0, 1 ); 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); } }; var _m3 = /* @__PURE__ */ new Matrix3(); function arrayNeedsUint32(array) { for (let i = array.length - 1; i >= 0; --i) { if (array[i] >= 65535) return true; } return false; } function createElementNS(name) { return document.createElementNS("http://www.w3.org/1999/xhtml", name); } function createCanvasElement() { const canvas = createElementNS("canvas"); canvas.style.display = "block"; return canvas; } var _cache = {}; function warnOnce(message) { if (message in _cache) return; _cache[message] = true; console.warn(message); } function probeAsync(gl, sync, interval2) { return new Promise(function(resolve, reject) { function probe() { switch (gl.clientWaitSync(sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0)) { case gl.WAIT_FAILED: reject(); break; case gl.TIMEOUT_EXPIRED: setTimeout(probe, interval2); break; default: resolve(); } } setTimeout(probe, interval2); }); } function toNormalizedProjectionMatrix(projectionMatrix) { const m2 = projectionMatrix.elements; m2[2] = 0.5 * m2[2] + 0.5 * m2[3]; m2[6] = 0.5 * m2[6] + 0.5 * m2[7]; m2[10] = 0.5 * m2[10] + 0.5 * m2[11]; m2[14] = 0.5 * m2[14] + 0.5 * m2[15]; } function toReversedProjectionMatrix(projectionMatrix) { const m2 = projectionMatrix.elements; const isPerspectiveMatrix = m2[11] === -1; if (isPerspectiveMatrix) { m2[10] = -m2[10] - 1; m2[14] = -m2[14]; } else { m2[10] = -m2[10]; m2[14] = -m2[14] + 1; } } var ColorManagement = { enabled: true, workingColorSpace: LinearSRGBColorSpace, /** * Implementations of supported color spaces. * * Required: * - primaries: chromaticity coordinates [ rx ry gx gy bx by ] * - whitePoint: reference white [ x y ] * - transfer: transfer function (pre-defined) * - toXYZ: Matrix3 RGB to XYZ transform * - fromXYZ: Matrix3 XYZ to RGB transform * - luminanceCoefficients: RGB luminance coefficients * * Optional: * - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace } * - workingColorSpaceConfig: { unpackColorSpace: ColorSpace } * * Reference: * - https://www.russellcottrell.com/photo/matrixCalculator.htm */ spaces: {}, convert: function(color2, sourceColorSpace, targetColorSpace) { if (this.enabled === false || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) { return color2; } if (this.spaces[sourceColorSpace].transfer === SRGBTransfer) { color2.r = SRGBToLinear(color2.r); color2.g = SRGBToLinear(color2.g); color2.b = SRGBToLinear(color2.b); } if (this.spaces[sourceColorSpace].primaries !== this.spaces[targetColorSpace].primaries) { color2.applyMatrix3(this.spaces[sourceColorSpace].toXYZ); color2.applyMatrix3(this.spaces[targetColorSpace].fromXYZ); } if (this.spaces[targetColorSpace].transfer === SRGBTransfer) { color2.r = LinearToSRGB(color2.r); color2.g = LinearToSRGB(color2.g); color2.b = LinearToSRGB(color2.b); } return color2; }, fromWorkingColorSpace: function(color2, targetColorSpace) { return this.convert(color2, this.workingColorSpace, targetColorSpace); }, toWorkingColorSpace: function(color2, sourceColorSpace) { return this.convert(color2, sourceColorSpace, this.workingColorSpace); }, getPrimaries: function(colorSpace) { return this.spaces[colorSpace].primaries; }, getTransfer: function(colorSpace) { if (colorSpace === NoColorSpace) return LinearTransfer; return this.spaces[colorSpace].transfer; }, getLuminanceCoefficients: function(target, colorSpace = this.workingColorSpace) { return target.fromArray(this.spaces[colorSpace].luminanceCoefficients); }, define: function(colorSpaces) { Object.assign(this.spaces, colorSpaces); }, // Internal APIs _getMatrix: function(targetMatrix, sourceColorSpace, targetColorSpace) { return targetMatrix.copy(this.spaces[sourceColorSpace].toXYZ).multiply(this.spaces[targetColorSpace].fromXYZ); }, _getDrawingBufferColorSpace: function(colorSpace) { return this.spaces[colorSpace].outputColorSpaceConfig.drawingBufferColorSpace; }, _getUnpackColorSpace: function(colorSpace = this.workingColorSpace) { return this.spaces[colorSpace].workingColorSpaceConfig.unpackColorSpace; } }; 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 REC709_PRIMARIES = [0.64, 0.33, 0.3, 0.6, 0.15, 0.06]; var REC709_LUMINANCE_COEFFICIENTS = [0.2126, 0.7152, 0.0722]; var D65 = [0.3127, 0.329]; var LINEAR_REC709_TO_XYZ = /* @__PURE__ */ new Matrix3().set( 0.4123908, 0.3575843, 0.1804808, 0.212639, 0.7151687, 0.0721923, 0.0193308, 0.1191948, 0.9505322 ); var XYZ_TO_LINEAR_REC709 = /* @__PURE__ */ new Matrix3().set( 3.2409699, -1.5373832, -0.4986108, -0.9692436, 1.8759675, 0.0415551, 0.0556301, -0.203977, 1.0569715 ); ColorManagement.define({ [LinearSRGBColorSpace]: { primaries: REC709_PRIMARIES, whitePoint: D65, transfer: LinearTransfer, toXYZ: LINEAR_REC709_TO_XYZ, fromXYZ: XYZ_TO_LINEAR_REC709, luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS, workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace }, outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace } }, [SRGBColorSpace]: { primaries: REC709_PRIMARIES, whitePoint: D65, transfer: SRGBTransfer, toXYZ: LINEAR_REC709_TO_XYZ, fromXYZ: XYZ_TO_LINEAR_REC709, luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS, outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace } } }); 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 = createElementNS("canvas"); _canvas.width = image.width; _canvas.height = image.height; const context2 = _canvas.getContext("2d"); if (image instanceof ImageData) { context2.putImageData(image, 0, 0); } else { context2.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"); } } static sRGBToLinear(image) { if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) { const canvas = createElementNS("canvas"); canvas.width = image.width; canvas.height = image.height; const context2 = canvas.getContext("2d"); context2.drawImage(image, 0, 0, image.width, image.height); const imageData = context2.getImageData(0, 0, image.width, image.height); const data = imageData.data; for (let i = 0; i < data.length; i++) { data[i] = SRGBToLinear(data[i] / 255) * 255; } context2.putImageData(imageData, 0, 0); return canvas; } else if (image.data) { const data = image.data.slice(0); for (let i = 0; i < data.length; i++) { if (data instanceof Uint8Array || data instanceof Uint8ClampedArray) { data[i] = Math.floor(SRGBToLinear(data[i] / 255) * 255); } else { data[i] = SRGBToLinear(data[i]); } } return { data, width: image.width, height: image.height }; } else { console.warn("THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied."); return image; } } }; var _sourceId = 0; var Source = class { constructor(data = null) { this.isSource = true; Object.defineProperty(this, "id", { value: _sourceId++ }); this.uuid = generateUUID(); this.data = data; this.dataReady = true; this.version = 0; } set needsUpdate(value) { if (value === true) this.version++; } toJSON(meta) { const isRootObject = meta === void 0 || typeof meta === "string"; if (!isRootObject && meta.images[this.uuid] !== void 0) { return meta.images[this.uuid]; } const output2 = { uuid: this.uuid, url: "" }; const data = this.data; if (data !== null) { let url; if (Array.isArray(data)) { url = []; for (let i = 0, l = data.length; i < l; i++) { if (data[i].isDataTexture) { url.push(serializeImage(data[i].image)); } else { url.push(serializeImage(data[i])); } } } else { url = serializeImage(data); } output2.url = url; } if (!isRootObject) { meta.images[this.uuid] = output2; } return output2; } }; 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.from(image.data), width: image.width, height: image.height, type: image.data.constructor.name }; } else { console.warn("THREE.Texture: Unable to serialize Texture."); return {}; } } } var _textureId = 0; var Texture = class _Texture extends EventDispatcher { constructor(image = _Texture.DEFAULT_IMAGE, mapping = _Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format2 = RGBAFormat, type = UnsignedByteType, anisotropy2 = _Texture.DEFAULT_ANISOTROPY, colorSpace = NoColorSpace) { super(); this.isTexture = true; Object.defineProperty(this, "id", { value: _textureId++ }); this.uuid = generateUUID(); this.name = ""; this.source = new Source(image); this.mipmaps = []; this.mapping = mapping; this.channel = 0; this.wrapS = wrapS; this.wrapT = wrapT; this.magFilter = magFilter; this.minFilter = minFilter; this.anisotropy = anisotropy2; this.format = format2; 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.colorSpace = colorSpace; this.userData = {}; this.version = 0; this.onUpdate = null; this.isRenderTargetTexture = false; this.pmremVersion = 0; } get image() { return this.source.data; } set image(value = null) { this.source.data = value; } 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.source = source.source; this.mipmaps = source.mipmaps.slice(0); this.mapping = source.mapping; this.channel = source.channel; 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.colorSpace = source.colorSpace; this.userData = JSON.parse(JSON.stringify(source.userData)); this.needsUpdate = true; 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 output2 = { metadata: { version: 4.6, type: "Texture", generator: "Texture.toJSON" }, uuid: this.uuid, name: this.name, image: this.source.toJSON(meta).uuid, mapping: this.mapping, channel: this.channel, 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, internalFormat: this.internalFormat, type: this.type, colorSpace: this.colorSpace, minFilter: this.minFilter, magFilter: this.magFilter, anisotropy: this.anisotropy, flipY: this.flipY, generateMipmaps: this.generateMipmaps, premultiplyAlpha: this.premultiplyAlpha, unpackAlignment: this.unpackAlignment }; if (Object.keys(this.userData).length > 0) output2.userData = this.userData; if (!isRootObject) { meta.textures[this.uuid] = output2; } return output2; } dispose() { this.dispatchEvent({ type: "dispose" }); } transformUv(uv2) { if (this.mapping !== UVMapping) return uv2; uv2.applyMatrix3(this.matrix); if (uv2.x < 0 || uv2.x > 1) { switch (this.wrapS) { case RepeatWrapping: uv2.x = uv2.x - Math.floor(uv2.x); break; case ClampToEdgeWrapping: uv2.x = uv2.x < 0 ? 0 : 1; break; case MirroredRepeatWrapping: if (Math.abs(Math.floor(uv2.x) % 2) === 1) { uv2.x = Math.ceil(uv2.x) - uv2.x; } else { uv2.x = uv2.x - Math.floor(uv2.x); } break; } } if (uv2.y < 0 || uv2.y > 1) { switch (this.wrapT) { case RepeatWrapping: uv2.y = uv2.y - Math.floor(uv2.y); break; case ClampToEdgeWrapping: uv2.y = uv2.y < 0 ? 0 : 1; break; case MirroredRepeatWrapping: if (Math.abs(Math.floor(uv2.y) % 2) === 1) { uv2.y = Math.ceil(uv2.y) - uv2.y; } else { uv2.y = uv2.y - Math.floor(uv2.y); } break; } } if (this.flipY) { uv2.y = 1 - uv2.y; } return uv2; } set needsUpdate(value) { if (value === true) { this.version++; this.source.needsUpdate = true; } } set needsPMREMUpdate(value) { if (value === true) { this.pmremVersion++; } } }; Texture.DEFAULT_IMAGE = null; Texture.DEFAULT_MAPPING = UVMapping; Texture.DEFAULT_ANISOTROPY = 1; var Vector4 = class _Vector4 { constructor(x2 = 0, y2 = 0, z2 = 0, w = 1) { _Vector4.prototype.isVector4 = true; this.x = x2; this.y = y2; this.z = z2; this.w = w; } get width() { return this.z; } set width(value) { this.z = value; } get height() { return this.w; } set height(value) { this.w = value; } set(x2, y2, z2, w) { this.x = x2; this.y = y2; this.z = z2; this.w = w; return this; } setScalar(scalar) { this.x = scalar; this.y = scalar; this.z = scalar; this.w = scalar; return this; } setX(x2) { this.x = x2; return this; } setY(y2) { this.y = y2; return this; } setZ(z2) { this.z = z2; return this; } setW(w) { this.w = w; return this; } setComponent(index5, value) { switch (index5) { 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: " + index5); } return this; } getComponent(index5) { switch (index5) { 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: " + index5); } } 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) { 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, b) { this.x = a2.x + b.x; this.y = a2.y + b.y; this.z = a2.z + b.z; this.w = a2.w + b.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) { 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, b) { this.x = a2.x - b.x; this.y = a2.y - b.y; this.z = a2.z - b.z; this.w = a2.w - b.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(m2) { const x2 = this.x, y2 = this.y, z2 = this.z, w = this.w; const e = m2.elements; this.x = e[0] * x2 + e[4] * y2 + e[8] * z2 + e[12] * w; this.y = e[1] * x2 + e[5] * y2 + e[9] * z2 + e[13] * w; this.z = e[2] * x2 + e[6] * y2 + e[10] * z2 + e[14] * w; this.w = e[3] * x2 + e[7] * y2 + e[11] * z2 + e[15] * w; return this; } divide(v) { this.x /= v.x; this.y /= v.y; this.z /= v.z; this.w /= v.w; 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(m2) { let angle, x2, y2, z2; const epsilon = 0.01, epsilon2 = 0.1, te = m2.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) { x2 = 0; y2 = 0.707106781; z2 = 0.707106781; } else { x2 = Math.sqrt(xx); y2 = xy / x2; z2 = xz / x2; } } else if (yy > zz) { if (yy < epsilon) { x2 = 0.707106781; y2 = 0; z2 = 0.707106781; } else { y2 = Math.sqrt(yy); x2 = xy / y2; z2 = yz / y2; } } else { if (zz < epsilon) { x2 = 0.707106781; y2 = 0.707106781; z2 = 0; } else { z2 = Math.sqrt(zz); x2 = xz / z2; y2 = yz / z2; } } this.set(x2, y2, z2, 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; } setFromMatrixPosition(m2) { const e = m2.elements; this.x = e[12]; this.y = e[13]; this.z = e[14]; this.w = e[15]; 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(min2, max2) { this.x = Math.max(min2.x, Math.min(max2.x, this.x)); this.y = Math.max(min2.y, Math.min(max2.y, this.y)); this.z = Math.max(min2.z, Math.min(max2.z, this.z)); this.w = Math.max(min2.w, Math.min(max2.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(min2, max2) { const length2 = this.length(); return this.divideScalar(length2 || 1).multiplyScalar(Math.max(min2, Math.min(max2, length2))); } 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 = Math.trunc(this.x); this.y = Math.trunc(this.y); this.z = Math.trunc(this.z); this.w = Math.trunc(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(length2) { return this.normalize().multiplyScalar(length2); } 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(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.y) * alpha; this.z = v1.z + (v2.z - v1.z) * alpha; this.w = v1.w + (v2.w - v1.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(attribute2, index5) { this.x = attribute2.getX(index5); this.y = attribute2.getY(index5); this.z = attribute2.getZ(index5); this.w = attribute2.getW(index5); return this; } random() { this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); this.w = Math.random(); return this; } *[Symbol.iterator]() { yield this.x; yield this.y; yield this.z; yield this.w; } }; var RenderTarget = class extends EventDispatcher { constructor(width = 1, height = 1, options = {}) { super(); this.isRenderTarget = true; 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); const image = { width, height, depth: 1 }; options = Object.assign({ generateMipmaps: false, internalFormat: null, minFilter: LinearFilter, depthBuffer: true, stencilBuffer: false, resolveDepthBuffer: true, resolveStencilBuffer: true, depthTexture: null, samples: 0, count: 1 }, options); const texture2 = new Texture(image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.colorSpace); texture2.flipY = false; texture2.generateMipmaps = options.generateMipmaps; texture2.internalFormat = options.internalFormat; this.textures = []; const count = options.count; for (let i = 0; i < count; i++) { this.textures[i] = texture2.clone(); this.textures[i].isRenderTargetTexture = true; } this.depthBuffer = options.depthBuffer; this.stencilBuffer = options.stencilBuffer; this.resolveDepthBuffer = options.resolveDepthBuffer; this.resolveStencilBuffer = options.resolveStencilBuffer; this.depthTexture = options.depthTexture; this.samples = options.samples; } get texture() { return this.textures[0]; } set texture(value) { this.textures[0] = value; } setSize(width, height, depth2 = 1) { if (this.width !== width || this.height !== height || this.depth !== depth2) { this.width = width; this.height = height; this.depth = depth2; for (let i = 0, il = this.textures.length; i < il; i++) { this.textures[i].image.width = width; this.textures[i].image.height = height; this.textures[i].image.depth = depth2; } 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.scissor.copy(source.scissor); this.scissorTest = source.scissorTest; this.viewport.copy(source.viewport); this.textures.length = 0; for (let i = 0, il = source.textures.length; i < il; i++) { this.textures[i] = source.textures[i].clone(); this.textures[i].isRenderTargetTexture = true; } const image = Object.assign({}, source.texture.image); this.texture.source = new Source(image); this.depthBuffer = source.depthBuffer; this.stencilBuffer = source.stencilBuffer; this.resolveDepthBuffer = source.resolveDepthBuffer; this.resolveStencilBuffer = source.resolveStencilBuffer; if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone(); this.samples = source.samples; return this; } dispose() { this.dispatchEvent({ type: "dispose" }); } }; var WebGLRenderTarget = class extends RenderTarget { constructor(width = 1, height = 1, options = {}) { super(width, height, options); this.isWebGLRenderTarget = true; } }; var DataArrayTexture = class extends Texture { constructor(data = null, width = 1, height = 1, depth2 = 1) { super(null); this.isDataArrayTexture = true; this.image = { data, width, height, depth: depth2 }; this.magFilter = NearestFilter; this.minFilter = NearestFilter; this.wrapR = ClampToEdgeWrapping; this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; this.layerUpdates = /* @__PURE__ */ new Set(); } addLayerUpdate(layerIndex) { this.layerUpdates.add(layerIndex); } clearLayerUpdates() { this.layerUpdates.clear(); } }; var Data3DTexture = class extends Texture { constructor(data = null, width = 1, height = 1, depth2 = 1) { super(null); this.isData3DTexture = true; this.image = { data, width, height, depth: depth2 }; this.magFilter = NearestFilter; this.minFilter = NearestFilter; this.wrapR = ClampToEdgeWrapping; this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; } }; var Quaternion = class { constructor(x2 = 0, y2 = 0, z2 = 0, w = 1) { this.isQuaternion = true; this._x = x2; this._y = y2; this._z = z2; this._w = w; } static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) { let x0 = src0[srcOffset0 + 0], y0 = src0[srcOffset0 + 1], z0 = src0[srcOffset0 + 2], w02 = src0[srcOffset0 + 3]; const x1 = src1[srcOffset1 + 0], y1 = src1[srcOffset1 + 1], z1 = src1[srcOffset1 + 2], w12 = src1[srcOffset1 + 3]; if (t === 0) { dst[dstOffset + 0] = x0; dst[dstOffset + 1] = y0; dst[dstOffset + 2] = z0; dst[dstOffset + 3] = w02; return; } if (t === 1) { dst[dstOffset + 0] = x1; dst[dstOffset + 1] = y1; dst[dstOffset + 2] = z1; dst[dstOffset + 3] = w12; return; } if (w02 !== w12 || x0 !== x1 || y0 !== y1 || z0 !== z1) { let s = 1 - t; const cos2 = x0 * x1 + y0 * y1 + z0 * z1 + w02 * w12, dir = cos2 >= 0 ? 1 : -1, sqrSin = 1 - cos2 * cos2; if (sqrSin > Number.EPSILON) { const sin2 = Math.sqrt(sqrSin), len = Math.atan2(sin2, cos2 * dir); s = Math.sin(s * len) / sin2; t = Math.sin(t * len) / sin2; } const tDir = t * dir; x0 = x0 * s + x1 * tDir; y0 = y0 * s + y1 * tDir; z0 = z0 * s + z1 * tDir; w02 = w02 * s + w12 * tDir; if (s === 1 - t) { const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w02 * w02); x0 *= f; y0 *= f; z0 *= f; w02 *= f; } } dst[dstOffset] = x0; dst[dstOffset + 1] = y0; dst[dstOffset + 2] = z0; dst[dstOffset + 3] = w02; } static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) { const x0 = src0[srcOffset0]; const y0 = src0[srcOffset0 + 1]; const z0 = src0[srcOffset0 + 2]; const w02 = src0[srcOffset0 + 3]; const x1 = src1[srcOffset1]; const y1 = src1[srcOffset1 + 1]; const z1 = src1[srcOffset1 + 2]; const w12 = src1[srcOffset1 + 3]; dst[dstOffset] = x0 * w12 + w02 * x1 + y0 * z1 - z0 * y1; dst[dstOffset + 1] = y0 * w12 + w02 * y1 + z0 * x1 - x0 * z1; dst[dstOffset + 2] = z0 * w12 + w02 * z1 + x0 * y1 - y0 * x1; dst[dstOffset + 3] = w02 * w12 - 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(x2, y2, z2, w) { this._x = x2; this._y = y2; this._z = z2; this._w = w; 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, update4 = true) { const x2 = euler._x, y2 = euler._y, z2 = euler._z, order = euler._order; const cos2 = Math.cos; const sin2 = Math.sin; const c1 = cos2(x2 / 2); const c2 = cos2(y2 / 2); const c3 = cos2(z2 / 2); const s1 = sin2(x2 / 2); const s2 = sin2(y2 / 2); const s3 = sin2(z2 / 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 (update4 === true) 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(m2) { const te = m2.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, step2) { const angle = this.angleTo(q); if (angle === 0) return this; const t = Math.min(1, step2 / 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) { return this.multiplyQuaternions(this, q); } premultiply(q) { return this.multiplyQuaternions(q, this); } multiplyQuaternions(a2, b) { const qax = a2._x, qay = a2._y, qaz = a2._z, qaw = a2._w; const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; this._onChangeCallback(); return this; } slerp(qb, t) { if (t === 0) return this; if (t === 1) return this.copy(qb); const x2 = this._x, y2 = this._y, z2 = this._z, w = this._w; let cosHalfTheta = w * qb._w + x2 * qb._x + y2 * qb._y + z2 * 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 = w; this._x = x2; this._y = y2; this._z = z2; return this; } const sqrSinHalfTheta = 1 - cosHalfTheta * cosHalfTheta; if (sqrSinHalfTheta <= Number.EPSILON) { const s = 1 - t; this._w = s * w + t * this._w; this._x = s * x2 + t * this._x; this._y = s * y2 + t * this._y; this._z = s * z2 + t * this._z; this.normalize(); 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 = w * ratioA + this._w * ratioB; this._x = x2 * ratioA + this._x * ratioB; this._y = y2 * ratioA + this._y * ratioB; this._z = z2 * ratioA + this._z * ratioB; this._onChangeCallback(); return this; } slerpQuaternions(qa, qb, t) { return this.copy(qa).slerp(qb, t); } random() { const theta1 = 2 * Math.PI * Math.random(); const theta2 = 2 * Math.PI * Math.random(); const x0 = Math.random(); const r1 = Math.sqrt(1 - x0); const r2 = Math.sqrt(x0); return this.set( r1 * Math.sin(theta1), r1 * Math.cos(theta1), r2 * Math.sin(theta2), r2 * Math.cos(theta2) ); } 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(attribute2, index5) { this._x = attribute2.getX(index5); this._y = attribute2.getY(index5); this._z = attribute2.getZ(index5); this._w = attribute2.getW(index5); this._onChangeCallback(); return this; } toJSON() { return this.toArray(); } _onChange(callback) { this._onChangeCallback = callback; return this; } _onChangeCallback() { } *[Symbol.iterator]() { yield this._x; yield this._y; yield this._z; yield this._w; } }; var Vector3 = class _Vector3 { constructor(x2 = 0, y2 = 0, z2 = 0) { _Vector3.prototype.isVector3 = true; this.x = x2; this.y = y2; this.z = z2; } set(x2, y2, z2) { if (z2 === void 0) z2 = this.z; this.x = x2; this.y = y2; this.z = z2; return this; } setScalar(scalar) { this.x = scalar; this.y = scalar; this.z = scalar; return this; } setX(x2) { this.x = x2; return this; } setY(y2) { this.y = y2; return this; } setZ(z2) { this.z = z2; return this; } setComponent(index5, value) { switch (index5) { 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: " + index5); } return this; } getComponent(index5) { switch (index5) { case 0: return this.x; case 1: return this.y; case 2: return this.z; default: throw new Error("index is out of range: " + index5); } } 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) { 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, b) { this.x = a2.x + b.x; this.y = a2.y + b.y; this.z = a2.z + b.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) { 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, b) { this.x = a2.x - b.x; this.y = a2.y - b.y; this.z = a2.z - b.z; return this; } multiply(v) { 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, b) { this.x = a2.x * b.x; this.y = a2.y * b.y; this.z = a2.z * b.z; return this; } applyEuler(euler) { return this.applyQuaternion(_quaternion$4.setFromEuler(euler)); } applyAxisAngle(axis, angle) { return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle)); } applyMatrix3(m2) { const x2 = this.x, y2 = this.y, z2 = this.z; const e = m2.elements; this.x = e[0] * x2 + e[3] * y2 + e[6] * z2; this.y = e[1] * x2 + e[4] * y2 + e[7] * z2; this.z = e[2] * x2 + e[5] * y2 + e[8] * z2; return this; } applyNormalMatrix(m2) { return this.applyMatrix3(m2).normalize(); } applyMatrix4(m2) { const x2 = this.x, y2 = this.y, z2 = this.z; const e = m2.elements; const w = 1 / (e[3] * x2 + e[7] * y2 + e[11] * z2 + e[15]); this.x = (e[0] * x2 + e[4] * y2 + e[8] * z2 + e[12]) * w; this.y = (e[1] * x2 + e[5] * y2 + e[9] * z2 + e[13]) * w; this.z = (e[2] * x2 + e[6] * y2 + e[10] * z2 + e[14]) * w; return this; } applyQuaternion(q) { const vx = this.x, vy = this.y, vz = this.z; const qx = q.x, qy = q.y, qz = q.z, qw = q.w; const tx = 2 * (qy * vz - qz * vy); const ty = 2 * (qz * vx - qx * vz); const tz = 2 * (qx * vy - qy * vx); this.x = vx + qw * tx + qy * tz - qz * ty; this.y = vy + qw * ty + qz * tx - qx * tz; this.z = vz + qw * tz + qx * ty - qy * tx; return this; } project(camera3) { return this.applyMatrix4(camera3.matrixWorldInverse).applyMatrix4(camera3.projectionMatrix); } unproject(camera3) { return this.applyMatrix4(camera3.projectionMatrixInverse).applyMatrix4(camera3.matrixWorld); } transformDirection(m2) { const x2 = this.x, y2 = this.y, z2 = this.z; const e = m2.elements; this.x = e[0] * x2 + e[4] * y2 + e[8] * z2; this.y = e[1] * x2 + e[5] * y2 + e[9] * z2; this.z = e[2] * x2 + e[6] * y2 + e[10] * z2; 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(min2, max2) { this.x = Math.max(min2.x, Math.min(max2.x, this.x)); this.y = Math.max(min2.y, Math.min(max2.y, this.y)); this.z = Math.max(min2.z, Math.min(max2.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(min2, max2) { const length2 = this.length(); return this.divideScalar(length2 || 1).multiplyScalar(Math.max(min2, Math.min(max2, length2))); } 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 = Math.trunc(this.x); this.y = Math.trunc(this.y); this.z = Math.trunc(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; } // TODO lengthSquared? 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(length2) { return this.normalize().multiplyScalar(length2); } 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(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.y) * alpha; this.z = v1.z + (v2.z - v1.z) * alpha; return this; } cross(v) { return this.crossVectors(this, v); } crossVectors(a2, b) { const ax = a2.x, ay = a2.y, az = a2.z; const bx = b.x, by = b.y, bz = b.z; this.x = ay * bz - az * by; this.y = az * bx - ax * bz; this.z = ax * by - ay * bx; return this; } projectOnVector(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(normal2) { return this.sub(_vector$c.copy(normal2).multiplyScalar(2 * this.dot(normal2))); } 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, y2) { this.x = radius * Math.sin(theta); this.y = y2; this.z = radius * Math.cos(theta); return this; } setFromMatrixPosition(m2) { const e = m2.elements; this.x = e[12]; this.y = e[13]; this.z = e[14]; return this; } setFromMatrixScale(m2) { const sx = this.setFromMatrixColumn(m2, 0).length(); const sy = this.setFromMatrixColumn(m2, 1).length(); const sz = this.setFromMatrixColumn(m2, 2).length(); this.x = sx; this.y = sy; this.z = sz; return this; } setFromMatrixColumn(m2, index5) { return this.fromArray(m2.elements, index5 * 4); } setFromMatrix3Column(m2, index5) { return this.fromArray(m2.elements, index5 * 3); } setFromEuler(e) { this.x = e._x; this.y = e._y; this.z = e._z; return this; } setFromColor(c2) { this.x = c2.r; this.y = c2.g; this.z = c2.b; return this; } 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(attribute2, index5) { this.x = attribute2.getX(index5); this.y = attribute2.getY(index5); this.z = attribute2.getZ(index5); return this; } random() { this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); return this; } randomDirection() { const theta = Math.random() * Math.PI * 2; const u = Math.random() * 2 - 1; const c2 = Math.sqrt(1 - u * u); this.x = c2 * Math.cos(theta); this.y = u; this.z = c2 * Math.sin(theta); return this; } *[Symbol.iterator]() { yield this.x; yield this.y; yield this.z; } }; var _vector$c = /* @__PURE__ */ new Vector3(); var _quaternion$4 = /* @__PURE__ */ new Quaternion(); var Box3 = class { constructor(min2 = new Vector3(Infinity, Infinity, Infinity), max2 = new Vector3(-Infinity, -Infinity, -Infinity)) { this.isBox3 = true; this.min = min2; this.max = max2; } set(min2, max2) { this.min.copy(min2); this.max.copy(max2); return this; } setFromArray(array) { this.makeEmpty(); for (let i = 0, il = array.length; i < il; i += 3) { this.expandByPoint(_vector$b.fromArray(array, i)); } return this; } setFromBufferAttribute(attribute2) { this.makeEmpty(); for (let i = 0, il = attribute2.count; i < il; i++) { this.expandByPoint(_vector$b.fromBufferAttribute(attribute2, i)); } 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, precise = false) { this.makeEmpty(); return this.expandByObject(object, precise); } 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, precise = false) { object.updateWorldMatrix(false, false); const geometry = object.geometry; if (geometry !== void 0) { const positionAttribute = geometry.getAttribute("position"); if (precise === true && positionAttribute !== void 0 && object.isInstancedMesh !== true) { for (let i = 0, l = positionAttribute.count; i < l; i++) { if (object.isMesh === true) { object.getVertexPosition(i, _vector$b); } else { _vector$b.fromBufferAttribute(positionAttribute, i); } _vector$b.applyMatrix4(object.matrixWorld); this.expandByPoint(_vector$b); } } else { if (object.boundingBox !== void 0) { if (object.boundingBox === null) { object.computeBoundingBox(); } _box$4.copy(object.boundingBox); } else { if (geometry.boundingBox === null) { geometry.computeBoundingBox(); } _box$4.copy(geometry.boundingBox); } _box$4.applyMatrix4(object.matrixWorld); this.union(_box$4); } } const children = object.children; for (let i = 0, l = children.length; i < l; i++) { this.expandByObject(children[i], precise); } 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; } 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; } intersectsSphere(sphere) { this.clampPoint(sphere.center, _vector$b); return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius; } intersectsPlane(plane) { let min2, max2; if (plane.normal.x > 0) { min2 = plane.normal.x * this.min.x; max2 = plane.normal.x * this.max.x; } else { min2 = plane.normal.x * this.max.x; max2 = plane.normal.x * this.min.x; } if (plane.normal.y > 0) { min2 += plane.normal.y * this.min.y; max2 += plane.normal.y * this.max.y; } else { min2 += plane.normal.y * this.max.y; max2 += plane.normal.y * this.min.y; } if (plane.normal.z > 0) { min2 += plane.normal.z * this.min.z; max2 += plane.normal.z * this.max.z; } else { min2 += plane.normal.z * this.max.z; max2 += plane.normal.z * this.min.z; } return min2 <= -plane.constant && max2 >= -plane.constant; } intersectsTriangle(triangle) { if (this.isEmpty()) { return false; } this.getCenter(_center); _extents.subVectors(this.max, _center); _v0$3.subVectors(triangle.a, _center); _v1$7.subVectors(triangle.b, _center); _v2$4.subVectors(triangle.c, _center); _f0.subVectors(_v1$7, _v0$3); _f1.subVectors(_v2$4, _v1$7); _f2.subVectors(_v0$3, _v2$4); 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$3, _v1$7, _v2$4, _extents)) { return false; } axes = [1, 0, 0, 0, 1, 0, 0, 0, 1]; if (!satForAxes(axes, _v0$3, _v1$7, _v2$4, _extents)) { return false; } _triangleNormal.crossVectors(_f0, _f1); axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z]; return satForAxes(axes, _v0$3, _v1$7, _v2$4, _extents); } clampPoint(point, target) { return target.copy(point).clamp(this.min, this.max); } distanceToPoint(point) { return this.clampPoint(point, _vector$b).distanceTo(point); } getBoundingSphere(target) { if (this.isEmpty()) { target.makeEmpty(); } else { 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); } }; 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$4 = /* @__PURE__ */ new Box3(); var _v0$3 = /* @__PURE__ */ new Vector3(); var _v1$7 = /* @__PURE__ */ new Vector3(); var _v2$4 = /* @__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, v0, v1, v2, 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 = v0.dot(_testAxis); const p1 = v1.dot(_testAxis); const p2 = v2.dot(_testAxis); if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) { return false; } } return true; } var _box$3 = /* @__PURE__ */ new Box3(); var _v1$6 = /* @__PURE__ */ new Vector3(); var _v2$3 = /* @__PURE__ */ new Vector3(); var Sphere = class { constructor(center = new Vector3(), radius = -1) { this.isSphere = true; 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$3.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) { if (this.isEmpty()) { this.center.copy(point); this.radius = 0; return this; } _v1$6.subVectors(point, this.center); const lengthSq2 = _v1$6.lengthSq(); if (lengthSq2 > this.radius * this.radius) { const length2 = Math.sqrt(lengthSq2); const delta = (length2 - this.radius) * 0.5; this.center.addScaledVector(_v1$6, delta / length2); this.radius += delta; } return this; } union(sphere) { if (sphere.isEmpty()) { return this; } if (this.isEmpty()) { this.copy(sphere); return this; } if (this.center.equals(sphere.center) === true) { this.radius = Math.max(this.radius, sphere.radius); } else { _v2$3.subVectors(sphere.center, this.center).setLength(sphere.radius); this.expandByPoint(_v1$6.copy(sphere.center).add(_v2$3)); this.expandByPoint(_v1$6.copy(sphere.center).sub(_v2$3)); } 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(), direction2 = new Vector3(0, 0, -1)) { this.origin = origin; this.direction = direction2; } set(origin, direction2) { this.origin.copy(origin); this.direction.copy(direction2); return this; } copy(ray) { this.origin.copy(ray.origin); this.direction.copy(ray.direction); return this; } at(t, target) { return target.copy(this.origin).addScaledVector(this.direction, t); } 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.origin).addScaledVector(this.direction, directionDistance); } 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.origin).addScaledVector(this.direction, directionDistance); return _vector$a.distanceToSquared(point); } distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) { _segCenter.copy(v0).add(v1).multiplyScalar(0.5); _segDir.copy(v1).sub(v0).normalize(); _diff.copy(this.origin).sub(_segCenter); const segExtent = v0.distanceTo(v1) * 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.origin).addScaledVector(this.direction, s0); } if (optionalPointOnSegment) { optionalPointOnSegment.copy(_segCenter).addScaledVector(_segDir, s1); } 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 (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 || isNaN(tmin)) tmin = tymin; if (tymax < tmax || isNaN(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, b, c2, backfaceCulling, target) { _edge1.subVectors(b, 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 _Matrix4 { constructor(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { _Matrix4.prototype.isMatrix4 = true; this.elements = [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]; if (n11 !== void 0) { this.set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44); } } 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(m2) { const te = this.elements; const me = m2.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(m2) { const te = this.elements, me = m2.elements; te[12] = me[12]; te[13] = me[13]; te[14] = me[14]; return this; } setFromMatrix3(m2) { const me = m2.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(m2) { const te = this.elements; const me = m2.elements; const scaleX = 1 / _v1$5.setFromMatrixColumn(m2, 0).length(); const scaleY = 1 / _v1$5.setFromMatrixColumn(m2, 1).length(); const scaleZ = 1 / _v1$5.setFromMatrixColumn(m2, 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) { const te = this.elements; const x2 = euler.x, y2 = euler.y, z2 = euler.z; const a2 = Math.cos(x2), b = Math.sin(x2); const c2 = Math.cos(y2), d = Math.sin(y2); const e = Math.cos(z2), f = Math.sin(z2); if (euler.order === "XYZ") { const ae = a2 * e, af = a2 * f, be = b * e, bf = b * f; te[0] = c2 * e; te[4] = -c2 * f; te[8] = d; te[1] = af + be * d; te[5] = ae - bf * d; te[9] = -b * 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 * b; te[4] = de * b - cf; te[8] = a2 * d; te[1] = a2 * f; te[5] = a2 * e; te[9] = -b; te[2] = cf * b - de; te[6] = df + ce * b; 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 * b; te[4] = -a2 * f; te[8] = de + cf * b; te[1] = cf + de * b; te[5] = a2 * e; te[9] = df - ce * b; te[2] = -a2 * d; te[6] = b; te[10] = a2 * c2; } else if (euler.order === "ZYX") { const ae = a2 * e, af = a2 * f, be = b * e, bf = b * 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] = b * c2; te[10] = a2 * c2; } else if (euler.order === "YZX") { const ac = a2 * c2, ad = a2 * d, bc = b * c2, bd = b * d; te[0] = c2 * e; te[4] = bd - ac * f; te[8] = bc * f + ad; te[1] = f; te[5] = a2 * e; te[9] = -b * 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 = b * c2, bd = b * 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] = b * 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(m2) { return this.multiplyMatrices(this, m2); } premultiply(m2) { return this.multiplyMatrices(m2, this); } multiplyMatrices(a2, b) { const ae = a2.elements; const be = b.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 tmp2; tmp2 = te[1]; te[1] = te[4]; te[4] = tmp2; tmp2 = te[2]; te[2] = te[8]; te[8] = tmp2; tmp2 = te[6]; te[6] = te[9]; te[9] = tmp2; tmp2 = te[3]; te[3] = te[12]; te[12] = tmp2; tmp2 = te[7]; te[7] = te[13]; te[13] = tmp2; tmp2 = te[11]; te[11] = te[14]; te[14] = tmp2; return this; } setPosition(x2, y2, z2) { const te = this.elements; if (x2.isVector3) { te[12] = x2.x; te[13] = x2.y; te[14] = x2.z; } else { te[12] = x2; te[13] = y2; te[14] = z2; } 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 x2 = v.x, y2 = v.y, z2 = v.z; te[0] *= x2; te[4] *= y2; te[8] *= z2; te[1] *= x2; te[5] *= y2; te[9] *= z2; te[2] *= x2; te[6] *= y2; te[10] *= z2; te[3] *= x2; te[7] *= y2; te[11] *= z2; 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(x2, y2, z2) { if (x2.isVector3) { this.set( 1, 0, 0, x2.x, 0, 1, 0, x2.y, 0, 0, 1, x2.z, 0, 0, 0, 1 ); } else { this.set( 1, 0, 0, x2, 0, 1, 0, y2, 0, 0, 1, z2, 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 x2 = axis.x, y2 = axis.y, z2 = axis.z; const tx = t * x2, ty = t * y2; this.set( tx * x2 + c2, tx * y2 - s * z2, tx * z2 + s * y2, 0, tx * y2 + s * z2, ty * y2 + c2, ty * z2 - s * x2, 0, tx * z2 - s * y2, ty * z2 + s * x2, t * z2 * z2 + c2, 0, 0, 0, 0, 1 ); return this; } makeScale(x2, y2, z2) { this.set( x2, 0, 0, 0, 0, y2, 0, 0, 0, 0, z2, 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 x2 = quaternion._x, y2 = quaternion._y, z2 = quaternion._z, w = quaternion._w; const x22 = x2 + x2, y22 = y2 + y2, z22 = z2 + z2; const xx = x2 * x22, xy = x2 * y22, xz = x2 * z22; const yy = y2 * y22, yz = y2 * z22, zz = z2 * z22; const wx = w * x22, wy = w * y22, wz = w * z22; 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$4.copy(this); const invSX = 1 / sx; const invSY = 1 / sy; const invSZ = 1 / sz; _m1$4.elements[0] *= invSX; _m1$4.elements[1] *= invSX; _m1$4.elements[2] *= invSX; _m1$4.elements[4] *= invSY; _m1$4.elements[5] *= invSY; _m1$4.elements[6] *= invSY; _m1$4.elements[8] *= invSZ; _m1$4.elements[9] *= invSZ; _m1$4.elements[10] *= invSZ; quaternion.setFromRotationMatrix(_m1$4); scale.x = sx; scale.y = sy; scale.z = sz; return this; } makePerspective(left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem) { const te = this.elements; const x2 = 2 * near / (right - left); const y2 = 2 * near / (top - bottom); const a2 = (right + left) / (right - left); const b = (top + bottom) / (top - bottom); let c2, d; if (coordinateSystem === WebGLCoordinateSystem) { c2 = -(far + near) / (far - near); d = -2 * far * near / (far - near); } else if (coordinateSystem === WebGPUCoordinateSystem) { c2 = -far / (far - near); d = -far * near / (far - near); } else { throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: " + coordinateSystem); } te[0] = x2; te[4] = 0; te[8] = a2; te[12] = 0; te[1] = 0; te[5] = y2; te[9] = b; 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, coordinateSystem = WebGLCoordinateSystem) { const te = this.elements; const w = 1 / (right - left); const h = 1 / (top - bottom); const p = 1 / (far - near); const x2 = (right + left) * w; const y2 = (top + bottom) * h; let z2, zInv; if (coordinateSystem === WebGLCoordinateSystem) { z2 = (far + near) * p; zInv = -2 * p; } else if (coordinateSystem === WebGPUCoordinateSystem) { z2 = near * p; zInv = -1 * p; } else { throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: " + coordinateSystem); } te[0] = 2 * w; te[4] = 0; te[8] = 0; te[12] = -x2; te[1] = 0; te[5] = 2 * h; te[9] = 0; te[13] = -y2; te[2] = 0; te[6] = 0; te[10] = zInv; te[14] = -z2; 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; } }; var _v1$5 = /* @__PURE__ */ new Vector3(); var _m1$4 = /* @__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$2 = /* @__PURE__ */ new Matrix4(); var _quaternion$3 = /* @__PURE__ */ new Quaternion(); var Euler = class _Euler { constructor(x2 = 0, y2 = 0, z2 = 0, order = _Euler.DEFAULT_ORDER) { this.isEuler = true; this._x = x2; this._y = y2; this._z = z2; 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(x2, y2, z2, order = this._order) { this._x = x2; this._y = y2; this._z = z2; 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(m2, order = this._order, update4 = true) { const te = m2.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 (update4 === true) this._onChangeCallback(); return this; } setFromQuaternion(q, order, update4) { _matrix$2.makeRotationFromQuaternion(q); return this.setFromRotationMatrix(_matrix$2, order, update4); } 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; } _onChange(callback) { this._onChangeCallback = callback; return this; } _onChangeCallback() { } *[Symbol.iterator]() { yield this._x; yield this._y; yield this._z; yield this._order; } }; Euler.DEFAULT_ORDER = "XYZ"; var Layers = class { constructor() { this.mask = 1 | 0; } set(channel) { this.mask = (1 << channel | 0) >>> 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; } isEnabled(channel) { return (this.mask & (1 << channel | 0)) !== 0; } }; var _object3DId = 0; var _v1$4 = /* @__PURE__ */ new Vector3(); var _q1 = /* @__PURE__ */ new Quaternion(); var _m1$3 = /* @__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 _childaddedEvent = { type: "childadded", child: null }; var _childremovedEvent = { type: "childremoved", child: null }; var Object3D = class _Object3D extends EventDispatcher { constructor() { super(); this.isObject3D = true; Object.defineProperty(this, "id", { value: _object3DId++ }); this.uuid = generateUUID(); this.name = ""; this.type = "Object3D"; this.parent = null; this.children = []; this.up = _Object3D.DEFAULT_UP.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.DEFAULT_MATRIX_AUTO_UPDATE; this.matrixWorldAutoUpdate = _Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; 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 = {}; } onBeforeShadow() { } onAfterShadow() { } 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(m2) { this.quaternion.setFromRotationMatrix(m2); } 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, distance2) { _v1$4.copy(axis).applyQuaternion(this.quaternion); this.position.add(_v1$4.multiplyScalar(distance2)); return this; } translateX(distance2) { return this.translateOnAxis(_xAxis, distance2); } translateY(distance2) { return this.translateOnAxis(_yAxis, distance2); } translateZ(distance2) { return this.translateOnAxis(_zAxis, distance2); } localToWorld(vector) { this.updateWorldMatrix(true, false); return vector.applyMatrix4(this.matrixWorld); } worldToLocal(vector) { this.updateWorldMatrix(true, false); return vector.applyMatrix4(_m1$3.copy(this.matrixWorld).invert()); } lookAt(x2, y2, z2) { if (x2.isVector3) { _target.copy(x2); } else { _target.set(x2, y2, z2); } const parent = this.parent; this.updateWorldMatrix(true, false); _position$3.setFromMatrixPosition(this.matrixWorld); if (this.isCamera || this.isLight) { _m1$3.lookAt(_position$3, _target, this.up); } else { _m1$3.lookAt(_target, _position$3, this.up); } this.quaternion.setFromRotationMatrix(_m1$3); if (parent) { _m1$3.extractRotation(parent.matrixWorld); _q1.setFromRotationMatrix(_m1$3); 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) { object.removeFromParent(); object.parent = this; this.children.push(object); object.dispatchEvent(_addedEvent); _childaddedEvent.child = object; this.dispatchEvent(_childaddedEvent); _childaddedEvent.child = null; } 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 index5 = this.children.indexOf(object); if (index5 !== -1) { object.parent = null; this.children.splice(index5, 1); object.dispatchEvent(_removedEvent); _childremovedEvent.child = object; this.dispatchEvent(_childremovedEvent); _childremovedEvent.child = null; } return this; } removeFromParent() { const parent = this.parent; if (parent !== null) { parent.remove(this); } return this; } clear() { return this.remove(...this.children); } attach(object) { this.updateWorldMatrix(true, false); _m1$3.copy(this.matrixWorld).invert(); if (object.parent !== null) { object.parent.updateWorldMatrix(true, false); _m1$3.multiply(object.parent.matrixWorld); } object.applyMatrix4(_m1$3); object.removeFromParent(); object.parent = this; this.children.push(object); object.updateWorldMatrix(false, true); object.dispatchEvent(_addedEvent); _childaddedEvent.child = object; this.dispatchEvent(_childaddedEvent); _childaddedEvent.child = null; return this; } getObjectById(id2) { return this.getObjectByProperty("id", id2); } 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; } getObjectsByProperty(name, value, result = []) { if (this[name] === value) result.push(this); const children = this.children; for (let i = 0, l = children.length; i < l; i++) { children[i].getObjectsByProperty(name, value, result); } return result; } 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.matrixWorldAutoUpdate === true) { 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++) { const child = children[i]; child.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.matrixWorldAutoUpdate === true) { 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++) { const child = children[i]; child.updateWorldMatrix(false, true); } } } toJSON(meta) { const isRootObject = meta === void 0 || typeof meta === "string"; const output2 = {}; if (isRootObject) { meta = { geometries: {}, materials: {}, textures: {}, images: {}, shapes: {}, skeletons: {}, animations: {}, nodes: {} }; output2.metadata = { version: 4.6, 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 (Object.keys(this.userData).length > 0) object.userData = this.userData; object.layers = this.layers.mask; object.matrix = this.matrix.toArray(); object.up = this.up.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(); } if (this.isBatchedMesh) { object.type = "BatchedMesh"; object.perObjectFrustumCulled = this.perObjectFrustumCulled; object.sortObjects = this.sortObjects; object.drawRanges = this._drawRanges; object.reservedRanges = this._reservedRanges; object.visibility = this._visibility; object.active = this._active; object.bounds = this._bounds.map((bound) => ({ boxInitialized: bound.boxInitialized, boxMin: bound.box.min.toArray(), boxMax: bound.box.max.toArray(), sphereInitialized: bound.sphereInitialized, sphereRadius: bound.sphere.radius, sphereCenter: bound.sphere.center.toArray() })); object.maxInstanceCount = this._maxInstanceCount; object.maxVertexCount = this._maxVertexCount; object.maxIndexCount = this._maxIndexCount; object.geometryInitialized = this._geometryInitialized; object.geometryCount = this._geometryCount; object.matricesTexture = this._matricesTexture.toJSON(meta); if (this._colorsTexture !== null) object.colorsTexture = this._colorsTexture.toJSON(meta); if (this.boundingSphere !== null) { object.boundingSphere = { center: object.boundingSphere.center.toArray(), radius: object.boundingSphere.radius }; } if (this.boundingBox !== null) { object.boundingBox = { min: object.boundingBox.min.toArray(), max: object.boundingBox.max.toArray() }; } } function serialize(library, element2) { if (library[element2.uuid] === void 0) { library[element2.uuid] = element2.toJSON(meta); } return element2.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 && this.environment.isRenderTargetTexture !== true) { 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); const nodes = extractFromCache(meta.nodes); if (geometries.length > 0) output2.geometries = geometries; if (materials.length > 0) output2.materials = materials; if (textures.length > 0) output2.textures = textures; if (images.length > 0) output2.images = images; if (shapes.length > 0) output2.shapes = shapes; if (skeletons.length > 0) output2.skeletons = skeletons; if (animations.length > 0) output2.animations = animations; if (nodes.length > 0) output2.nodes = nodes; } output2.object = object; return output2; function extractFromCache(cache2) { const values = []; for (const key in cache2) { const data = cache2[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.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; 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.animations = source.animations.slice(); 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.DEFAULT_UP = /* @__PURE__ */ new Vector3(0, 1, 0); Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true; Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true; var _v0$2 = /* @__PURE__ */ new Vector3(); var _v1$3 = /* @__PURE__ */ new Vector3(); var _v2$2 = /* @__PURE__ */ new Vector3(); var _v3$2 = /* @__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 _v40 = /* @__PURE__ */ new Vector4(); var _v41 = /* @__PURE__ */ new Vector4(); var _v42 = /* @__PURE__ */ new Vector4(); var Triangle = class _Triangle { constructor(a2 = new Vector3(), b = new Vector3(), c2 = new Vector3()) { this.a = a2; this.b = b; this.c = c2; } static getNormal(a2, b, c2, target) { target.subVectors(c2, b); _v0$2.subVectors(a2, b); target.cross(_v0$2); const targetLengthSq = target.lengthSq(); if (targetLengthSq > 0) { return target.multiplyScalar(1 / Math.sqrt(targetLengthSq)); } return target.set(0, 0, 0); } // static/instance method to calculate barycentric coordinates // based on: http://www.blackpawn.com/texts/pointinpoly/default.html static getBarycoord(point, a2, b, c2, target) { _v0$2.subVectors(c2, a2); _v1$3.subVectors(b, a2); _v2$2.subVectors(point, a2); const dot00 = _v0$2.dot(_v0$2); const dot01 = _v0$2.dot(_v1$3); const dot02 = _v0$2.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) { target.set(0, 0, 0); return null; } 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, b, c2) { if (this.getBarycoord(point, a2, b, c2, _v3$2) === null) { return false; } return _v3$2.x >= 0 && _v3$2.y >= 0 && _v3$2.x + _v3$2.y <= 1; } static getInterpolation(point, p1, p2, p3, v1, v2, v3, target) { if (this.getBarycoord(point, p1, p2, p3, _v3$2) === null) { target.x = 0; target.y = 0; if ("z" in target) target.z = 0; if ("w" in target) target.w = 0; return null; } target.setScalar(0); target.addScaledVector(v1, _v3$2.x); target.addScaledVector(v2, _v3$2.y); target.addScaledVector(v3, _v3$2.z); return target; } static getInterpolatedAttribute(attr, i1, i2, i3, barycoord, target) { _v40.setScalar(0); _v41.setScalar(0); _v42.setScalar(0); _v40.fromBufferAttribute(attr, i1); _v41.fromBufferAttribute(attr, i2); _v42.fromBufferAttribute(attr, i3); target.setScalar(0); target.addScaledVector(_v40, barycoord.x); target.addScaledVector(_v41, barycoord.y); target.addScaledVector(_v42, barycoord.z); return target; } static isFrontFacing(a2, b, c2, direction2) { _v0$2.subVectors(c2, b); _v1$3.subVectors(a2, b); return _v0$2.cross(_v1$3).dot(direction2) < 0 ? true : false; } set(a2, b, c2) { this.a.copy(a2); this.b.copy(b); 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; } setFromAttributeAndIndices(attribute2, i0, i1, i2) { this.a.fromBufferAttribute(attribute2, i0); this.b.fromBufferAttribute(attribute2, i1); this.c.fromBufferAttribute(attribute2, 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$2.subVectors(this.c, this.b); _v1$3.subVectors(this.a, this.b); return _v0$2.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); } getInterpolation(point, v1, v2, v3, target) { return _Triangle.getInterpolation(point, this.a, this.b, this.c, v1, v2, v3, target); } containsPoint(point) { return _Triangle.containsPoint(point, this.a, this.b, this.c); } isFrontFacing(direction2) { return _Triangle.isFrontFacing(this.a, this.b, this.c, direction2); } intersectsBox(box) { return box.intersectsTriangle(this); } closestPointToPoint(p, target) { const a2 = this.a, b = this.b, c2 = this.c; let v, w; _vab.subVectors(b, a2); _vac.subVectors(c2, a2); _vap.subVectors(p, a2); const d1 = _vab.dot(_vap); const d2 = _vac.dot(_vap); if (d1 <= 0 && d2 <= 0) { return target.copy(a2); } _vbp.subVectors(p, b); const d3 = _vab.dot(_vbp); const d4 = _vac.dot(_vbp); if (d3 >= 0 && d4 <= d3) { return target.copy(b); } const vc = d1 * d4 - d3 * d2; if (vc <= 0 && d1 >= 0 && d3 <= 0) { v = d1 / (d1 - d3); return target.copy(a2).addScaledVector(_vab, v); } _vcp.subVectors(p, c2); const d5 = _vab.dot(_vcp); const d6 = _vac.dot(_vcp); if (d6 >= 0 && d5 <= d6) { return target.copy(c2); } const vb = d5 * d2 - d1 * d6; if (vb <= 0 && d2 >= 0 && d6 <= 0) { w = d2 / (d2 - d6); return target.copy(a2).addScaledVector(_vac, w); } const va = d3 * d6 - d5 * d4; if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) { _vbc.subVectors(c2, b); w = (d4 - d3) / (d4 - d3 + (d5 - d6)); return target.copy(b).addScaledVector(_vbc, w); } const denom = 1 / (va + vb + vc); v = vb * denom; w = vc * denom; return target.copy(a2).addScaledVector(_vab, v).addScaledVector(_vac, w); } equals(triangle) { return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c); } }; 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(p, q, t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); return p; } var Color = class { constructor(r, g, b) { this.isColor = true; this.r = 1; this.g = 1; this.b = 1; return this.set(r, g, b); } set(r, g, b) { if (g === void 0 && b === void 0) { const value = r; if (value && value.isColor) { this.copy(value); } else if (typeof value === "number") { this.setHex(value); } else if (typeof value === "string") { this.setStyle(value); } } else { this.setRGB(r, g, b); } return this; } setScalar(scalar) { this.r = scalar; this.g = scalar; this.b = scalar; return this; } setHex(hex, colorSpace = SRGBColorSpace) { hex = Math.floor(hex); this.r = (hex >> 16 & 255) / 255; this.g = (hex >> 8 & 255) / 255; this.b = (hex & 255) / 255; ColorManagement.toWorkingColorSpace(this, colorSpace); return this; } setRGB(r, g, b, colorSpace = ColorManagement.workingColorSpace) { this.r = r; this.g = g; this.b = b; ColorManagement.toWorkingColorSpace(this, colorSpace); return this; } setHSL(h, s, l, colorSpace = ColorManagement.workingColorSpace) { 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 p = l <= 0.5 ? l * (1 + s) : l + s - l * s; const q = 2 * l - p; this.r = hue2rgb(q, p, h + 1 / 3); this.g = hue2rgb(q, p, h); this.b = hue2rgb(q, p, h - 1 / 3); } ColorManagement.toWorkingColorSpace(this, colorSpace); return this; } setStyle(style, colorSpace = SRGBColorSpace) { function handleAlpha(string) { if (string === void 0) return; if (parseFloat(string) < 1) { console.warn("THREE.Color: Alpha component of " + style + " will be ignored."); } } let m2; if (m2 = /^(\w+)\(([^\)]*)\)/.exec(style)) { let color2; const name = m2[1]; const components = m2[2]; switch (name) { case "rgb": case "rgba": if (color2 = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { handleAlpha(color2[4]); return this.setRGB( Math.min(255, parseInt(color2[1], 10)) / 255, Math.min(255, parseInt(color2[2], 10)) / 255, Math.min(255, parseInt(color2[3], 10)) / 255, colorSpace ); } if (color2 = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { handleAlpha(color2[4]); return this.setRGB( Math.min(100, parseInt(color2[1], 10)) / 100, Math.min(100, parseInt(color2[2], 10)) / 100, Math.min(100, parseInt(color2[3], 10)) / 100, colorSpace ); } break; case "hsl": case "hsla": if (color2 = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { handleAlpha(color2[4]); return this.setHSL( parseFloat(color2[1]) / 360, parseFloat(color2[2]) / 100, parseFloat(color2[3]) / 100, colorSpace ); } break; default: console.warn("THREE.Color: Unknown color model " + style); } } else if (m2 = /^\#([A-Fa-f\d]+)$/.exec(style)) { const hex = m2[1]; const size = hex.length; if (size === 3) { return this.setRGB( parseInt(hex.charAt(0), 16) / 15, parseInt(hex.charAt(1), 16) / 15, parseInt(hex.charAt(2), 16) / 15, colorSpace ); } else if (size === 6) { return this.setHex(parseInt(hex, 16), colorSpace); } else { console.warn("THREE.Color: Invalid hex color " + style); } } else if (style && style.length > 0) { return this.setColorName(style, colorSpace); } return this; } setColorName(style, colorSpace = SRGBColorSpace) { const hex = _colorKeywords[style.toLowerCase()]; if (hex !== void 0) { this.setHex(hex, colorSpace); } else { console.warn("THREE.Color: Unknown color " + style); } return this; } clone() { return new this.constructor(this.r, this.g, this.b); } copy(color2) { this.r = color2.r; this.g = color2.g; this.b = color2.b; return this; } copySRGBToLinear(color2) { this.r = SRGBToLinear(color2.r); this.g = SRGBToLinear(color2.g); this.b = SRGBToLinear(color2.b); return this; } copyLinearToSRGB(color2) { this.r = LinearToSRGB(color2.r); this.g = LinearToSRGB(color2.g); this.b = LinearToSRGB(color2.b); return this; } convertSRGBToLinear() { this.copySRGBToLinear(this); return this; } convertLinearToSRGB() { this.copyLinearToSRGB(this); return this; } getHex(colorSpace = SRGBColorSpace) { ColorManagement.fromWorkingColorSpace(_color.copy(this), colorSpace); return Math.round(clamp(_color.r * 255, 0, 255)) * 65536 + Math.round(clamp(_color.g * 255, 0, 255)) * 256 + Math.round(clamp(_color.b * 255, 0, 255)); } getHexString(colorSpace = SRGBColorSpace) { return ("000000" + this.getHex(colorSpace).toString(16)).slice(-6); } getHSL(target, colorSpace = ColorManagement.workingColorSpace) { ColorManagement.fromWorkingColorSpace(_color.copy(this), colorSpace); const r = _color.r, g = _color.g, b = _color.b; const max2 = Math.max(r, g, b); const min2 = Math.min(r, g, b); let hue, saturation; const lightness = (min2 + max2) / 2; if (min2 === max2) { hue = 0; saturation = 0; } else { const delta = max2 - min2; saturation = lightness <= 0.5 ? delta / (max2 + min2) : delta / (2 - max2 - min2); switch (max2) { case r: hue = (g - b) / delta + (g < b ? 6 : 0); break; case g: hue = (b - r) / delta + 2; break; case b: hue = (r - g) / delta + 4; break; } hue /= 6; } target.h = hue; target.s = saturation; target.l = lightness; return target; } getRGB(target, colorSpace = ColorManagement.workingColorSpace) { ColorManagement.fromWorkingColorSpace(_color.copy(this), colorSpace); target.r = _color.r; target.g = _color.g; target.b = _color.b; return target; } getStyle(colorSpace = SRGBColorSpace) { ColorManagement.fromWorkingColorSpace(_color.copy(this), colorSpace); const r = _color.r, g = _color.g, b = _color.b; if (colorSpace !== SRGBColorSpace) { return `color(${colorSpace} ${r.toFixed(3)} ${g.toFixed(3)} ${b.toFixed(3)})`; } return `rgb(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)})`; } offsetHSL(h, s, l) { this.getHSL(_hslA); return this.setHSL(_hslA.h + h, _hslA.s + s, _hslA.l + l); } add(color2) { this.r += color2.r; this.g += color2.g; this.b += color2.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(color2) { this.r = Math.max(0, this.r - color2.r); this.g = Math.max(0, this.g - color2.g); this.b = Math.max(0, this.b - color2.b); return this; } multiply(color2) { this.r *= color2.r; this.g *= color2.g; this.b *= color2.b; return this; } multiplyScalar(s) { this.r *= s; this.g *= s; this.b *= s; return this; } lerp(color2, alpha) { this.r += (color2.r - this.r) * alpha; this.g += (color2.g - this.g) * alpha; this.b += (color2.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(color2, alpha) { this.getHSL(_hslA); color2.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; } setFromVector3(v) { this.r = v.x; this.g = v.y; this.b = v.z; return this; } applyMatrix3(m2) { const r = this.r, g = this.g, b = this.b; const e = m2.elements; this.r = e[0] * r + e[3] * g + e[6] * b; this.g = e[1] * r + e[4] * g + e[7] * b; this.b = e[2] * r + e[5] * g + e[8] * b; 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(attribute2, index5) { this.r = attribute2.getX(index5); this.g = attribute2.getY(index5); this.b = attribute2.getZ(index5); return this; } toJSON() { return this.getHex(); } *[Symbol.iterator]() { yield this.r; yield this.g; yield this.b; } }; var _color = /* @__PURE__ */ new Color(); Color.NAMES = _colorKeywords; var _materialId = 0; var Material = class extends EventDispatcher { static get type() { return "Material"; } get type() { return this.constructor.type; } set type(_value) { } constructor() { super(); this.isMaterial = true; Object.defineProperty(this, "id", { value: _materialId++ }); this.uuid = generateUUID(); this.name = ""; this.blending = NormalBlending; this.side = FrontSide; this.vertexColors = false; this.opacity = 1; this.transparent = false; this.alphaHash = false; this.blendSrc = SrcAlphaFactor; this.blendDst = OneMinusSrcAlphaFactor; this.blendEquation = AddEquation; this.blendSrcAlpha = null; this.blendDstAlpha = null; this.blendEquationAlpha = null; this.blendColor = new Color(0, 0, 0); this.blendAlpha = 0; 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.forceSinglePass = 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; } // onBeforeRender and onBeforeCompile only supported in WebGLRenderer onBeforeRender() { } 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: parameter '${key}' has value of undefined.`); continue; } const currentValue = this[key]; if (currentValue === void 0) { console.warn(`THREE.Material: '${key}' is not a property of THREE.${this.type}.`); 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 isRootObject = meta === void 0 || typeof meta === "string"; if (isRootObject) { meta = { textures: {}, images: {} }; } const data = { metadata: { version: 4.6, 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.sheen !== void 0) data.sheen = this.sheen; if (this.sheenColor && this.sheenColor.isColor) data.sheenColor = this.sheenColor.getHex(); if (this.sheenRoughness !== void 0) data.sheenRoughness = this.sheenRoughness; if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex(); if (this.emissiveIntensity !== void 0 && 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.specularColor && this.specularColor.isColor) data.specularColor = this.specularColor.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.dispersion !== void 0) data.dispersion = this.dispersion; if (this.iridescence !== void 0) data.iridescence = this.iridescence; if (this.iridescenceIOR !== void 0) data.iridescenceIOR = this.iridescenceIOR; if (this.iridescenceThicknessRange !== void 0) data.iridescenceThicknessRange = this.iridescenceThicknessRange; if (this.iridescenceMap && this.iridescenceMap.isTexture) { data.iridescenceMap = this.iridescenceMap.toJSON(meta).uuid; } if (this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture) { data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON(meta).uuid; } if (this.anisotropy !== void 0) data.anisotropy = this.anisotropy; if (this.anisotropyRotation !== void 0) data.anisotropyRotation = this.anisotropyRotation; if (this.anisotropyMap && this.anisotropyMap.isTexture) { data.anisotropyMap = this.anisotropyMap.toJSON(meta).uuid; } 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.specularColorMap && this.specularColorMap.isTexture) data.specularColorMap = this.specularColorMap.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.envMapRotation !== void 0) data.envMapRotation = this.envMapRotation.toArray(); 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 && this.attenuationDistance !== Infinity) data.attenuationDistance = this.attenuationDistance; if (this.attenuationColor !== void 0) data.attenuationColor = this.attenuationColor.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 === true) data.vertexColors = true; if (this.opacity < 1) data.opacity = this.opacity; if (this.transparent === true) data.transparent = true; if (this.blendSrc !== SrcAlphaFactor) data.blendSrc = this.blendSrc; if (this.blendDst !== OneMinusSrcAlphaFactor) data.blendDst = this.blendDst; if (this.blendEquation !== AddEquation) data.blendEquation = this.blendEquation; if (this.blendSrcAlpha !== null) data.blendSrcAlpha = this.blendSrcAlpha; if (this.blendDstAlpha !== null) data.blendDstAlpha = this.blendDstAlpha; if (this.blendEquationAlpha !== null) data.blendEquationAlpha = this.blendEquationAlpha; if (this.blendColor && this.blendColor.isColor) data.blendColor = this.blendColor.getHex(); if (this.blendAlpha !== 0) data.blendAlpha = this.blendAlpha; if (this.depthFunc !== LessEqualDepth) data.depthFunc = this.depthFunc; if (this.depthTest === false) data.depthTest = this.depthTest; if (this.depthWrite === false) data.depthWrite = this.depthWrite; if (this.colorWrite === false) data.colorWrite = this.colorWrite; if (this.stencilWriteMask !== 255) data.stencilWriteMask = this.stencilWriteMask; if (this.stencilFunc !== AlwaysStencilFunc) data.stencilFunc = this.stencilFunc; if (this.stencilRef !== 0) data.stencilRef = this.stencilRef; if (this.stencilFuncMask !== 255) data.stencilFuncMask = this.stencilFuncMask; if (this.stencilFail !== KeepStencilOp) data.stencilFail = this.stencilFail; if (this.stencilZFail !== KeepStencilOp) data.stencilZFail = this.stencilZFail; if (this.stencilZPass !== KeepStencilOp) data.stencilZPass = this.stencilZPass; if (this.stencilWrite === true) data.stencilWrite = this.stencilWrite; if (this.rotation !== void 0 && 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 !== void 0 && 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.alphaHash === true) data.alphaHash = true; if (this.alphaToCoverage === true) data.alphaToCoverage = true; if (this.premultipliedAlpha === true) data.premultipliedAlpha = true; if (this.forceSinglePass === true) data.forceSinglePass = true; if (this.wireframe === true) data.wireframe = true; 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 = true; if (this.visible === false) data.visible = false; if (this.toneMapped === false) data.toneMapped = false; if (this.fog === false) data.fog = false; if (Object.keys(this.userData).length > 0) data.userData = this.userData; function extractFromCache(cache2) { const values = []; for (const key in cache2) { const data2 = cache2[key]; delete data2.metadata; values.push(data2); } return values; } if (isRootObject) { 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.blending = source.blending; this.side = source.side; this.vertexColors = source.vertexColors; this.opacity = source.opacity; this.transparent = source.transparent; this.blendSrc = source.blendSrc; this.blendDst = source.blendDst; this.blendEquation = source.blendEquation; this.blendSrcAlpha = source.blendSrcAlpha; this.blendDstAlpha = source.blendDstAlpha; this.blendEquationAlpha = source.blendEquationAlpha; this.blendColor.copy(source.blendColor); this.blendAlpha = source.blendAlpha; 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.alphaHash = source.alphaHash; this.alphaToCoverage = source.alphaToCoverage; this.premultipliedAlpha = source.premultipliedAlpha; this.forceSinglePass = source.forceSinglePass; 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++; } onBuild() { console.warn("Material: onBuild() has been removed."); } }; var MeshBasicMaterial = class extends Material { static get type() { return "MeshBasicMaterial"; } constructor(parameters) { super(); this.isMeshBasicMaterial = true; 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.envMapRotation = new Euler(); this.combine = MultiplyOperation; this.reflectivity = 1; this.refractionRatio = 0.98; this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = "round"; this.wireframeLinejoin = "round"; this.fog = true; 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.envMapRotation.copy(source.envMapRotation); 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.fog = source.fog; return this; } }; var _vector$9 = /* @__PURE__ */ new Vector3(); var _vector2$1 = /* @__PURE__ */ new Vector2(); var BufferAttribute = class { constructor(array, itemSize, normalized = false) { if (Array.isArray(array)) { throw new TypeError("THREE.BufferAttribute: array should be a Typed Array."); } this.isBufferAttribute = true; this.name = ""; this.array = array; this.itemSize = itemSize; this.count = array !== void 0 ? array.length / itemSize : 0; this.normalized = normalized; this.usage = StaticDrawUsage; this.updateRanges = []; this.gpuType = FloatType; this.version = 0; } onUploadCallback() { } set needsUpdate(value) { if (value === true) this.version++; } setUsage(value) { this.usage = value; return this; } addUpdateRange(start, count) { this.updateRanges.push({ start, count }); } clearUpdateRanges() { this.updateRanges.length = 0; } 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; this.gpuType = source.gpuType; return this; } copyAt(index1, attribute2, index22) { index1 *= this.itemSize; index22 *= attribute2.itemSize; for (let i = 0, l = this.itemSize; i < l; i++) { this.array[index1 + i] = attribute2.array[index22 + i]; } return this; } copyArray(array) { this.array.set(array); return this; } applyMatrix3(m2) { if (this.itemSize === 2) { for (let i = 0, l = this.count; i < l; i++) { _vector2$1.fromBufferAttribute(this, i); _vector2$1.applyMatrix3(m2); 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(m2); this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } } return this; } applyMatrix4(m2) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); _vector$9.applyMatrix4(m2); this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } return this; } applyNormalMatrix(m2) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); _vector$9.applyNormalMatrix(m2); this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z); } return this; } transformDirection(m2) { for (let i = 0, l = this.count; i < l; i++) { _vector$9.fromBufferAttribute(this, i); _vector$9.transformDirection(m2); 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; } getComponent(index5, component) { let value = this.array[index5 * this.itemSize + component]; if (this.normalized) value = denormalize(value, this.array); return value; } setComponent(index5, component, value) { if (this.normalized) value = normalize(value, this.array); this.array[index5 * this.itemSize + component] = value; return this; } getX(index5) { let x2 = this.array[index5 * this.itemSize]; if (this.normalized) x2 = denormalize(x2, this.array); return x2; } setX(index5, x2) { if (this.normalized) x2 = normalize(x2, this.array); this.array[index5 * this.itemSize] = x2; return this; } getY(index5) { let y2 = this.array[index5 * this.itemSize + 1]; if (this.normalized) y2 = denormalize(y2, this.array); return y2; } setY(index5, y2) { if (this.normalized) y2 = normalize(y2, this.array); this.array[index5 * this.itemSize + 1] = y2; return this; } getZ(index5) { let z2 = this.array[index5 * this.itemSize + 2]; if (this.normalized) z2 = denormalize(z2, this.array); return z2; } setZ(index5, z2) { if (this.normalized) z2 = normalize(z2, this.array); this.array[index5 * this.itemSize + 2] = z2; return this; } getW(index5) { let w = this.array[index5 * this.itemSize + 3]; if (this.normalized) w = denormalize(w, this.array); return w; } setW(index5, w) { if (this.normalized) w = normalize(w, this.array); this.array[index5 * this.itemSize + 3] = w; return this; } setXY(index5, x2, y2) { index5 *= this.itemSize; if (this.normalized) { x2 = normalize(x2, this.array); y2 = normalize(y2, this.array); } this.array[index5 + 0] = x2; this.array[index5 + 1] = y2; return this; } setXYZ(index5, x2, y2, z2) { index5 *= this.itemSize; if (this.normalized) { x2 = normalize(x2, this.array); y2 = normalize(y2, this.array); z2 = normalize(z2, this.array); } this.array[index5 + 0] = x2; this.array[index5 + 1] = y2; this.array[index5 + 2] = z2; return this; } setXYZW(index5, x2, y2, z2, w) { index5 *= this.itemSize; if (this.normalized) { x2 = normalize(x2, this.array); y2 = normalize(y2, this.array); z2 = normalize(z2, this.array); w = normalize(w, this.array); } this.array[index5 + 0] = x2; this.array[index5 + 1] = y2; this.array[index5 + 2] = z2; this.array[index5 + 3] = w; 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.from(this.array), normalized: this.normalized }; if (this.name !== "") data.name = this.name; if (this.usage !== StaticDrawUsage) data.usage = this.usage; return data; } }; 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 Float32BufferAttribute = class extends BufferAttribute { constructor(array, itemSize, normalized) { super(new Float32Array(array), itemSize, normalized); } }; var _id$2 = 0; var _m1$2 = /* @__PURE__ */ new Matrix4(); var _obj = /* @__PURE__ */ new Object3D(); var _offset = /* @__PURE__ */ new Vector3(); var _box$2 = /* @__PURE__ */ new Box3(); var _boxMorphTargets = /* @__PURE__ */ new Box3(); var _vector$8 = /* @__PURE__ */ new Vector3(); var BufferGeometry = class _BufferGeometry extends EventDispatcher { constructor() { super(); this.isBufferGeometry = true; Object.defineProperty(this, "id", { value: _id$2++ }); this.uuid = generateUUID(); this.name = ""; this.type = "BufferGeometry"; this.index = null; this.indirect = 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(index5) { if (Array.isArray(index5)) { this.index = new (arrayNeedsUint32(index5) ? Uint32BufferAttribute : Uint16BufferAttribute)(index5, 1); } else { this.index = index5; } return this; } setIndirect(indirect) { this.indirect = indirect; return this; } getIndirect() { return this.indirect; } getAttribute(name) { return this.attributes[name]; } setAttribute(name, attribute2) { this.attributes[name] = attribute2; 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 normal2 = this.attributes.normal; if (normal2 !== void 0) { const normalMatrix = new Matrix3().getNormalMatrix(matrix); normal2.applyNormalMatrix(normalMatrix); normal2.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$2.makeRotationFromQuaternion(q); this.applyMatrix4(_m1$2); return this; } rotateX(angle) { _m1$2.makeRotationX(angle); this.applyMatrix4(_m1$2); return this; } rotateY(angle) { _m1$2.makeRotationY(angle); this.applyMatrix4(_m1$2); return this; } rotateZ(angle) { _m1$2.makeRotationZ(angle); this.applyMatrix4(_m1$2); return this; } translate(x2, y2, z2) { _m1$2.makeTranslation(x2, y2, z2); this.applyMatrix4(_m1$2); return this; } scale(x2, y2, z2) { _m1$2.makeScale(x2, y2, z2); this.applyMatrix4(_m1$2); 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 positionAttribute = this.getAttribute("position"); if (positionAttribute === void 0) { 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)); } else { for (let i = 0, l = positionAttribute.count; i < l; i++) { const point = points[i]; positionAttribute.setXYZ(i, point.x, point.y, point.z || 0); } if (points.length > positionAttribute.count) { console.warn("THREE.BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry."); } positionAttribute.needsUpdate = true; } 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.", 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$2.setFromBufferAttribute(morphAttribute); if (this.morphTargetsRelative) { _vector$8.addVectors(this.boundingBox.min, _box$2.min); this.boundingBox.expandByPoint(_vector$8); _vector$8.addVectors(this.boundingBox.max, _box$2.max); this.boundingBox.expandByPoint(_vector$8); } else { this.boundingBox.expandByPoint(_box$2.min); this.boundingBox.expandByPoint(_box$2.max); } } } } else { this.boundingBox.makeEmpty(); } if (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) { console.error('THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this); } } computeBoundingSphere() { 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.", this); this.boundingSphere.set(new Vector3(), Infinity); return; } if (position) { const center = this.boundingSphere.center; _box$2.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$2.min, _boxMorphTargets.min); _box$2.expandByPoint(_vector$8); _vector$8.addVectors(_box$2.max, _boxMorphTargets.max); _box$2.expandByPoint(_vector$8); } else { _box$2.expandByPoint(_boxMorphTargets.min); _box$2.expandByPoint(_boxMorphTargets.max); } } } _box$2.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 index5 = this.index; const attributes = this.attributes; if (index5 === 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 positionAttribute = attributes.position; const normalAttribute = attributes.normal; const uvAttribute = attributes.uv; if (this.hasAttribute("tangent") === false) { this.setAttribute("tangent", new BufferAttribute(new Float32Array(4 * positionAttribute.count), 4)); } const tangentAttribute = this.getAttribute("tangent"); const tan1 = [], tan2 = []; for (let i = 0; i < positionAttribute.count; 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, b, c2) { vA.fromBufferAttribute(positionAttribute, a2); vB.fromBufferAttribute(positionAttribute, b); vC.fromBufferAttribute(positionAttribute, c2); uvA.fromBufferAttribute(uvAttribute, a2); uvB.fromBufferAttribute(uvAttribute, b); uvC.fromBufferAttribute(uvAttribute, c2); 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[b].add(sdir); tan1[c2].add(sdir); tan2[a2].add(tdir); tan2[b].add(tdir); tan2[c2].add(tdir); } let groups = this.groups; if (groups.length === 0) { groups = [{ start: 0, count: index5.count }]; } 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( index5.getX(j + 0), index5.getX(j + 1), index5.getX(j + 2) ); } } const tmp2 = new Vector3(), tmp22 = new Vector3(); const n = new Vector3(), n2 = new Vector3(); function handleVertex(v) { n.fromBufferAttribute(normalAttribute, v); n2.copy(n); const t = tan1[v]; tmp2.copy(t); tmp2.sub(n.multiplyScalar(n.dot(t))).normalize(); tmp22.crossVectors(n2, t); const test = tmp22.dot(tan2[v]); const w = test < 0 ? -1 : 1; tangentAttribute.setXYZW(v, tmp2.x, tmp2.y, tmp2.z, w); } 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(index5.getX(j + 0)); handleVertex(index5.getX(j + 1)); handleVertex(index5.getX(j + 2)); } } } computeVertexNormals() { const index5 = 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 cb = new Vector3(), ab = new Vector3(); if (index5) { for (let i = 0, il = index5.count; i < il; i += 3) { const vA = index5.getX(i + 0); const vB = index5.getX(i + 1); const vC = index5.getX(i + 2); pA.fromBufferAttribute(positionAttribute, vA); pB.fromBufferAttribute(positionAttribute, vB); pC.fromBufferAttribute(positionAttribute, vC); cb.subVectors(pC, pB); ab.subVectors(pA, pB); cb.cross(ab); nA.fromBufferAttribute(normalAttribute, vA); nB.fromBufferAttribute(normalAttribute, vB); nC.fromBufferAttribute(normalAttribute, vC); nA.add(cb); nB.add(cb); nC.add(cb); 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); cb.subVectors(pC, pB); ab.subVectors(pA, pB); cb.cross(ab); normalAttribute.setXYZ(i + 0, cb.x, cb.y, cb.z); normalAttribute.setXYZ(i + 1, cb.x, cb.y, cb.z); normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z); } } this.normalizeNormals(); normalAttribute.needsUpdate = true; } } 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(attribute2, indices2) { const array = attribute2.array; const itemSize = attribute2.itemSize; const normalized = attribute2.normalized; const array2 = new array.constructor(indices2.length * itemSize); let index5 = 0, index22 = 0; for (let i = 0, l = indices2.length; i < l; i++) { if (attribute2.isInterleavedBufferAttribute) { index5 = indices2[i] * attribute2.data.stride + attribute2.offset; } else { index5 = indices2[i] * itemSize; } for (let j = 0; j < itemSize; j++) { array2[index22++] = array[index5++]; } } 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 attribute2 = attributes[name]; const newAttribute = convertBufferAttribute(attribute2, 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 attribute2 = morphAttribute[i]; const newAttribute = convertBufferAttribute(attribute2, 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.6, 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 index5 = this.index; if (index5 !== null) { data.data.index = { type: index5.array.constructor.name, array: Array.prototype.slice.call(index5.array) }; } const attributes = this.attributes; for (const key in attributes) { const attribute2 = attributes[key]; data.data.attributes[key] = attribute2.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 attribute2 = attributeArray[i]; array.push(attribute2.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 this.constructor().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 index5 = source.index; if (index5 !== null) { this.setIndex(index5.clone(data)); } const attributes = source.attributes; for (const name in attributes) { const attribute2 = attributes[name]; this.setAttribute(name, attribute2.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" }); } }; var _inverseMatrix$3 = /* @__PURE__ */ new Matrix4(); var _ray$3 = /* @__PURE__ */ new Ray(); var _sphere$6 = /* @__PURE__ */ new Sphere(); var _sphereHitAt = /* @__PURE__ */ new Vector3(); var _vA$1 = /* @__PURE__ */ new Vector3(); var _vB$1 = /* @__PURE__ */ new Vector3(); var _vC$1 = /* @__PURE__ */ new Vector3(); var _tempA = /* @__PURE__ */ new Vector3(); var _morphA = /* @__PURE__ */ new Vector3(); var _intersectionPoint = /* @__PURE__ */ new Vector3(); var _intersectionPointWorld = /* @__PURE__ */ new Vector3(); var Mesh = class extends Object3D { constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) { super(); this.isMesh = true; this.type = "Mesh"; this.geometry = geometry; this.material = material; this.updateMorphTargets(); } copy(source, recursive) { super.copy(source, recursive); if (source.morphTargetInfluences !== void 0) { this.morphTargetInfluences = source.morphTargetInfluences.slice(); } if (source.morphTargetDictionary !== void 0) { this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); } this.material = Array.isArray(source.material) ? source.material.slice() : source.material; this.geometry = source.geometry; return this; } updateMorphTargets() { const geometry = this.geometry; 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 m2 = 0, ml = morphAttribute.length; m2 < ml; m2++) { const name = morphAttribute[m2].name || String(m2); this.morphTargetInfluences.push(0); this.morphTargetDictionary[name] = m2; } } } } getVertexPosition(index5, target) { const geometry = this.geometry; const position = geometry.attributes.position; const morphPosition = geometry.morphAttributes.position; const morphTargetsRelative = geometry.morphTargetsRelative; target.fromBufferAttribute(position, index5); const morphInfluences = this.morphTargetInfluences; if (morphPosition && morphInfluences) { _morphA.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, index5); if (morphTargetsRelative) { _morphA.addScaledVector(_tempA, influence); } else { _morphA.addScaledVector(_tempA.sub(target), influence); } } target.add(_morphA); } return target; } raycast(raycaster, intersects) { const geometry = this.geometry; const material = this.material; const matrixWorld = this.matrixWorld; if (material === void 0) return; if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$6.copy(geometry.boundingSphere); _sphere$6.applyMatrix4(matrixWorld); _ray$3.copy(raycaster.ray).recast(raycaster.near); if (_sphere$6.containsPoint(_ray$3.origin) === false) { if (_ray$3.intersectSphere(_sphere$6, _sphereHitAt) === null) return; if (_ray$3.origin.distanceToSquared(_sphereHitAt) > (raycaster.far - raycaster.near) ** 2) return; } _inverseMatrix$3.copy(matrixWorld).invert(); _ray$3.copy(raycaster.ray).applyMatrix4(_inverseMatrix$3); if (geometry.boundingBox !== null) { if (_ray$3.intersectsBox(geometry.boundingBox) === false) return; } this._computeIntersections(raycaster, intersects, _ray$3); } _computeIntersections(raycaster, intersects, rayLocalSpace) { let intersection; const geometry = this.geometry; const material = this.material; const index5 = geometry.index; const position = geometry.attributes.position; const uv2 = geometry.attributes.uv; const uv1 = geometry.attributes.uv1; const normal2 = geometry.attributes.normal; const groups = geometry.groups; const drawRange = geometry.drawRange; if (index5 !== 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(index5.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); for (let j = start, jl = end; j < jl; j += 3) { const a2 = index5.getX(j); const b = index5.getX(j + 1); const c2 = index5.getX(j + 2); intersection = checkGeometryIntersection(this, groupMaterial, raycaster, rayLocalSpace, uv2, uv1, normal2, a2, b, c2); if (intersection) { intersection.faceIndex = Math.floor(j / 3); intersection.face.materialIndex = group.materialIndex; intersects.push(intersection); } } } } else { const start = Math.max(0, drawRange.start); const end = Math.min(index5.count, drawRange.start + drawRange.count); for (let i = start, il = end; i < il; i += 3) { const a2 = index5.getX(i); const b = index5.getX(i + 1); const c2 = index5.getX(i + 2); intersection = checkGeometryIntersection(this, material, raycaster, rayLocalSpace, uv2, uv1, normal2, a2, b, c2); if (intersection) { intersection.faceIndex = Math.floor(i / 3); intersects.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(position.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); for (let j = start, jl = end; j < jl; j += 3) { const a2 = j; const b = j + 1; const c2 = j + 2; intersection = checkGeometryIntersection(this, groupMaterial, raycaster, rayLocalSpace, uv2, uv1, normal2, a2, b, c2); if (intersection) { intersection.faceIndex = Math.floor(j / 3); intersection.face.materialIndex = group.materialIndex; intersects.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 b = i + 1; const c2 = i + 2; intersection = checkGeometryIntersection(this, material, raycaster, rayLocalSpace, uv2, uv1, normal2, a2, b, c2); if (intersection) { intersection.faceIndex = Math.floor(i / 3); intersects.push(intersection); } } } } } }; function checkIntersection$1(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 === FrontSide, point); } if (intersect2 === null) return null; _intersectionPointWorld.copy(point); _intersectionPointWorld.applyMatrix4(object.matrixWorld); const distance2 = raycaster.ray.origin.distanceTo(_intersectionPointWorld); if (distance2 < raycaster.near || distance2 > raycaster.far) return null; return { distance: distance2, point: _intersectionPointWorld.clone(), object }; } function checkGeometryIntersection(object, material, raycaster, ray, uv2, uv1, normal2, a2, b, c2) { object.getVertexPosition(a2, _vA$1); object.getVertexPosition(b, _vB$1); object.getVertexPosition(c2, _vC$1); const intersection = checkIntersection$1(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint); if (intersection) { const barycoord = new Vector3(); Triangle.getBarycoord(_intersectionPoint, _vA$1, _vB$1, _vC$1, barycoord); if (uv2) { intersection.uv = Triangle.getInterpolatedAttribute(uv2, a2, b, c2, barycoord, new Vector2()); } if (uv1) { intersection.uv1 = Triangle.getInterpolatedAttribute(uv1, a2, b, c2, barycoord, new Vector2()); } if (normal2) { intersection.normal = Triangle.getInterpolatedAttribute(normal2, a2, b, c2, barycoord, new Vector3()); if (intersection.normal.dot(ray.direction) > 0) { intersection.normal.multiplyScalar(-1); } } const face = { a: a2, b, c: c2, normal: new Vector3(), materialIndex: 0 }; Triangle.getNormal(_vA$1, _vB$1, _vC$1, face.normal); intersection.face = face; intersection.barycoord = barycoord; } return intersection; } var BoxGeometry = class _BoxGeometry extends BufferGeometry { constructor(width = 1, height = 1, depth2 = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) { super(); this.type = "BoxGeometry"; this.parameters = { width, height, depth: depth2, 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, depth2, height, width, depthSegments, heightSegments, 0); buildPlane("z", "y", "x", 1, -1, depth2, height, -width, depthSegments, heightSegments, 1); buildPlane("x", "z", "y", 1, 1, width, depth2, height, widthSegments, depthSegments, 2); buildPlane("x", "z", "y", 1, -1, width, depth2, -height, widthSegments, depthSegments, 3); buildPlane("x", "y", "z", 1, -1, width, height, depth2, widthSegments, heightSegments, 4); buildPlane("x", "y", "z", -1, -1, width, height, -depth2, 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, w, udir, vdir, width2, height2, depth3, gridX, gridY, materialIndex) { const segmentWidth = width2 / gridX; const segmentHeight = height2 / gridY; const widthHalf = width2 / 2; const heightHalf = height2 / 2; const depthHalf = depth3 / 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 y2 = iy * segmentHeight - heightHalf; for (let ix = 0; ix < gridX1; ix++) { const x2 = ix * segmentWidth - widthHalf; vector[u] = x2 * udir; vector[v] = y2 * vdir; vector[w] = depthHalf; vertices.push(vector.x, vector.y, vector.z); vector[u] = 0; vector[v] = 0; vector[w] = depth3 > 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 b = numberOfVertices + ix + gridX1 * (iy + 1); const c2 = numberOfVertices + (ix + 1) + gridX1 * (iy + 1); const d = numberOfVertices + (ix + 1) + gridX1 * iy; indices.push(a2, b, d); indices.push(b, c2, d); groupCount += 6; } } scope.addGroup(groupStart, groupCount, materialIndex); groupStart += groupCount; numberOfVertices += vertexCounter; } } copy(source) { super.copy(source); this.parameters = Object.assign({}, source.parameters); return this; } 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 p in src[u]) { const property2 = src[u][p]; if (property2 && (property2.isColor || property2.isMatrix3 || property2.isMatrix4 || property2.isVector2 || property2.isVector3 || property2.isVector4 || property2.isTexture || property2.isQuaternion)) { if (property2.isRenderTargetTexture) { console.warn("UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms()."); dst[u][p] = null; } else { dst[u][p] = property2.clone(); } } else if (Array.isArray(property2)) { dst[u][p] = property2.slice(); } else { dst[u][p] = property2; } } } return dst; } function mergeUniforms(uniforms) { const merged = {}; for (let u = 0; u < uniforms.length; u++) { const tmp2 = cloneUniforms(uniforms[u]); for (const p in tmp2) { merged[p] = tmp2[p]; } } return merged; } function cloneUniformsGroups(src) { const dst = []; for (let u = 0; u < src.length; u++) { dst.push(src[u].clone()); } return dst; } function getUnlitUniformColorSpace(renderer3) { const currentRenderTarget = renderer3.getRenderTarget(); if (currentRenderTarget === null) { return renderer3.outputColorSpace; } if (currentRenderTarget.isXRRenderTarget === true) { return currentRenderTarget.texture.colorSpace; } return ColorManagement.workingColorSpace; } 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 { static get type() { return "ShaderMaterial"; } constructor(parameters) { super(); this.isShaderMaterial = true; this.defines = {}; this.uniforms = {}; this.uniformsGroups = []; 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.forceSinglePass = true; this.extensions = { clipCullDistance: false, // set to use vertex shader clipping multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID }; this.defaultAttributeValues = { "color": [1, 1, 1], "uv": [0, 0], "uv1": [0, 0] }; this.index0AttributeName = void 0; this.uniformsNeedUpdate = false; this.glslVersion = null; if (parameters !== void 0) { this.setValues(parameters); } } copy(source) { super.copy(source); this.fragmentShader = source.fragmentShader; this.vertexShader = source.vertexShader; this.uniforms = cloneUniforms(source.uniforms); this.uniformsGroups = cloneUniformsGroups(source.uniformsGroups); this.defines = Object.assign({}, source.defines); this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; this.fog = source.fog; 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 uniform2 = this.uniforms[name]; const value = uniform2.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; data.lights = this.lights; data.clipping = this.clipping; 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; } }; var Camera = class extends Object3D { constructor() { super(); this.isCamera = true; this.type = "Camera"; this.matrixWorldInverse = new Matrix4(); this.projectionMatrix = new Matrix4(); this.projectionMatrixInverse = new Matrix4(); this.coordinateSystem = WebGLCoordinateSystem; } copy(source, recursive) { super.copy(source, recursive); this.matrixWorldInverse.copy(source.matrixWorldInverse); this.projectionMatrix.copy(source.projectionMatrix); this.projectionMatrixInverse.copy(source.projectionMatrixInverse); this.coordinateSystem = source.coordinateSystem; return this; } getWorldDirection(target) { return super.getWorldDirection(target).negate(); } 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); } }; var _v3$1 = /* @__PURE__ */ new Vector3(); var _minTarget = /* @__PURE__ */ new Vector2(); var _maxTarget = /* @__PURE__ */ new Vector2(); var PerspectiveCamera = class extends Camera { constructor(fov3 = 50, aspect3 = 1, near = 0.1, far = 2e3) { super(); this.isPerspectiveCamera = true; this.type = "PerspectiveCamera"; this.fov = fov3; this.zoom = 1; this.near = near; this.far = far; this.focus = 10; this.aspect = aspect3; 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; } /** * Sets the FOV by focal length in respect to the current .filmGauge. * * The default film gauge is 35, so that the focal length can be specified for * a 35mm (full frame) camera. * * Values for focal length and film gauge must have the same unit. */ setFocalLength(focalLength) { const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; this.fov = RAD2DEG * 2 * Math.atan(vExtentSlope); this.updateProjectionMatrix(); } /** * Calculates the focal length from the current .fov and .filmGauge. */ 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); } /** * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. * Sets minTarget and maxTarget to the coordinates of the lower-left and upper-right corners of the view rectangle. */ getViewBounds(distance2, minTarget, maxTarget) { _v3$1.set(-1, -1, 0.5).applyMatrix4(this.projectionMatrixInverse); minTarget.set(_v3$1.x, _v3$1.y).multiplyScalar(-distance2 / _v3$1.z); _v3$1.set(1, 1, 0.5).applyMatrix4(this.projectionMatrixInverse); maxTarget.set(_v3$1.x, _v3$1.y).multiplyScalar(-distance2 / _v3$1.z); } /** * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. * Copies the result into the target Vector2, where x is width and y is height. */ getViewSize(distance2, target) { this.getViewBounds(distance2, _minTarget, _maxTarget); return target.subVectors(_maxTarget, _minTarget); } /** * Sets an offset in a larger frustum. This is useful for multi-window or * multi-monitor/multi-machine setups. * * For example, if you have 3x2 monitors and each monitor is 1920x1080 and * the monitors are in grid like this * * +---+---+---+ * | A | B | C | * +---+---+---+ * | D | E | F | * +---+---+---+ * * then for each monitor you would call it like this * * const w = 1920; * const h = 1080; * const fullWidth = w * 3; * const fullHeight = h * 2; * * --A-- * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); * --B-- * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); * --C-- * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); * --D-- * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); * --E-- * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); * --F-- * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); * * Note there is no reason monitors have to be the same size or in a grid. */ setViewOffset(fullWidth, fullHeight, x2, y2, 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 = x2; this.view.offsetY = y2; 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.coordinateSystem); 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; } }; var fov = -90; var aspect = 1; var CubeCamera = class extends Object3D { constructor(near, far, renderTarget) { super(); this.type = "CubeCamera"; this.renderTarget = renderTarget; this.coordinateSystem = null; this.activeMipmapLevel = 0; const cameraPX = new PerspectiveCamera(fov, aspect, near, far); cameraPX.layers = this.layers; this.add(cameraPX); const cameraNX = new PerspectiveCamera(fov, aspect, near, far); cameraNX.layers = this.layers; this.add(cameraNX); const cameraPY = new PerspectiveCamera(fov, aspect, near, far); cameraPY.layers = this.layers; this.add(cameraPY); const cameraNY = new PerspectiveCamera(fov, aspect, near, far); cameraNY.layers = this.layers; this.add(cameraNY); const cameraPZ = new PerspectiveCamera(fov, aspect, near, far); cameraPZ.layers = this.layers; this.add(cameraPZ); const cameraNZ = new PerspectiveCamera(fov, aspect, near, far); cameraNZ.layers = this.layers; this.add(cameraNZ); } updateCoordinateSystem() { const coordinateSystem = this.coordinateSystem; const cameras = this.children.concat(); const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = cameras; for (const camera3 of cameras) this.remove(camera3); if (coordinateSystem === WebGLCoordinateSystem) { cameraPX.up.set(0, 1, 0); cameraPX.lookAt(1, 0, 0); cameraNX.up.set(0, 1, 0); cameraNX.lookAt(-1, 0, 0); cameraPY.up.set(0, 0, -1); cameraPY.lookAt(0, 1, 0); cameraNY.up.set(0, 0, 1); cameraNY.lookAt(0, -1, 0); cameraPZ.up.set(0, 1, 0); cameraPZ.lookAt(0, 0, 1); cameraNZ.up.set(0, 1, 0); cameraNZ.lookAt(0, 0, -1); } else if (coordinateSystem === WebGPUCoordinateSystem) { cameraPX.up.set(0, -1, 0); cameraPX.lookAt(-1, 0, 0); cameraNX.up.set(0, -1, 0); cameraNX.lookAt(1, 0, 0); cameraPY.up.set(0, 0, 1); cameraPY.lookAt(0, 1, 0); cameraNY.up.set(0, 0, -1); cameraNY.lookAt(0, -1, 0); cameraPZ.up.set(0, -1, 0); cameraPZ.lookAt(0, 0, 1); cameraNZ.up.set(0, -1, 0); cameraNZ.lookAt(0, 0, -1); } else { throw new Error("THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: " + coordinateSystem); } for (const camera3 of cameras) { this.add(camera3); camera3.updateMatrixWorld(); } } update(renderer3, scene3) { if (this.parent === null) this.updateMatrixWorld(); const { renderTarget, activeMipmapLevel } = this; if (this.coordinateSystem !== renderer3.coordinateSystem) { this.coordinateSystem = renderer3.coordinateSystem; this.updateCoordinateSystem(); } const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = this.children; const currentRenderTarget = renderer3.getRenderTarget(); const currentActiveCubeFace = renderer3.getActiveCubeFace(); const currentActiveMipmapLevel = renderer3.getActiveMipmapLevel(); const currentXrEnabled = renderer3.xr.enabled; renderer3.xr.enabled = false; const generateMipmaps = renderTarget.texture.generateMipmaps; renderTarget.texture.generateMipmaps = false; renderer3.setRenderTarget(renderTarget, 0, activeMipmapLevel); renderer3.render(scene3, cameraPX); renderer3.setRenderTarget(renderTarget, 1, activeMipmapLevel); renderer3.render(scene3, cameraNX); renderer3.setRenderTarget(renderTarget, 2, activeMipmapLevel); renderer3.render(scene3, cameraPY); renderer3.setRenderTarget(renderTarget, 3, activeMipmapLevel); renderer3.render(scene3, cameraNY); renderer3.setRenderTarget(renderTarget, 4, activeMipmapLevel); renderer3.render(scene3, cameraPZ); renderTarget.texture.generateMipmaps = generateMipmaps; renderer3.setRenderTarget(renderTarget, 5, activeMipmapLevel); renderer3.render(scene3, cameraNZ); renderer3.setRenderTarget(currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel); renderer3.xr.enabled = currentXrEnabled; renderTarget.texture.needsPMREMUpdate = true; } }; var CubeTexture = class extends Texture { constructor(images, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy2, colorSpace) { images = images !== void 0 ? images : []; mapping = mapping !== void 0 ? mapping : CubeReflectionMapping; super(images, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy2, colorSpace); this.isCubeTexture = true; this.flipY = false; } get images() { return this.image; } set images(value) { this.image = value; } }; var WebGLCubeRenderTarget = class extends WebGLRenderTarget { constructor(size = 1, options = {}) { super(size, size, options); this.isWebGLCubeRenderTarget = true; const image = { width: size, height: size, depth: 1 }; const images = [image, image, image, image, image, image]; this.texture = new CubeTexture(images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.colorSpace); this.texture.isRenderTargetTexture = true; this.texture.generateMipmaps = options.generateMipmaps !== void 0 ? options.generateMipmaps : false; this.texture.minFilter = options.minFilter !== void 0 ? options.minFilter : LinearFilter; } fromEquirectangularTexture(renderer3, texture2) { this.texture.type = texture2.type; this.texture.colorSpace = texture2.colorSpace; this.texture.generateMipmaps = texture2.generateMipmaps; this.texture.minFilter = texture2.minFilter; this.texture.magFilter = texture2.magFilter; const shader = { uniforms: { tEquirect: { value: null } }, vertexShader: ( /* glsl */ ` varying vec3 vWorldDirection; vec3 transformDirection( in vec3 dir, in mat4 matrix ) { return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); } void main() { vWorldDirection = transformDirection( position, modelMatrix ); #include <begin_vertex> #include <project_vertex> } ` ), fragmentShader: ( /* glsl */ ` uniform sampler2D tEquirect; varying vec3 vWorldDirection; #include <common> 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 = texture2; const mesh = new Mesh(geometry, material); const currentMinFilter = texture2.minFilter; if (texture2.minFilter === LinearMipmapLinearFilter) texture2.minFilter = LinearFilter; const camera3 = new CubeCamera(1, 10, this); camera3.update(renderer3, mesh); texture2.minFilter = currentMinFilter; mesh.geometry.dispose(); mesh.material.dispose(); return this; } clear(renderer3, color2, depth2, stencil) { const currentRenderTarget = renderer3.getRenderTarget(); for (let i = 0; i < 6; i++) { renderer3.setRenderTarget(this, i); renderer3.clear(color2, depth2, stencil); } renderer3.setRenderTarget(currentRenderTarget); } }; var _vector1 = /* @__PURE__ */ new Vector3(); var _vector2 = /* @__PURE__ */ new Vector3(); var _normalMatrix = /* @__PURE__ */ new Matrix3(); var Plane = class { constructor(normal2 = new Vector3(1, 0, 0), constant = 0) { this.isPlane = true; this.normal = normal2; this.constant = constant; } set(normal2, constant) { this.normal.copy(normal2); this.constant = constant; return this; } setComponents(x2, y2, z2, w) { this.normal.set(x2, y2, z2); this.constant = w; return this; } setFromNormalAndCoplanarPoint(normal2, point) { this.normal.copy(normal2); this.constant = -point.dot(this.normal); return this; } setFromCoplanarPoints(a2, b, c2) { const normal2 = _vector1.subVectors(c2, b).cross(_vector2.subVectors(a2, b)).normalize(); this.setFromNormalAndCoplanarPoint(normal2, 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(point).addScaledVector(this.normal, -this.distanceToPoint(point)); } intersectLine(line, target) { const direction2 = line.delta(_vector1); const denominator = this.normal.dot(direction2); 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(line.start).addScaledVector(direction2, t); } 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 normal2 = this.normal.applyMatrix3(normalMatrix).normalize(); this.constant = -referencePoint.dot(normal2); 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); } }; var _sphere$5 = /* @__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(m2, coordinateSystem = WebGLCoordinateSystem) { const planes = this.planes; const me = m2.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(); if (coordinateSystem === WebGLCoordinateSystem) { planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize(); } else if (coordinateSystem === WebGPUCoordinateSystem) { planes[5].setComponents(me2, me6, me10, me14).normalize(); } else { throw new Error("THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: " + coordinateSystem); } return this; } intersectsObject(object) { if (object.boundingSphere !== void 0) { if (object.boundingSphere === null) object.computeBoundingSphere(); _sphere$5.copy(object.boundingSphere).applyMatrix4(object.matrixWorld); } else { const geometry = object.geometry; if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$5.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld); } return this.intersectsSphere(_sphere$5); } intersectsSprite(sprite) { _sphere$5.center.set(0, 0, 0); _sphere$5.radius = 0.7071067811865476; _sphere$5.applyMatrix4(sprite.matrixWorld); return this.intersectsSphere(_sphere$5); } intersectsSphere(sphere) { const planes = this.planes; const center = sphere.center; const negRadius = -sphere.radius; for (let i = 0; i < 6; i++) { const distance2 = planes[i].distanceToPoint(center); if (distance2 < 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 context2 = null; let isAnimating = false; let animationLoop = null; let requestId = null; function onAnimationFrame(time, frame2) { animationLoop(time, frame2); requestId = context2.requestAnimationFrame(onAnimationFrame); } return { start: function() { if (isAnimating === true) return; if (animationLoop === null) return; requestId = context2.requestAnimationFrame(onAnimationFrame); isAnimating = true; }, stop: function() { context2.cancelAnimationFrame(requestId); isAnimating = false; }, setAnimationLoop: function(callback) { animationLoop = callback; }, setContext: function(value) { context2 = value; } }; } function WebGLAttributes(gl) { const buffers = /* @__PURE__ */ new WeakMap(); function createBuffer(attribute2, bufferType) { const array = attribute2.array; const usage = attribute2.usage; const size = array.byteLength; const buffer2 = gl.createBuffer(); gl.bindBuffer(bufferType, buffer2); gl.bufferData(bufferType, array, usage); attribute2.onUploadCallback(); let type; if (array instanceof Float32Array) { type = gl.FLOAT; } else if (array instanceof Uint16Array) { if (attribute2.isFloat16BufferAttribute) { type = gl.HALF_FLOAT; } else { type = gl.UNSIGNED_SHORT; } } else if (array instanceof Int16Array) { type = gl.SHORT; } else if (array instanceof Uint32Array) { type = gl.UNSIGNED_INT; } else if (array instanceof Int32Array) { type = gl.INT; } else if (array instanceof Int8Array) { type = gl.BYTE; } else if (array instanceof Uint8Array) { type = gl.UNSIGNED_BYTE; } else if (array instanceof Uint8ClampedArray) { type = gl.UNSIGNED_BYTE; } else { throw new Error("THREE.WebGLAttributes: Unsupported buffer data format: " + array); } return { buffer: buffer2, type, bytesPerElement: array.BYTES_PER_ELEMENT, version: attribute2.version, size }; } function updateBuffer(buffer2, attribute2, bufferType) { const array = attribute2.array; const updateRanges = attribute2.updateRanges; gl.bindBuffer(bufferType, buffer2); if (updateRanges.length === 0) { gl.bufferSubData(bufferType, 0, array); } else { updateRanges.sort((a2, b) => a2.start - b.start); let mergeIndex = 0; for (let i = 1; i < updateRanges.length; i++) { const previousRange = updateRanges[mergeIndex]; const range = updateRanges[i]; if (range.start <= previousRange.start + previousRange.count + 1) { previousRange.count = Math.max( previousRange.count, range.start + range.count - previousRange.start ); } else { ++mergeIndex; updateRanges[mergeIndex] = range; } } updateRanges.length = mergeIndex + 1; for (let i = 0, l = updateRanges.length; i < l; i++) { const range = updateRanges[i]; gl.bufferSubData( bufferType, range.start * array.BYTES_PER_ELEMENT, array, range.start, range.count ); } attribute2.clearUpdateRanges(); } attribute2.onUploadCallback(); } function get2(attribute2) { if (attribute2.isInterleavedBufferAttribute) attribute2 = attribute2.data; return buffers.get(attribute2); } function remove2(attribute2) { if (attribute2.isInterleavedBufferAttribute) attribute2 = attribute2.data; const data = buffers.get(attribute2); if (data) { gl.deleteBuffer(data.buffer); buffers.delete(attribute2); } } function update4(attribute2, bufferType) { if (attribute2.isInterleavedBufferAttribute) attribute2 = attribute2.data; if (attribute2.isGLBufferAttribute) { const cached = buffers.get(attribute2); if (!cached || cached.version < attribute2.version) { buffers.set(attribute2, { buffer: attribute2.buffer, type: attribute2.type, bytesPerElement: attribute2.elementSize, version: attribute2.version }); } return; } const data = buffers.get(attribute2); if (data === void 0) { buffers.set(attribute2, createBuffer(attribute2, bufferType)); } else if (data.version < attribute2.version) { if (data.size !== attribute2.array.byteLength) { throw new Error("THREE.WebGLAttributes: The size of the buffer attribute's array buffer does not match the original size. Resizing buffer attributes is not supported."); } updateBuffer(data.buffer, attribute2, bufferType); data.version = attribute2.version; } } return { get: get2, remove: remove2, update: update4 }; } var PlaneGeometry = class _PlaneGeometry 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 y2 = iy * segment_height - height_half; for (let ix = 0; ix < gridX1; ix++) { const x2 = ix * segment_width - width_half; vertices.push(x2, -y2, 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 b = ix + gridX1 * (iy + 1); const c2 = ix + 1 + gridX1 * (iy + 1); const d = ix + 1 + gridX1 * iy; indices.push(a2, b, d); indices.push(b, 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)); } copy(source) { super.copy(source); this.parameters = Object.assign({}, source.parameters); return this; } static fromJSON(data) { return new _PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments); } }; var alphahash_fragment = "#ifdef USE_ALPHAHASH\n if ( diffuseColor.a < getAlphaHashThreshold( vPosition ) ) discard;\n#endif"; var alphahash_pars_fragment = "#ifdef USE_ALPHAHASH\n const float ALPHA_HASH_SCALE = 0.05;\n float hash2D( vec2 value ) {\n return fract( 1.0e4 * sin( 17.0 * value.x + 0.1 * value.y ) * ( 0.1 + abs( sin( 13.0 * value.y + value.x ) ) ) );\n }\n float hash3D( vec3 value ) {\n return hash2D( vec2( hash2D( value.xy ), value.z ) );\n }\n float getAlphaHashThreshold( vec3 position ) {\n float maxDeriv = max(\n length( dFdx( position.xyz ) ),\n length( dFdy( position.xyz ) )\n );\n float pixScale = 1.0 / ( ALPHA_HASH_SCALE * maxDeriv );\n vec2 pixScales = vec2(\n exp2( floor( log2( pixScale ) ) ),\n exp2( ceil( log2( pixScale ) ) )\n );\n vec2 alpha = vec2(\n hash3D( floor( pixScales.x * position.xyz ) ),\n hash3D( floor( pixScales.y * position.xyz ) )\n );\n float lerpFactor = fract( log2( pixScale ) );\n float x = ( 1.0 - lerpFactor ) * alpha.x + lerpFactor * alpha.y;\n float a = min( lerpFactor, 1.0 - lerpFactor );\n vec3 cases = vec3(\n x * x / ( 2.0 * a * ( 1.0 - a ) ),\n ( x - 0.5 * a ) / ( 1.0 - a ),\n 1.0 - ( ( 1.0 - x ) * ( 1.0 - x ) / ( 2.0 * a * ( 1.0 - a ) ) )\n );\n float threshold = ( x < ( 1.0 - a ) )\n ? ( ( x < a ) ? cases.x : cases.y )\n : cases.z;\n return clamp( threshold , 1.0e-6, 1.0 );\n }\n#endif"; var alphamap_fragment = "#ifdef USE_ALPHAMAP\n diffuseColor.a *= texture2D( alphaMap, vAlphaMapUv ).g;\n#endif"; var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n uniform sampler2D alphaMap;\n#endif"; var alphatest_fragment = "#ifdef USE_ALPHATEST\n #ifdef ALPHA_TO_COVERAGE\n diffuseColor.a = smoothstep( alphaTest, alphaTest + fwidth( diffuseColor.a ), diffuseColor.a );\n if ( diffuseColor.a == 0.0 ) discard;\n #else\n if ( diffuseColor.a < alphaTest ) discard;\n #endif\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, vAoMapUv ).r - 1.0 ) * aoMapIntensity + 1.0;\n reflectedLight.indirectDiffuse *= ambientOcclusion;\n #if defined( USE_CLEARCOAT ) \n clearcoatSpecularIndirect *= ambientOcclusion;\n #endif\n #if defined( USE_SHEEN ) \n sheenSpecularIndirect *= ambientOcclusion;\n #endif\n #if defined( USE_ENVMAP ) && defined( STANDARD )\n float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\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 batching_pars_vertex = "#ifdef USE_BATCHING\n #if ! defined( GL_ANGLE_multi_draw )\n #define gl_DrawID _gl_DrawID\n uniform int _gl_DrawID;\n #endif\n uniform highp sampler2D batchingTexture;\n uniform highp usampler2D batchingIdTexture;\n mat4 getBatchingMatrix( const in float i ) {\n int size = textureSize( batchingTexture, 0 ).x;\n int j = int( i ) * 4;\n int x = j % size;\n int y = j / size;\n vec4 v1 = texelFetch( batchingTexture, ivec2( x, y ), 0 );\n vec4 v2 = texelFetch( batchingTexture, ivec2( x + 1, y ), 0 );\n vec4 v3 = texelFetch( batchingTexture, ivec2( x + 2, y ), 0 );\n vec4 v4 = texelFetch( batchingTexture, ivec2( x + 3, y ), 0 );\n return mat4( v1, v2, v3, v4 );\n }\n float getIndirectIndex( const in int i ) {\n int size = textureSize( batchingIdTexture, 0 ).x;\n int x = i % size;\n int y = i / size;\n return float( texelFetch( batchingIdTexture, ivec2( x, y ), 0 ).r );\n }\n#endif\n#ifdef USE_BATCHING_COLOR\n uniform sampler2D batchingColorTexture;\n vec3 getBatchingColor( const in float i ) {\n int size = textureSize( batchingColorTexture, 0 ).x;\n int j = int( i );\n int x = j % size;\n int y = j / size;\n return texelFetch( batchingColorTexture, ivec2( x, y ), 0 ).rgb;\n }\n#endif"; var batching_vertex = "#ifdef USE_BATCHING\n mat4 batchingMatrix = getBatchingMatrix( getIndirectIndex( gl_DrawID ) );\n#endif"; var begin_vertex = "vec3 transformed = vec3( position );\n#ifdef USE_ALPHAHASH\n vPosition = vec3( position );\n#endif"; var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n vec3 objectTangent = vec3( tangent.xyz );\n#endif"; var bsdfs = "float 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 vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNH = saturate( dot( normal, halfDir ) );\n float dotVH = saturate( dot( 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} // validated"; var iridescence_fragment = "#ifdef USE_IRIDESCENCE\n const mat3 XYZ_TO_REC709 = mat3(\n 3.2404542, -0.9692660, 0.0556434,\n -1.5371385, 1.8760108, -0.2040259,\n -0.4985314, 0.0415560, 1.0572252\n );\n vec3 Fresnel0ToIor( vec3 fresnel0 ) {\n vec3 sqrtF0 = sqrt( fresnel0 );\n return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n }\n vec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n return pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n }\n float IorToFresnel0( float transmittedIor, float incidentIor ) {\n return pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n }\n vec3 evalSensitivity( float OPD, vec3 shift ) {\n float phase = 2.0 * PI * OPD * 1.0e-9;\n vec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n vec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n vec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n vec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var );\n xyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );\n xyz /= 1.0685e-7;\n vec3 rgb = XYZ_TO_REC709 * xyz;\n return rgb;\n }\n vec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n vec3 I;\n float iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n float sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n float cosTheta2Sq = 1.0 - sinTheta2Sq;\n if ( cosTheta2Sq < 0.0 ) {\n return vec3( 1.0 );\n }\n float cosTheta2 = sqrt( cosTheta2Sq );\n float R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n float R12 = F_Schlick( R0, 1.0, cosTheta1 );\n float T121 = 1.0 - R12;\n float phi12 = 0.0;\n if ( iridescenceIOR < outsideIOR ) phi12 = PI;\n float phi21 = PI - phi12;\n vec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) ); vec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n vec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n vec3 phi23 = vec3( 0.0 );\n if ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI;\n if ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI;\n if ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI;\n float OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n vec3 phi = vec3( phi21 ) + phi23;\n vec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n vec3 r123 = sqrt( R123 );\n vec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n vec3 C0 = R12 + Rs;\n I = C0;\n vec3 Cm = Rs - T121;\n for ( int m = 1; m <= 2; ++ m ) {\n Cm *= r123;\n vec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n I += Cm * Sm;\n }\n return max( I, vec3( 0.0 ) );\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( vBumpMapUv );\n vec2 dSTdy = dFdy( vBumpMapUv );\n float Hll = bumpScale * texture2D( bumpMap, vBumpMapUv ).x;\n float dBx = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdx ).x - Hll;\n float dBy = bumpScale * texture2D( bumpMap, vBumpMapUv + 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 = normalize( dFdx( surf_pos.xyz ) );\n vec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) );\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 #ifdef ALPHA_TO_COVERAGE\n float distanceToPlane, distanceGradient;\n float clipOpacity = 1.0;\n #pragma unroll_loop_start\n for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n plane = clippingPlanes[ i ];\n distanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n distanceGradient = fwidth( distanceToPlane ) / 2.0;\n clipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n if ( clipOpacity == 0.0 ) discard;\n }\n #pragma unroll_loop_end\n #if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n float unionClipOpacity = 1.0;\n #pragma unroll_loop_start\n for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n plane = clippingPlanes[ i ];\n distanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n distanceGradient = fwidth( distanceToPlane ) / 2.0;\n unionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n }\n #pragma unroll_loop_end\n clipOpacity *= 1.0 - unionClipOpacity;\n #endif\n diffuseColor.a *= clipOpacity;\n if ( diffuseColor.a == 0.0 ) discard;\n #else\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\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 ) || defined( USE_BATCHING_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 ) || defined( USE_BATCHING_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\n#ifdef USE_BATCHING_COLOR\n vec3 batchingColor = getBatchingColor( getIndirectIndex( gl_DrawID ) );\n vColor.xyz *= batchingColor.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; }\nvec3 pow2( const in vec3 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 v ) { return dot( v, vec3( 0.3333333 ) ); }\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};\n#ifdef USE_ALPHAHASH\n varying vec3 vPosition;\n#endif\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}\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}\nvec3 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 F_Schlick( const in float 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} // validated"; var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n #define cubeUV_minMipLevel 4.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 highp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n if ( face > 2.0 ) {\n uv.y += faceSize;\n face -= 3.0;\n }\n uv.x += face * faceSize;\n uv.x += filterInt * 3.0 * cubeUV_minTileSize;\n uv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n uv.x *= CUBEUV_TEXEL_WIDTH;\n uv.y *= CUBEUV_TEXEL_HEIGHT;\n #ifdef texture2DGradEXT\n return texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n #else\n return texture2D( envMap, uv ).rgb;\n #endif\n }\n #define cubeUV_r0 1.0\n #define cubeUV_m0 - 2.0\n #define cubeUV_r1 0.8\n #define cubeUV_m1 - 1.0\n #define cubeUV_r4 0.4\n #define cubeUV_m4 2.0\n #define cubeUV_r5 0.305\n #define cubeUV_m5 3.0\n #define cubeUV_r6 0.21\n #define cubeUV_m6 4.0\n float roughnessToMip( float roughness ) {\n float mip = 0.0;\n if ( roughness >= cubeUV_r1 ) {\n mip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n } else if ( roughness >= cubeUV_r4 ) {\n mip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n } else if ( roughness >= cubeUV_r5 ) {\n mip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n } else if ( roughness >= cubeUV_r6 ) {\n mip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_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 ), cubeUV_m0, CUBEUV_MAX_MIP );\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_TANGENT\n vec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n mat3 bm = mat3( batchingMatrix );\n transformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n transformedNormal = bm * transformedNormal;\n #ifdef USE_TANGENT\n transformedTangent = bm * transformedTangent;\n #endif\n#endif\n#ifdef USE_INSTANCING\n mat3 im = mat3( instanceMatrix );\n transformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n transformedNormal = im * transformedNormal;\n #ifdef USE_TANGENT\n transformedTangent = im * transformedTangent;\n #endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n transformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n transformedTangent = ( modelViewMatrix * vec4( transformedTangent, 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, vDisplacementMapUv ).x * displacementScale + displacementBias );\n#endif"; var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n vec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv );\n #ifdef DECODE_VIDEO_TEXTURE_EMISSIVE\n emissiveColor = sRGBTransferEOTF( emissiveColor );\n #endif\n totalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n uniform sampler2D emissiveMap;\n#endif"; var colorspace_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; var colorspace_pars_fragment = "vec4 LinearTransferOETF( in vec4 value ) {\n return value;\n}\nvec4 sRGBTransferEOTF( 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 sRGBTransferOETF( 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}"; 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, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\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 mat3 envMapRotation;\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 ) || defined( LAMBERT )\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 ) || defined( LAMBERT )\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 vec3( texture2D( gradientMap, coord ).r );\n #else\n vec2 fw = fwidth( coord ) * 0.5;\n return mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n #endif\n}"; var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n uniform sampler2D lightMap;\n uniform float lightMapIntensity;\n#endif"; var lights_lambert_fragment = "LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;"; var lights_lambert_pars_fragment = "varying vec3 vViewPosition;\nstruct LambertMaterial {\n vec3 diffuseColor;\n float specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_Lambert\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Lambert"; var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n uniform vec3 lightProbe[ 9 ];\n#endif\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 vec3 normal ) {\n vec3 worldNormal = inverseTransformDirection( 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 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}\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, 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 vec3 geometryPosition, out IncidentLight light ) {\n vec3 lVector = pointLight.position - geometryPosition;\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 vec3 geometryPosition, out IncidentLight light ) {\n vec3 lVector = spotLight.position - geometryPosition;\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 vec3 normal ) {\n float dotNL = dot( 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 = "#ifdef USE_ENVMAP\n vec3 getIBLIrradiance( const in vec3 normal ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, envMapRotation * 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 #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 reflectVec = reflect( - viewDir, normal );\n reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n reflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n vec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n return envMapColor.rgb * envMapIntensity;\n #else\n return vec3( 0.0 );\n #endif\n }\n #ifdef USE_ANISOTROPY\n vec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n #ifdef ENVMAP_TYPE_CUBE_UV\n vec3 bentNormal = cross( bitangent, viewDir );\n bentNormal = normalize( cross( bentNormal, bitangent ) );\n bentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n return getIBLRadiance( viewDir, bentNormal, roughness );\n #else\n return vec3( 0.0 );\n #endif\n }\n #endif\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 vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, 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"; 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 vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, 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"; var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\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 material.ior = ior;\n #ifdef USE_SPECULAR\n float specularIntensityFactor = specularIntensity;\n vec3 specularColorFactor = specularColor;\n #ifdef USE_SPECULAR_COLORMAP\n specularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n #endif\n #ifdef USE_SPECULAR_INTENSITYMAP\n specularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n #endif\n material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n #else\n float specularIntensityFactor = 1.0;\n vec3 specularColorFactor = vec3( 1.0 );\n material.specularF90 = 1.0;\n #endif\n material.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, 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, vClearcoatMapUv ).x;\n #endif\n #ifdef USE_CLEARCOAT_ROUGHNESSMAP\n material.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).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_DISPERSION\n material.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n material.iridescence = iridescence;\n material.iridescenceIOR = iridescenceIOR;\n #ifdef USE_IRIDESCENCEMAP\n material.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n #endif\n #ifdef USE_IRIDESCENCE_THICKNESSMAP\n material.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n #else\n material.iridescenceThickness = iridescenceThicknessMaximum;\n #endif\n#endif\n#ifdef USE_SHEEN\n material.sheenColor = sheenColor;\n #ifdef USE_SHEEN_COLORMAP\n material.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n #endif\n material.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n #ifdef USE_SHEEN_ROUGHNESSMAP\n material.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n #endif\n#endif\n#ifdef USE_ANISOTROPY\n #ifdef USE_ANISOTROPYMAP\n mat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n vec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n vec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n #else\n vec2 anisotropyV = anisotropyVector;\n #endif\n material.anisotropy = length( anisotropyV );\n if( material.anisotropy == 0.0 ) {\n anisotropyV = vec2( 1.0, 0.0 );\n } else {\n anisotropyV /= material.anisotropy;\n material.anisotropy = saturate( material.anisotropy );\n }\n material.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n material.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n material.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif"; var lights_physical_pars_fragment = "struct PhysicalMaterial {\n vec3 diffuseColor;\n float roughness;\n vec3 specularColor;\n float specularF90;\n float dispersion;\n #ifdef USE_CLEARCOAT\n float clearcoat;\n float clearcoatRoughness;\n vec3 clearcoatF0;\n float clearcoatF90;\n #endif\n #ifdef USE_IRIDESCENCE\n float iridescence;\n float iridescenceIOR;\n float iridescenceThickness;\n vec3 iridescenceFresnel;\n vec3 iridescenceF0;\n #endif\n #ifdef USE_SHEEN\n vec3 sheenColor;\n float sheenRoughness;\n #endif\n #ifdef IOR\n float ior;\n #endif\n #ifdef USE_TRANSMISSION\n float transmission;\n float transmissionAlpha;\n float thickness;\n float attenuationDistance;\n vec3 attenuationColor;\n #endif\n #ifdef USE_ANISOTROPY\n float anisotropy;\n float alphaT;\n vec3 anisotropyT;\n vec3 anisotropyB;\n #endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\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}\n#ifdef USE_ANISOTROPY\n float V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n float gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n float gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n float v = 0.5 / ( gv + gl );\n return saturate(v);\n }\n float D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n float a2 = alphaT * alphaB;\n highp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n highp float v2 = dot( v, v );\n float w2 = a2 / v2;\n return RECIPROCAL_PI * a2 * pow2 ( w2 );\n }\n#endif\n#ifdef USE_CLEARCOAT\n vec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n vec3 f0 = material.clearcoatF0;\n float f90 = material.clearcoatF90;\n float roughness = material.clearcoatRoughness;\n float alpha = pow2( roughness );\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\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 }\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n vec3 f0 = material.specularColor;\n float f90 = material.specularF90;\n float roughness = material.roughness;\n float alpha = pow2( roughness );\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\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 #ifdef USE_IRIDESCENCE\n F = mix( F, material.iridescenceFresnel, material.iridescence );\n #endif\n #ifdef USE_ANISOTROPY\n float dotTL = dot( material.anisotropyT, lightDir );\n float dotTV = dot( material.anisotropyT, viewDir );\n float dotTH = dot( material.anisotropyT, halfDir );\n float dotBL = dot( material.anisotropyB, lightDir );\n float dotBV = dot( material.anisotropyB, viewDir );\n float dotBH = dot( material.anisotropyB, halfDir );\n float V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n float D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n #else\n float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n float D = D_GGX( alpha, dotNH );\n #endif\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}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n float alpha = pow2( roughness );\n float invAlpha = 1.0 / alpha;\n float cos2h = dotNH * dotNH;\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 dotNV, float dotNL ) {\n return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n vec3 halfDir = normalize( lightDir + viewDir );\n float dotNL = saturate( dot( normal, lightDir ) );\n float dotNV = saturate( dot( normal, viewDir ) );\n float dotNH = saturate( dot( normal, halfDir ) );\n float D = D_Charlie( sheenRoughness, dotNH );\n float V = V_Neubelt( dotNV, dotNL );\n return sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n float dotNV = saturate( dot( normal, viewDir ) );\n float r2 = roughness * roughness;\n float a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n float b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n float DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n return saturate( DG * RECIPROCAL_PI );\n}\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}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\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#endif\n vec2 fab = DFGApprox( normal, viewDir, roughness );\n #ifdef USE_IRIDESCENCE\n vec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n #else\n vec3 Fr = specularColor;\n #endif\n vec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n float Ess = fab.x + fab.y;\n float Ems = 1.0 - Ess;\n vec3 Favg = Fr + ( 1.0 - Fr ) * 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 vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n vec3 normal = geometryNormal;\n vec3 viewDir = geometryViewDir;\n vec3 position = geometryPosition;\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 vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n #ifdef USE_CLEARCOAT\n float dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n vec3 ccIrradiance = dotNLcc * directLight.color;\n clearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n #endif\n #ifdef USE_SHEEN\n sheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n #endif\n reflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material );\n reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, 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 vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n #ifdef USE_CLEARCOAT\n clearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n #endif\n #ifdef USE_SHEEN\n sheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n #endif\n vec3 singleScattering = vec3( 0.0 );\n vec3 multiScattering = vec3( 0.0 );\n vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n #ifdef USE_IRIDESCENCE\n computeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n #else\n computeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n #endif\n vec3 totalScattering = singleScattering + multiScattering;\n vec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\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 = "\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n geometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n float dotNVi = saturate( dot( normal, geometryViewDir ) );\n if ( material.iridescenceThickness == 0.0 ) {\n material.iridescence = 0.0;\n } else {\n material.iridescence = saturate( material.iridescence );\n }\n if ( material.iridescence > 0.0 ) {\n material.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n material.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n }\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, geometryPosition, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n pointLightShadow = pointLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n }\n #pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n SpotLight spotLight;\n vec4 spotColor;\n vec3 spotLightCoord;\n bool inSpotLightMap;\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, geometryPosition, directLight );\n #if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n #define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n #elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n #define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n #else\n #define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n #endif\n #if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n spotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n inSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n spotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n directLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n #endif\n #undef SPOT_LIGHT_MAP_INDEX\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n spotLightShadow = spotLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, 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, directLight );\n #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n directionalLightShadow = directionalLightShadows[ i ];\n directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, 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, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, 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 #if defined( USE_LIGHT_PROBES )\n irradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n #endif\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 ], geometryNormal );\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, vLightMapUv );\n vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n irradiance += lightMapIrradiance;\n #endif\n #if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n iblIrradiance += getIBLIrradiance( geometryNormal );\n #endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n #ifdef USE_ANISOTROPY\n radiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n #else\n radiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n #endif\n #ifdef USE_CLEARCOAT\n clearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n #endif\n#endif"; var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n RE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif"; var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF )\n gl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF )\n uniform float logDepthBufFC;\n varying float vFragDepth;\n varying float vIsPerspective;\n#endif"; var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n varying float vFragDepth;\n varying float vIsPerspective;\n#endif"; var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n vFragDepth = 1.0 + gl_Position.w;\n vIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n#endif"; var map_fragment = "#ifdef USE_MAP\n vec4 sampledDiffuseColor = texture2D( map, vMapUv );\n #ifdef DECODE_VIDEO_TEXTURE\n sampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor );\n #endif\n diffuseColor *= sampledDiffuseColor;\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 #if defined( USE_POINTS_UV )\n vec2 uv = vUv;\n #else\n vec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n #endif\n#endif\n#ifdef USE_MAP\n diffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n diffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif"; var map_particle_pars_fragment = "#if defined( USE_POINTS_UV )\n varying vec2 vUv;\n#else\n #if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n uniform mat3 uvTransform;\n #endif\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, vMetalnessMapUv );\n metalnessFactor *= texelMetalness.b;\n#endif"; var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n uniform sampler2D metalnessMap;\n#endif"; var morphinstance_vertex = "#ifdef USE_INSTANCING_MORPH\n float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n float morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r;\n for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n morphTargetInfluences[i] = texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r;\n }\n#endif"; var morphcolor_vertex = "#if defined( USE_MORPHCOLORS )\n vColor *= morphTargetBaseInfluence;\n for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n #if defined( USE_COLOR_ALPHA )\n if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n #elif defined( USE_COLOR )\n if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n #endif\n }\n#endif"; var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n objectNormal *= morphTargetBaseInfluence;\n for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n if ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n }\n#endif"; var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n #ifndef USE_INSTANCING_MORPH\n uniform float morphTargetBaseInfluence;\n uniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n #endif\n uniform sampler2DArray morphTargetsTexture;\n uniform ivec2 morphTargetsTextureSize;\n vec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n int texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n int y = texelIndex / morphTargetsTextureSize.x;\n int x = texelIndex - y * morphTargetsTextureSize.x;\n ivec3 morphUV = ivec3( x, y, morphTargetIndex );\n return texelFetch( morphTargetsTexture, morphUV, 0 );\n }\n#endif"; var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n transformed *= morphTargetBaseInfluence;\n for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n if ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n }\n#endif"; var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n#else\n vec3 normal = normalize( vNormal );\n #ifdef DOUBLE_SIDED\n normal *= faceDirection;\n #endif\n#endif\n#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )\n #ifdef USE_TANGENT\n mat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n #else\n mat3 tbn = getTangentFrame( - vViewPosition, normal,\n #if defined( USE_NORMALMAP )\n vNormalMapUv\n #elif defined( USE_CLEARCOAT_NORMALMAP )\n vClearcoatNormalMapUv\n #else\n vUv\n #endif\n );\n #endif\n #if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n tbn[0] *= faceDirection;\n tbn[1] *= faceDirection;\n #endif\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n #ifdef USE_TANGENT\n mat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n #else\n mat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n #endif\n #if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n tbn2[0] *= faceDirection;\n tbn2[1] *= faceDirection;\n #endif\n#endif\nvec3 nonPerturbedNormal = normal;"; var normal_fragment_maps = "#ifdef USE_NORMALMAP_OBJECTSPACE\n normal = texture2D( normalMap, vNormalMapUv ).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( USE_NORMALMAP_TANGENTSPACE )\n vec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n mapN.xy *= normalScale;\n normal = normalize( tbn * mapN );\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 USE_NORMALMAP_OBJECTSPACE\n uniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) )\n mat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) {\n vec3 q0 = dFdx( eye_pos.xyz );\n vec3 q1 = dFdy( eye_pos.xyz );\n vec2 st0 = dFdx( uv.st );\n vec2 st1 = dFdy( uv.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 : inversesqrt( det );\n return mat3( T * scale, B * scale, N );\n }\n#endif"; var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n vec3 clearcoatNormal = nonPerturbedNormal;\n#endif"; var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n vec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0;\n clearcoatMapN.xy *= clearcoatNormalScale;\n clearcoatNormal = normalize( tbn2 * clearcoatMapN );\n#endif"; var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n uniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n uniform sampler2D clearcoatNormalMap;\n uniform vec2 clearcoatNormalScale;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n uniform sampler2D clearcoatRoughnessMap;\n#endif"; var iridescence_pars_fragment = "#ifdef USE_IRIDESCENCEMAP\n uniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n uniform sampler2D iridescenceThicknessMap;\n#endif"; var opaque_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha;\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.;const float ShiftRight8 = 1. / 256.;\nconst float Inv255 = 1. / 255.;\nconst vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );\nconst vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g );\nconst vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b );\nconst vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a );\nvec4 packDepthToRGBA( const in float v ) {\n if( v <= 0.0 )\n return vec4( 0., 0., 0., 0. );\n if( v >= 1.0 )\n return vec4( 1., 1., 1., 1. );\n float vuf;\n float af = modf( v * PackFactors.a, vuf );\n float bf = modf( vuf * ShiftRight8, vuf );\n float gf = modf( vuf * ShiftRight8, vuf );\n return vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af );\n}\nvec3 packDepthToRGB( const in float v ) {\n if( v <= 0.0 )\n return vec3( 0., 0., 0. );\n if( v >= 1.0 )\n return vec3( 1., 1., 1. );\n float vuf;\n float bf = modf( v * PackFactors.b, vuf );\n float gf = modf( vuf * ShiftRight8, vuf );\n return vec3( vuf * Inv255, gf * PackUpscale, bf );\n}\nvec2 packDepthToRG( const in float v ) {\n if( v <= 0.0 )\n return vec2( 0., 0. );\n if( v >= 1.0 )\n return vec2( 1., 1. );\n float vuf;\n float gf = modf( v * 256., vuf );\n return vec2( vuf * Inv255, gf );\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n return dot( v, UnpackFactors4 );\n}\nfloat unpackRGBToDepth( const in vec3 v ) {\n return dot( v, UnpackFactors3 );\n}\nfloat unpackRGToDepth( const in vec2 v ) {\n return v.r * UnpackFactors2.r + v.g * UnpackFactors2.g;\n}\nvec4 pack2HalfToRGBA( const in 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( const in 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 depth, const in float near, const in float far ) {\n return depth * ( 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 depth, const in float near, const in float far ) {\n return ( near * far ) / ( ( far - near ) * depth - 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_BATCHING\n mvPosition = batchingMatrix * mvPosition;\n#endif\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, vRoughnessMapUv );\n roughnessFactor *= texelRoughness.g;\n#endif"; var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n uniform sampler2D roughnessMap;\n#endif"; var shadowmap_pars_fragment = "#if NUM_SPOT_LIGHT_COORDS > 0\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#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 shadowIntensity;\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 struct SpotLightShadow {\n float shadowIntensity;\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 shadowIntensity;\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 shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n float shadow = 1.0;\n shadowCoord.xyz /= shadowCoord.w;\n shadowCoord.z += shadowBias;\n bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n bool frustumTest = inFrustum && shadowCoord.z <= 1.0;\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 mix( 1.0, shadow, shadowIntensity );\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 shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n float shadow = 1.0;\n vec3 lightToPosition = shadowCoord.xyz;\n \n float lightToPositionLength = length( lightToPosition );\n if ( lightToPositionLength - shadowCameraFar <= 0.0 && lightToPositionLength - shadowCameraNear >= 0.0 ) {\n float dp = ( lightToPositionLength - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); dp += shadowBias;\n vec3 bd3D = normalize( lightToPosition );\n vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\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 shadow = (\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 shadow = texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n #endif\n }\n return mix( 1.0, shadow, shadowIntensity );\n }\n#endif"; var shadowmap_pars_vertex = "#if NUM_SPOT_LIGHT_COORDS > 0\n uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#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 shadowIntensity;\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 struct SpotLightShadow {\n float shadowIntensity;\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 shadowIntensity;\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 = "#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n vec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\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_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\n#if NUM_SPOT_LIGHT_COORDS > 0\n #pragma unroll_loop_start\n for ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n shadowWorldPosition = worldPosition;\n #if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n shadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n #endif\n vSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n }\n #pragma unroll_loop_end\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.shadowIntensity, 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.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ 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.shadowIntensity, 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 uniform highp sampler2D boneTexture;\n mat4 getBoneMatrix( const in float i ) {\n int size = textureSize( boneTexture, 0 ).x;\n int j = int( i ) * 4;\n int x = j % size;\n int y = j / size;\n vec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\n vec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\n vec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\n vec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\n return mat4( v1, v2, v3, v4 );\n }\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, vSpecularMapUv );\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 saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n return saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 CineonToneMapping( 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}\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n vec3( 1.6605, - 0.1246, - 0.0182 ),\n vec3( - 0.5876, 1.1329, - 0.1006 ),\n vec3( - 0.0728, - 0.0083, 1.1187 )\n);\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n vec3( 0.6274, 0.0691, 0.0164 ),\n vec3( 0.3293, 0.9195, 0.0880 ),\n vec3( 0.0433, 0.0113, 0.8956 )\n);\nvec3 agxDefaultContrastApprox( vec3 x ) {\n vec3 x2 = x * x;\n vec3 x4 = x2 * x2;\n return + 15.5 * x4 * x2\n - 40.14 * x4 * x\n + 31.96 * x4\n - 6.868 * x2 * x\n + 0.4298 * x2\n + 0.1191 * x\n - 0.00232;\n}\nvec3 AgXToneMapping( vec3 color ) {\n const mat3 AgXInsetMatrix = mat3(\n vec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n vec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n vec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )\n );\n const mat3 AgXOutsetMatrix = mat3(\n vec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),\n vec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),\n vec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )\n );\n const float AgxMinEv = - 12.47393; const float AgxMaxEv = 4.026069;\n color *= toneMappingExposure;\n color = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n color = AgXInsetMatrix * color;\n color = max( color, 1e-10 ); color = log2( color );\n color = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );\n color = clamp( color, 0.0, 1.0 );\n color = agxDefaultContrastApprox( color );\n color = AgXOutsetMatrix * color;\n color = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );\n color = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n color = clamp( color, 0.0, 1.0 );\n return color;\n}\nvec3 NeutralToneMapping( vec3 color ) {\n const float StartCompression = 0.8 - 0.04;\n const float Desaturation = 0.15;\n color *= toneMappingExposure;\n float x = min( color.r, min( color.g, color.b ) );\n float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n color -= offset;\n float peak = max( color.r, max( color.g, color.b ) );\n if ( peak < StartCompression ) return color;\n float d = 1. - StartCompression;\n float newPeak = 1. - d * d / ( peak + d - StartCompression );\n color *= newPeak / peak;\n float g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );\n return mix( color, vec3( newPeak ), g );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }"; var transmission_fragment = "#ifdef USE_TRANSMISSION\n material.transmission = transmission;\n material.transmissionAlpha = 1.0;\n material.thickness = thickness;\n material.attenuationDistance = attenuationDistance;\n material.attenuationColor = attenuationColor;\n #ifdef USE_TRANSMISSIONMAP\n material.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n #endif\n #ifdef USE_THICKNESSMAP\n material.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n #endif\n vec3 pos = vWorldPosition;\n vec3 v = normalize( cameraPosition - pos );\n vec3 n = inverseTransformDirection( normal, viewMatrix );\n vec4 transmitted = getIBLVolumeRefraction(\n n, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n pos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,\n material.attenuationColor, material.attenuationDistance );\n material.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n totalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif"; var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n uniform float transmission;\n uniform float thickness;\n uniform float attenuationDistance;\n uniform vec3 attenuationColor;\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 float w0( float a ) {\n return ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 );\n }\n float w1( float a ) {\n return ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 );\n }\n float w2( float a ){\n return ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 );\n }\n float w3( float a ) {\n return ( 1.0 / 6.0 ) * ( a * a * a );\n }\n float g0( float a ) {\n return w0( a ) + w1( a );\n }\n float g1( float a ) {\n return w2( a ) + w3( a );\n }\n float h0( float a ) {\n return - 1.0 + w1( a ) / ( w0( a ) + w1( a ) );\n }\n float h1( float a ) {\n return 1.0 + w3( a ) / ( w2( a ) + w3( a ) );\n }\n vec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) {\n uv = uv * texelSize.zw + 0.5;\n vec2 iuv = floor( uv );\n vec2 fuv = fract( uv );\n float g0x = g0( fuv.x );\n float g1x = g1( fuv.x );\n float h0x = h0( fuv.x );\n float h1x = h1( fuv.x );\n float h0y = h0( fuv.y );\n float h1y = h1( fuv.y );\n vec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n vec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n vec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n vec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n return g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) +\n g1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) );\n }\n vec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) {\n vec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) );\n vec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) );\n vec2 fLodSizeInv = 1.0 / fLodSize;\n vec2 cLodSizeInv = 1.0 / cLodSize;\n vec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) );\n vec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) );\n return mix( fSample, cSample, fract( lod ) );\n }\n vec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in 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( const in float roughness, const in float ior ) {\n return roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n }\n vec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n float lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n return textureBicubic( transmissionSamplerMap, fragCoord.xy, lod );\n }\n vec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n if ( isinf( attenuationDistance ) ) {\n return vec3( 1.0 );\n } else {\n vec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n vec3 transmittance = exp( - attenuationCoefficient * transmissionDistance ); return transmittance;\n }\n }\n vec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n const in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n const in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,\n const in vec3 attenuationColor, const in float attenuationDistance ) {\n vec4 transmittedLight;\n vec3 transmittance;\n #ifdef USE_DISPERSION\n float halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;\n vec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );\n for ( int i = 0; i < 3; i ++ ) {\n vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );\n vec3 refractedRayExit = position + transmissionRay;\n \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 \n vec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );\n transmittedLight[ i ] = transmissionSample[ i ];\n transmittedLight.a += transmissionSample.a;\n transmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];\n }\n transmittedLight.a /= 3.0;\n \n #else\n \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 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n transmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );\n \n #endif\n vec3 attenuatedColor = transmittance * transmittedLight.rgb;\n vec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n float transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0;\n return vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor );\n }\n#endif"; var uv_pars_fragment = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n varying vec2 vUv;\n#endif\n#ifdef USE_MAP\n varying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n varying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n varying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n varying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n varying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n varying vec2 vNormalMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n varying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n varying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n varying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n varying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n varying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n varying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n varying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n varying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n varying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n varying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n varying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n varying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n varying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n varying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n uniform mat3 transmissionMapTransform;\n varying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n uniform mat3 thicknessMapTransform;\n varying vec2 vThicknessMapUv;\n#endif"; var uv_pars_vertex = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n varying vec2 vUv;\n#endif\n#ifdef USE_MAP\n uniform mat3 mapTransform;\n varying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n uniform mat3 alphaMapTransform;\n varying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n uniform mat3 lightMapTransform;\n varying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n uniform mat3 aoMapTransform;\n varying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n uniform mat3 bumpMapTransform;\n varying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n uniform mat3 normalMapTransform;\n varying vec2 vNormalMapUv;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n uniform mat3 displacementMapTransform;\n varying vec2 vDisplacementMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n uniform mat3 emissiveMapTransform;\n varying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n uniform mat3 metalnessMapTransform;\n varying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n uniform mat3 roughnessMapTransform;\n varying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n uniform mat3 anisotropyMapTransform;\n varying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n uniform mat3 clearcoatMapTransform;\n varying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n uniform mat3 clearcoatNormalMapTransform;\n varying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n uniform mat3 clearcoatRoughnessMapTransform;\n varying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n uniform mat3 sheenColorMapTransform;\n varying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n uniform mat3 sheenRoughnessMapTransform;\n varying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n uniform mat3 iridescenceMapTransform;\n varying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n uniform mat3 iridescenceThicknessMapTransform;\n varying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n uniform mat3 specularMapTransform;\n varying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n uniform mat3 specularColorMapTransform;\n varying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n uniform mat3 specularIntensityMapTransform;\n varying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n uniform mat3 transmissionMapTransform;\n varying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n uniform mat3 thicknessMapTransform;\n varying vec2 vThicknessMapUv;\n#endif"; var uv_vertex = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n vUv = vec3( uv, 1 ).xy;\n#endif\n#ifdef USE_MAP\n vMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ALPHAMAP\n vAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_LIGHTMAP\n vLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_AOMAP\n vAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_BUMPMAP\n vBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_NORMALMAP\n vNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n vDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_EMISSIVEMAP\n vEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_METALNESSMAP\n vMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ROUGHNESSMAP\n vRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ANISOTROPYMAP\n vAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOATMAP\n vClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n vClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n vClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n vIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n vIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n vSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n vSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULARMAP\n vSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n vSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n vSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n vTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_THICKNESSMAP\n vThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy;\n#endif"; var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\n vec4 worldPosition = vec4( transformed, 1.0 );\n #ifdef USE_BATCHING\n worldPosition = batchingMatrix * worldPosition;\n #endif\n #ifdef USE_INSTANCING\n worldPosition = instanceMatrix * worldPosition;\n #endif\n worldPosition = modelMatrix * worldPosition;\n#endif"; var vertex$h = "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 fragment$h = "uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n vec4 texColor = texture2D( t2D, vUv );\n #ifdef DECODE_VIDEO_TEXTURE\n texColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n #endif\n texColor.rgb *= backgroundIntensity;\n gl_FragColor = texColor;\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}"; var vertex$g = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n vWorldDirection = transformDirection( position, modelMatrix );\n #include <begin_vertex>\n #include <project_vertex>\n gl_Position.z = gl_Position.w;\n}"; var fragment$g = "#ifdef ENVMAP_TYPE_CUBE\n uniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n uniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nuniform mat3 backgroundRotation;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n #ifdef ENVMAP_TYPE_CUBE\n vec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n #elif defined( ENVMAP_TYPE_CUBE_UV )\n vec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );\n #else\n vec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n #endif\n texColor.rgb *= backgroundIntensity;\n gl_FragColor = texColor;\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}"; var vertex$f = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n vWorldDirection = transformDirection( position, modelMatrix );\n #include <begin_vertex>\n #include <project_vertex>\n gl_Position.z = gl_Position.w;\n}"; var fragment$f = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n vec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n gl_FragColor = texColor;\n gl_FragColor.a *= opacity;\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}"; var vertex$e = "#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n #include <uv_vertex>\n #include <batching_vertex>\n #include <skinbase_vertex>\n #include <morphinstance_vertex>\n #ifdef USE_DISPLACEMENTMAP\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinnormal_vertex>\n #endif\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vHighPrecisionZW = gl_Position.zw;\n}"; var fragment$e = "#if DEPTH_PACKING == 3200\n uniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n vec4 diffuseColor = vec4( 1.0 );\n #include <clipping_planes_fragment>\n #if DEPTH_PACKING == 3200\n diffuseColor.a = opacity;\n #endif\n #include <map_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <logdepthbuf_fragment>\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 #elif DEPTH_PACKING == 3202\n gl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 );\n #elif DEPTH_PACKING == 3203\n gl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 );\n #endif\n}"; var vertex$d = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <batching_vertex>\n #include <skinbase_vertex>\n #include <morphinstance_vertex>\n #ifdef USE_DISPLACEMENTMAP\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinnormal_vertex>\n #endif\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <worldpos_vertex>\n #include <clipping_planes_vertex>\n vWorldPosition = worldPosition.xyz;\n}"; var fragment$d = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n vec4 diffuseColor = vec4( 1.0 );\n #include <clipping_planes_fragment>\n #include <map_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n float dist = length( vWorldPosition - referencePosition );\n dist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n dist = saturate( dist );\n gl_FragColor = packDepthToRGBA( dist );\n}"; var vertex$c = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n vWorldDirection = transformDirection( position, modelMatrix );\n #include <begin_vertex>\n #include <project_vertex>\n}"; var fragment$c = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n vec3 direction = normalize( vWorldDirection );\n vec2 sampleUV = equirectUv( direction );\n gl_FragColor = texture2D( tEquirect, sampleUV );\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n}"; var vertex$b = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n vLineDistance = scale * lineDistance;\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <fog_vertex>\n}"; var fragment$b = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n if ( mod( vLineDistance, totalSize ) > dashSize ) {\n discard;\n }\n vec3 outgoingLight = vec3( 0.0 );\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n outgoingLight = diffuseColor.rgb;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n}"; var vertex$a = "#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #endif\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <fog_vertex>\n}"; var fragment$a = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n varying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\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, vLightMapUv );\n reflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\n #else\n reflectedLight.indirectDiffuse += vec3( 1.0 );\n #endif\n #include <aomap_fragment>\n reflectedLight.indirectDiffuse *= diffuseColor.rgb;\n vec3 outgoingLight = reflectedLight.indirectDiffuse;\n #include <envmap_fragment>\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; var vertex$9 = "#define LAMBERT\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n}"; var fragment$9 = "#define LAMBERT\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_lambert_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_lambert_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n #include <envmap_fragment>\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; var vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <fog_vertex>\n vViewPosition = - mvPosition.xyz;\n}"; var fragment$8 = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <normal_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\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 #else\n vec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n #endif\n vec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; var vertex$7 = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n varying vec3 vViewPosition;\n#endif\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphinstance_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n vViewPosition = - mvPosition.xyz;\n#endif\n}"; var fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n varying vec3 vViewPosition;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <normal_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity );\n #include <clipping_planes_fragment>\n #include <logdepthbuf_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n gl_FragColor = vec4( packNormalToRGB( normal ), diffuseColor.a );\n #ifdef OPAQUE\n gl_FragColor.a = 1.0;\n #endif\n}"; var vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphinstance_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n}"; var fragment$6 = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_phong_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n #include <envmap_fragment>\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; var vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n varying vec3 vWorldPosition;\n#endif\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n#ifdef USE_TRANSMISSION\n vWorldPosition = worldPosition.xyz;\n#endif\n}"; var fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n #define IOR\n #define USE_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 USE_SPECULAR\n uniform float specularIntensity;\n uniform vec3 specularColor;\n #ifdef USE_SPECULAR_COLORMAP\n uniform sampler2D specularColorMap;\n #endif\n #ifdef USE_SPECULAR_INTENSITYMAP\n uniform sampler2D specularIntensityMap;\n #endif\n#endif\n#ifdef USE_CLEARCOAT\n uniform float clearcoat;\n uniform float clearcoatRoughness;\n#endif\n#ifdef USE_DISPERSION\n uniform float dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n uniform float iridescence;\n uniform float iridescenceIOR;\n uniform float iridescenceThicknessMinimum;\n uniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n uniform vec3 sheenColor;\n uniform float sheenRoughness;\n #ifdef USE_SHEEN_COLORMAP\n uniform sampler2D sheenColorMap;\n #endif\n #ifdef USE_SHEEN_ROUGHNESSMAP\n uniform sampler2D sheenRoughnessMap;\n #endif\n#endif\n#ifdef USE_ANISOTROPY\n uniform vec2 anisotropyVector;\n #ifdef USE_ANISOTROPYMAP\n uniform sampler2D anisotropyMap;\n #endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <iridescence_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_physical_pars_fragment>\n#include <transmission_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <iridescence_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <roughnessmap_fragment>\n #include <metalnessmap_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <clearcoat_normal_fragment_begin>\n #include <clearcoat_normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_physical_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n vec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n #include <transmission_fragment>\n vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n #ifdef USE_SHEEN\n float sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n outgoingLight = outgoingLight * sheenEnergyComp + sheenSpecularDirect + sheenSpecularIndirect;\n #endif\n #ifdef USE_CLEARCOAT\n float dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n vec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n outgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n #endif\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; var vertex$4 = "#define TOON\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <normal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <displacementmap_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n vViewPosition = - mvPosition.xyz;\n #include <worldpos_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n}"; var fragment$4 = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_toon_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <normal_fragment_begin>\n #include <normal_fragment_maps>\n #include <emissivemap_fragment>\n #include <lights_toon_fragment>\n #include <lights_fragment_begin>\n #include <lights_fragment_maps>\n #include <lights_fragment_end>\n #include <aomap_fragment>\n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n #include <dithering_fragment>\n}"; var vertex$3 = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n#ifdef USE_POINTS_UV\n varying vec2 vUv;\n uniform mat3 uvTransform;\n#endif\nvoid main() {\n #ifdef USE_POINTS_UV\n vUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n #endif\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <project_vertex>\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 <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <worldpos_vertex>\n #include <fog_vertex>\n}"; var fragment$3 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n vec3 outgoingLight = vec3( 0.0 );\n #include <logdepthbuf_fragment>\n #include <map_particle_fragment>\n #include <color_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n outgoingLight = diffuseColor.rgb;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n #include <premultiplied_alpha_fragment>\n}"; var vertex$2 = "#include <common>\n#include <batching_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n #include <batching_vertex>\n #include <beginnormal_vertex>\n #include <morphinstance_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <worldpos_vertex>\n #include <shadowmap_vertex>\n #include <fog_vertex>\n}"; var fragment$2 = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <logdepthbuf_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n #include <logdepthbuf_fragment>\n gl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n}"; var vertex$1 = "uniform float rotation;\nuniform vec2 center;\n#include <common>\n#include <uv_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n #include <uv_vertex>\n vec4 mvPosition = modelViewMatrix[ 3 ];\n vec2 scale = vec2( length( modelMatrix[ 0 ].xyz ), length( modelMatrix[ 1 ].xyz ) );\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 <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n #include <fog_vertex>\n}"; var fragment$1 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include <clipping_planes_fragment>\n vec3 outgoingLight = vec3( 0.0 );\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n outgoingLight = diffuseColor.rgb;\n #include <opaque_fragment>\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n}"; var ShaderChunk = { alphahash_fragment, alphahash_pars_fragment, alphamap_fragment, alphamap_pars_fragment, alphatest_fragment, alphatest_pars_fragment, aomap_fragment, aomap_pars_fragment, batching_pars_vertex, batching_vertex, begin_vertex, beginnormal_vertex, bsdfs, iridescence_fragment, 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, colorspace_fragment, colorspace_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_pars_fragment, lights_lambert_fragment, lights_lambert_pars_fragment, 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, morphinstance_vertex, morphcolor_vertex, 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, iridescence_pars_fragment, opaque_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, worldpos_vertex, background_vert: vertex$h, background_frag: fragment$h, backgroundCube_vert: vertex$g, backgroundCube_frag: fragment$g, cube_vert: vertex$f, cube_frag: fragment$f, depth_vert: vertex$e, depth_frag: fragment$e, distanceRGBA_vert: vertex$d, distanceRGBA_frag: fragment$d, equirect_vert: vertex$c, equirect_frag: fragment$c, linedashed_vert: vertex$b, linedashed_frag: fragment$b, meshbasic_vert: vertex$a, meshbasic_frag: fragment$a, meshlambert_vert: vertex$9, meshlambert_frag: fragment$9, meshmatcap_vert: vertex$8, meshmatcap_frag: fragment$8, meshnormal_vert: vertex$7, meshnormal_frag: fragment$7, meshphong_vert: vertex$6, meshphong_frag: fragment$6, meshphysical_vert: vertex$5, meshphysical_frag: fragment$5, meshtoon_vert: vertex$4, meshtoon_frag: fragment$4, points_vert: vertex$3, points_frag: fragment$3, shadow_vert: vertex$2, shadow_frag: fragment$2, sprite_vert: vertex$1, sprite_frag: fragment$1 }; var UniformsLib = { common: { diffuse: { value: /* @__PURE__ */ new Color(16777215) }, opacity: { value: 1 }, map: { value: null }, mapTransform: { value: /* @__PURE__ */ new Matrix3() }, alphaMap: { value: null }, alphaMapTransform: { value: /* @__PURE__ */ new Matrix3() }, alphaTest: { value: 0 } }, specularmap: { specularMap: { value: null }, specularMapTransform: { value: /* @__PURE__ */ new Matrix3() } }, envmap: { envMap: { value: null }, envMapRotation: { value: /* @__PURE__ */ new Matrix3() }, flipEnvMap: { value: -1 }, reflectivity: { value: 1 }, // basic, lambert, phong ior: { value: 1.5 }, // physical refractionRatio: { value: 0.98 } // basic, lambert, phong }, aomap: { aoMap: { value: null }, aoMapIntensity: { value: 1 }, aoMapTransform: { value: /* @__PURE__ */ new Matrix3() } }, lightmap: { lightMap: { value: null }, lightMapIntensity: { value: 1 }, lightMapTransform: { value: /* @__PURE__ */ new Matrix3() } }, bumpmap: { bumpMap: { value: null }, bumpMapTransform: { value: /* @__PURE__ */ new Matrix3() }, bumpScale: { value: 1 } }, normalmap: { normalMap: { value: null }, normalMapTransform: { value: /* @__PURE__ */ new Matrix3() }, normalScale: { value: /* @__PURE__ */ new Vector2(1, 1) } }, displacementmap: { displacementMap: { value: null }, displacementMapTransform: { value: /* @__PURE__ */ new Matrix3() }, displacementScale: { value: 1 }, displacementBias: { value: 0 } }, emissivemap: { emissiveMap: { value: null }, emissiveMapTransform: { value: /* @__PURE__ */ new Matrix3() } }, metalnessmap: { metalnessMap: { value: null }, metalnessMapTransform: { value: /* @__PURE__ */ new Matrix3() } }, roughnessmap: { roughnessMap: { value: null }, roughnessMapTransform: { value: /* @__PURE__ */ new Matrix3() } }, gradientmap: { gradientMap: { value: null } }, fog: { fogDensity: { value: 25e-5 }, fogNear: { value: 1 }, fogFar: { value: 2e3 }, fogColor: { value: /* @__PURE__ */ new Color(16777215) } }, lights: { ambientLightColor: { value: [] }, lightProbe: { value: [] }, directionalLights: { value: [], properties: { direction: {}, color: {} } }, directionalLightShadows: { value: [], properties: { shadowIntensity: 1, shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {} } }, directionalShadowMap: { value: [] }, directionalShadowMatrix: { value: [] }, spotLights: { value: [], properties: { color: {}, position: {}, direction: {}, distance: {}, coneCos: {}, penumbraCos: {}, decay: {} } }, spotLightShadows: { value: [], properties: { shadowIntensity: 1, shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {} } }, spotLightMap: { value: [] }, spotShadowMap: { value: [] }, spotLightMatrix: { value: [] }, pointLights: { value: [], properties: { color: {}, position: {}, decay: {}, distance: {} } }, pointLightShadows: { value: [], properties: { shadowIntensity: 1, shadowBias: {}, shadowNormalBias: {}, shadowRadius: {}, shadowMapSize: {}, shadowCameraNear: {}, shadowCameraFar: {} } }, pointShadowMap: { value: [] }, pointShadowMatrix: { value: [] }, hemisphereLights: { value: [], properties: { direction: {}, skyColor: {}, groundColor: {} } }, // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src rectAreaLights: { value: [], properties: { color: {}, position: {}, width: {}, height: {} } }, ltc_1: { value: null }, ltc_2: { value: null } }, points: { diffuse: { value: /* @__PURE__ */ new Color(16777215) }, opacity: { value: 1 }, size: { value: 1 }, scale: { value: 1 }, map: { value: null }, alphaMap: { value: null }, alphaMapTransform: { value: /* @__PURE__ */ new Matrix3() }, alphaTest: { value: 0 }, uvTransform: { value: /* @__PURE__ */ new Matrix3() } }, sprite: { diffuse: { value: /* @__PURE__ */ new Color(16777215) }, opacity: { value: 1 }, center: { value: /* @__PURE__ */ new Vector2(0.5, 0.5) }, rotation: { value: 0 }, map: { value: null }, mapTransform: { value: /* @__PURE__ */ new Matrix3() }, alphaMap: { value: null }, alphaMapTransform: { value: /* @__PURE__ */ new Matrix3() }, alphaTest: { value: 0 } } }; var ShaderLib = { basic: { uniforms: /* @__PURE__ */ mergeUniforms([ UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.fog ]), vertexShader: ShaderChunk.meshbasic_vert, fragmentShader: ShaderChunk.meshbasic_frag }, lambert: { uniforms: /* @__PURE__ */ 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: /* @__PURE__ */ new Color(0) } } ]), vertexShader: ShaderChunk.meshlambert_vert, fragmentShader: ShaderChunk.meshlambert_frag }, phong: { uniforms: /* @__PURE__ */ 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: /* @__PURE__ */ new Color(0) }, specular: { value: /* @__PURE__ */ new Color(1118481) }, shininess: { value: 30 } } ]), vertexShader: ShaderChunk.meshphong_vert, fragmentShader: ShaderChunk.meshphong_frag }, standard: { uniforms: /* @__PURE__ */ 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: /* @__PURE__ */ new Color(0) }, roughness: { value: 1 }, metalness: { value: 0 }, envMapIntensity: { value: 1 } } ]), vertexShader: ShaderChunk.meshphysical_vert, fragmentShader: ShaderChunk.meshphysical_frag }, toon: { uniforms: /* @__PURE__ */ mergeUniforms([ UniformsLib.common, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.gradientmap, UniformsLib.fog, UniformsLib.lights, { emissive: { value: /* @__PURE__ */ new Color(0) } } ]), vertexShader: ShaderChunk.meshtoon_vert, fragmentShader: ShaderChunk.meshtoon_frag }, matcap: { uniforms: /* @__PURE__ */ mergeUniforms([ UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, { matcap: { value: null } } ]), vertexShader: ShaderChunk.meshmatcap_vert, fragmentShader: ShaderChunk.meshmatcap_frag }, points: { uniforms: /* @__PURE__ */ mergeUniforms([ UniformsLib.points, UniformsLib.fog ]), vertexShader: ShaderChunk.points_vert, fragmentShader: ShaderChunk.points_frag }, dashed: { uniforms: /* @__PURE__ */ mergeUniforms([ UniformsLib.common, UniformsLib.fog, { scale: { value: 1 }, dashSize: { value: 1 }, totalSize: { value: 2 } } ]), vertexShader: ShaderChunk.linedashed_vert, fragmentShader: ShaderChunk.linedashed_frag }, depth: { uniforms: /* @__PURE__ */ mergeUniforms([ UniformsLib.common, UniformsLib.displacementmap ]), vertexShader: ShaderChunk.depth_vert, fragmentShader: ShaderChunk.depth_frag }, normal: { uniforms: /* @__PURE__ */ mergeUniforms([ UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, { opacity: { value: 1 } } ]), vertexShader: ShaderChunk.meshnormal_vert, fragmentShader: ShaderChunk.meshnormal_frag }, sprite: { uniforms: /* @__PURE__ */ mergeUniforms([ UniformsLib.sprite, UniformsLib.fog ]), vertexShader: ShaderChunk.sprite_vert, fragmentShader: ShaderChunk.sprite_frag }, background: { uniforms: { uvTransform: { value: /* @__PURE__ */ new Matrix3() }, t2D: { value: null }, backgroundIntensity: { value: 1 } }, vertexShader: ShaderChunk.background_vert, fragmentShader: ShaderChunk.background_frag }, backgroundCube: { uniforms: { envMap: { value: null }, flipEnvMap: { value: -1 }, backgroundBlurriness: { value: 0 }, backgroundIntensity: { value: 1 }, backgroundRotation: { value: /* @__PURE__ */ new Matrix3() } }, vertexShader: ShaderChunk.backgroundCube_vert, fragmentShader: ShaderChunk.backgroundCube_frag }, cube: { uniforms: { tCube: { value: null }, tFlip: { value: -1 }, 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: /* @__PURE__ */ mergeUniforms([ UniformsLib.common, UniformsLib.displacementmap, { referencePosition: { value: /* @__PURE__ */ new Vector3() }, nearDistance: { value: 1 }, farDistance: { value: 1e3 } } ]), vertexShader: ShaderChunk.distanceRGBA_vert, fragmentShader: ShaderChunk.distanceRGBA_frag }, shadow: { uniforms: /* @__PURE__ */ mergeUniforms([ UniformsLib.lights, UniformsLib.fog, { color: { value: /* @__PURE__ */ new Color(0) }, opacity: { value: 1 } } ]), vertexShader: ShaderChunk.shadow_vert, fragmentShader: ShaderChunk.shadow_frag } }; ShaderLib.physical = { uniforms: /* @__PURE__ */ mergeUniforms([ ShaderLib.standard.uniforms, { clearcoat: { value: 0 }, clearcoatMap: { value: null }, clearcoatMapTransform: { value: /* @__PURE__ */ new Matrix3() }, clearcoatNormalMap: { value: null }, clearcoatNormalMapTransform: { value: /* @__PURE__ */ new Matrix3() }, clearcoatNormalScale: { value: /* @__PURE__ */ new Vector2(1, 1) }, clearcoatRoughness: { value: 0 }, clearcoatRoughnessMap: { value: null }, clearcoatRoughnessMapTransform: { value: /* @__PURE__ */ new Matrix3() }, dispersion: { value: 0 }, iridescence: { value: 0 }, iridescenceMap: { value: null }, iridescenceMapTransform: { value: /* @__PURE__ */ new Matrix3() }, iridescenceIOR: { value: 1.3 }, iridescenceThicknessMinimum: { value: 100 }, iridescenceThicknessMaximum: { value: 400 }, iridescenceThicknessMap: { value: null }, iridescenceThicknessMapTransform: { value: /* @__PURE__ */ new Matrix3() }, sheen: { value: 0 }, sheenColor: { value: /* @__PURE__ */ new Color(0) }, sheenColorMap: { value: null }, sheenColorMapTransform: { value: /* @__PURE__ */ new Matrix3() }, sheenRoughness: { value: 1 }, sheenRoughnessMap: { value: null }, sheenRoughnessMapTransform: { value: /* @__PURE__ */ new Matrix3() }, transmission: { value: 0 }, transmissionMap: { value: null }, transmissionMapTransform: { value: /* @__PURE__ */ new Matrix3() }, transmissionSamplerSize: { value: /* @__PURE__ */ new Vector2() }, transmissionSamplerMap: { value: null }, thickness: { value: 0 }, thicknessMap: { value: null }, thicknessMapTransform: { value: /* @__PURE__ */ new Matrix3() }, attenuationDistance: { value: 0 }, attenuationColor: { value: /* @__PURE__ */ new Color(0) }, specularColor: { value: /* @__PURE__ */ new Color(1, 1, 1) }, specularColorMap: { value: null }, specularColorMapTransform: { value: /* @__PURE__ */ new Matrix3() }, specularIntensity: { value: 1 }, specularIntensityMap: { value: null }, specularIntensityMapTransform: { value: /* @__PURE__ */ new Matrix3() }, anisotropyVector: { value: /* @__PURE__ */ new Vector2() }, anisotropyMap: { value: null }, anisotropyMapTransform: { value: /* @__PURE__ */ new Matrix3() } } ]), vertexShader: ShaderChunk.meshphysical_vert, fragmentShader: ShaderChunk.meshphysical_frag }; var _rgb = { r: 0, b: 0, g: 0 }; var _e1$1 = /* @__PURE__ */ new Euler(); var _m1$1 = /* @__PURE__ */ new Matrix4(); function WebGLBackground(renderer3, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha) { const clearColor = new Color(0); let clearAlpha = alpha === true ? 0 : 1; let planeMesh; let boxMesh; let currentBackground = null; let currentBackgroundVersion = 0; let currentTonemapping = null; function getBackground(scene3) { let background = scene3.isScene === true ? scene3.background : null; if (background && background.isTexture) { const usePMREM = scene3.backgroundBlurriness > 0; background = (usePMREM ? cubeuvmaps : cubemaps).get(background); } return background; } function render(scene3) { let forceClear = false; const background = getBackground(scene3); if (background === null) { setClear(clearColor, clearAlpha); } else if (background && background.isColor) { setClear(background, 1); forceClear = true; } const environmentBlendMode = renderer3.xr.getEnvironmentBlendMode(); if (environmentBlendMode === "additive") { state.buffers.color.setClear(0, 0, 0, 1, premultipliedAlpha); } else if (environmentBlendMode === "alpha-blend") { state.buffers.color.setClear(0, 0, 0, 0, premultipliedAlpha); } if (renderer3.autoClear || forceClear) { state.buffers.depth.setTest(true); state.buffers.depth.setMask(true); state.buffers.color.setMask(true); renderer3.clear(renderer3.autoClearColor, renderer3.autoClearDepth, renderer3.autoClearStencil); } } function addToRenderList(renderList, scene3) { const background = getBackground(scene3); 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.backgroundCube.uniforms), vertexShader: ShaderLib.backgroundCube.vertexShader, fragmentShader: ShaderLib.backgroundCube.fragmentShader, side: BackSide, depthTest: false, depthWrite: false, fog: false }) ); boxMesh.geometry.deleteAttribute("normal"); boxMesh.geometry.deleteAttribute("uv"); boxMesh.onBeforeRender = function(renderer4, scene4, camera3) { this.matrixWorld.copyPosition(camera3.matrixWorld); }; Object.defineProperty(boxMesh.material, "envMap", { get: function() { return this.uniforms.envMap.value; } }); objects.update(boxMesh); } _e1$1.copy(scene3.backgroundRotation); _e1$1.x *= -1; _e1$1.y *= -1; _e1$1.z *= -1; if (background.isCubeTexture && background.isRenderTargetTexture === false) { _e1$1.y *= -1; _e1$1.z *= -1; } boxMesh.material.uniforms.envMap.value = background; boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background.isRenderTargetTexture === false ? -1 : 1; boxMesh.material.uniforms.backgroundBlurriness.value = scene3.backgroundBlurriness; boxMesh.material.uniforms.backgroundIntensity.value = scene3.backgroundIntensity; boxMesh.material.uniforms.backgroundRotation.value.setFromMatrix4(_m1$1.makeRotationFromEuler(_e1$1)); boxMesh.material.toneMapped = ColorManagement.getTransfer(background.colorSpace) !== SRGBTransfer; if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer3.toneMapping) { boxMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = background.version; currentTonemapping = renderer3.toneMapping; } boxMesh.layers.enableAll(); 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; planeMesh.material.uniforms.backgroundIntensity.value = scene3.backgroundIntensity; planeMesh.material.toneMapped = ColorManagement.getTransfer(background.colorSpace) !== SRGBTransfer; if (background.matrixAutoUpdate === true) { background.updateMatrix(); } planeMesh.material.uniforms.uvTransform.value.copy(background.matrix); if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer3.toneMapping) { planeMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = background.version; currentTonemapping = renderer3.toneMapping; } planeMesh.layers.enableAll(); renderList.unshift(planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null); } } function setClear(color2, alpha2) { color2.getRGB(_rgb, getUnlitUniformColorSpace(renderer3)); state.buffers.color.setClear(_rgb.r, _rgb.g, _rgb.b, alpha2, premultipliedAlpha); } return { getClearColor: function() { return clearColor; }, setClearColor: function(color2, alpha2 = 1) { clearColor.set(color2); clearAlpha = alpha2; setClear(clearColor, clearAlpha); }, getClearAlpha: function() { return clearAlpha; }, setClearAlpha: function(alpha2) { clearAlpha = alpha2; setClear(clearColor, clearAlpha); }, render, addToRenderList }; } function WebGLBindingStates(gl, attributes) { const maxVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); const bindingStates = {}; const defaultState = createBindingState(null); let currentState = defaultState; let forceUpdate = false; function setup(object, material, program, geometry, index5) { let updateBuffers = false; const state = getBindingState(geometry, program, material); if (currentState !== state) { currentState = state; bindVertexArrayObject(currentState.object); } updateBuffers = needsUpdate(object, geometry, program, index5); if (updateBuffers) saveCache(object, geometry, program, index5); if (index5 !== null) { attributes.update(index5, gl.ELEMENT_ARRAY_BUFFER); } if (updateBuffers || forceUpdate) { forceUpdate = false; setupVertexAttributes(object, material, program, geometry); if (index5 !== null) { gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attributes.get(index5).buffer); } } } function createVertexArrayObject() { return gl.createVertexArray(); } function bindVertexArrayObject(vao) { return gl.bindVertexArray(vao); } function deleteVertexArrayObject(vao) { return gl.deleteVertexArray(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 { // for backward compatibility on non-VAO support browser geometry: null, program: null, wireframe: false, newAttributes, enabledAttributes, attributeDivisors, object: vao, attributes: {}, index: null }; } function needsUpdate(object, geometry, program, index5) { const cachedAttributes = currentState.attributes; const geometryAttributes = geometry.attributes; let attributesNum = 0; const programAttributes = program.getAttributes(); for (const name in programAttributes) { const programAttribute = programAttributes[name]; if (programAttribute.location >= 0) { const cachedAttribute = cachedAttributes[name]; 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 (cachedAttribute === void 0) return true; if (cachedAttribute.attribute !== geometryAttribute) return true; if (geometryAttribute && cachedAttribute.data !== geometryAttribute.data) return true; attributesNum++; } } if (currentState.attributesNum !== attributesNum) return true; if (currentState.index !== index5) return true; return false; } function saveCache(object, geometry, program, index5) { const cache2 = {}; const attributes2 = geometry.attributes; let attributesNum = 0; const programAttributes = program.getAttributes(); for (const name in programAttributes) { const programAttribute = programAttributes[name]; if (programAttribute.location >= 0) { let attribute2 = attributes2[name]; if (attribute2 === void 0) { if (name === "instanceMatrix" && object.instanceMatrix) attribute2 = object.instanceMatrix; if (name === "instanceColor" && object.instanceColor) attribute2 = object.instanceColor; } const data = {}; data.attribute = attribute2; if (attribute2 && attribute2.data) { data.data = attribute2.data; } cache2[name] = data; attributesNum++; } } currentState.attributes = cache2; currentState.attributesNum = attributesNum; currentState.index = index5; } function initAttributes() { const newAttributes = currentState.newAttributes; for (let i = 0, il = newAttributes.length; i < il; i++) { newAttributes[i] = 0; } } function enableAttribute(attribute2) { enableAttributeAndDivisor(attribute2, 0); } function enableAttributeAndDivisor(attribute2, meshPerAttribute) { const newAttributes = currentState.newAttributes; const enabledAttributes = currentState.enabledAttributes; const attributeDivisors = currentState.attributeDivisors; newAttributes[attribute2] = 1; if (enabledAttributes[attribute2] === 0) { gl.enableVertexAttribArray(attribute2); enabledAttributes[attribute2] = 1; } if (attributeDivisors[attribute2] !== meshPerAttribute) { gl.vertexAttribDivisor(attribute2, meshPerAttribute); attributeDivisors[attribute2] = 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(index5, size, type, normalized, stride, offset, integer) { if (integer === true) { gl.vertexAttribIPointer(index5, size, type, stride, offset); } else { gl.vertexAttribPointer(index5, size, type, normalized, stride, offset); } } function setupVertexAttributes(object, material, program, geometry) { 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 attribute2 = attributes.get(geometryAttribute); if (attribute2 === void 0) continue; const buffer2 = attribute2.buffer; const type = attribute2.type; const bytesPerElement = attribute2.bytesPerElement; const integer = type === gl.INT || type === gl.UNSIGNED_INT || geometryAttribute.gpuType === IntType; if (geometryAttribute.isInterleavedBufferAttribute) { const data = geometryAttribute.data; const stride = data.stride; const offset = geometryAttribute.offset; if (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(gl.ARRAY_BUFFER, buffer2); 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, integer ); } } 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(gl.ARRAY_BUFFER, buffer2); for (let i = 0; i < programAttribute.locationSize; i++) { vertexAttribPointer( programAttribute.location + i, size / programAttribute.locationSize, type, normalized, size * bytesPerElement, size / programAttribute.locationSize * i * bytesPerElement, integer ); } } } 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(); forceUpdate = true; 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) { 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; gl.drawArraysInstanced(mode, start, count, primcount); info.update(count, mode, primcount); } function renderMultiDraw(starts, counts, drawCount) { if (drawCount === 0) return; const extension = extensions.get("WEBGL_multi_draw"); extension.multiDrawArraysWEBGL(mode, starts, 0, counts, 0, drawCount); let elementCount = 0; for (let i = 0; i < drawCount; i++) { elementCount += counts[i]; } info.update(elementCount, mode, 1); } function renderMultiDrawInstances(starts, counts, drawCount, primcount) { if (drawCount === 0) return; const extension = extensions.get("WEBGL_multi_draw"); if (extension === null) { for (let i = 0; i < starts.length; i++) { renderInstances(starts[i], counts[i], primcount[i]); } } else { extension.multiDrawArraysInstancedWEBGL(mode, starts, 0, counts, 0, primcount, 0, drawCount); let elementCount = 0; for (let i = 0; i < drawCount; i++) { elementCount += counts[i] * primcount[i]; } info.update(elementCount, mode, 1); } } this.setMode = setMode; this.render = render; this.renderInstances = renderInstances; this.renderMultiDraw = renderMultiDraw; this.renderMultiDrawInstances = renderMultiDrawInstances; } function WebGLCapabilities(gl, extensions, parameters, utils) { 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 textureFormatReadable(textureFormat) { if (textureFormat !== RGBAFormat && utils.convert(textureFormat) !== gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT)) { return false; } return true; } function textureTypeReadable(textureType) { const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has("EXT_color_buffer_half_float") || extensions.has("EXT_color_buffer_float")); if (textureType !== UnsignedByteType && utils.convert(textureType) !== gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE) && // Edge and Chrome Mac < 52 (#9513) textureType !== FloatType && !halfFloatSupportedByExt) { return false; } return true; } function getMaxPrecision(precision2) { if (precision2 === "highp") { if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) { return "highp"; } precision2 = "mediump"; } if (precision2 === "mediump") { if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) { return "mediump"; } } return "lowp"; } 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 logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true; const reverseDepthBuffer = parameters.reverseDepthBuffer === true && extensions.has("EXT_clip_control"); const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); const maxVertexTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); const maxCubemapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); const maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); const maxVertexUniforms = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); const maxVaryings = gl.getParameter(gl.MAX_VARYING_VECTORS); const maxFragmentUniforms = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS); const vertexTextures = maxVertexTextures > 0; const maxSamples = gl.getParameter(gl.MAX_SAMPLES); return { isWebGL2: true, // keeping this for backwards compatibility getMaxAnisotropy, getMaxPrecision, textureFormatReadable, textureTypeReadable, precision, logarithmicDepthBuffer, reverseDepthBuffer, maxTextures, maxVertexTextures, maxTextureSize, maxCubemapSize, maxAttributes, maxVertexUniforms, maxVaryings, maxFragmentUniforms, vertexTextures, maxSamples }; } function WebGLClipping(properties) { const scope = this; let globalState = null, numGlobalPlanes = 0, localClippingEnabled = false, renderingShadows = false; const plane = new Plane(), viewNormalMatrix = new Matrix3(), uniform2 = { value: null, needsUpdate: false }; this.uniform = uniform2; this.numPlanes = 0; this.numIntersection = 0; this.init = function(planes, enableLocalClipping) { const enabled = planes.length !== 0 || enableLocalClipping || // enable state of previous frame - the clipping code has to // run another frame in order to reset the state: numGlobalPlanes !== 0 || localClippingEnabled; localClippingEnabled = enableLocalClipping; numGlobalPlanes = planes.length; return enabled; }; this.beginShadows = function() { renderingShadows = true; projectPlanes(null); }; this.endShadows = function() { renderingShadows = false; }; this.setGlobalState = function(planes, camera3) { globalState = projectPlanes(planes, camera3, 0); }; this.setState = function(material, camera3, 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; uniform2.value = dstArray; dstArray = projectPlanes(planes, camera3, 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 (uniform2.value !== globalState) { uniform2.value = globalState; uniform2.needsUpdate = numGlobalPlanes > 0; } scope.numPlanes = numGlobalPlanes; scope.numIntersection = 0; } function projectPlanes(planes, camera3, dstOffset, skipTransform) { const nPlanes = planes !== null ? planes.length : 0; let dstArray = null; if (nPlanes !== 0) { dstArray = uniform2.value; if (skipTransform !== true || dstArray === null) { const flatSize = dstOffset + nPlanes * 4, viewMatrix = camera3.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; } } uniform2.value = dstArray; uniform2.needsUpdate = true; } scope.numPlanes = nPlanes; scope.numIntersection = 0; return dstArray; } } function WebGLCubeMaps(renderer3) { let cubemaps = /* @__PURE__ */ new WeakMap(); function mapTextureMapping2(texture2, mapping) { if (mapping === EquirectangularReflectionMapping) { texture2.mapping = CubeReflectionMapping; } else if (mapping === EquirectangularRefractionMapping) { texture2.mapping = CubeRefractionMapping; } return texture2; } function get2(texture2) { if (texture2 && texture2.isTexture) { const mapping = texture2.mapping; if (mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping) { if (cubemaps.has(texture2)) { const cubemap = cubemaps.get(texture2).texture; return mapTextureMapping2(cubemap, texture2.mapping); } else { const image = texture2.image; if (image && image.height > 0) { const renderTarget = new WebGLCubeRenderTarget(image.height); renderTarget.fromEquirectangularTexture(renderer3, texture2); cubemaps.set(texture2, renderTarget); texture2.addEventListener("dispose", onTextureDispose2); return mapTextureMapping2(renderTarget.texture, texture2.mapping); } else { return null; } } } } return texture2; } function onTextureDispose2(event) { const texture2 = event.target; texture2.removeEventListener("dispose", onTextureDispose2); const cubemap = cubemaps.get(texture2); if (cubemap !== void 0) { cubemaps.delete(texture2); cubemap.dispose(); } } function dispose() { cubemaps = /* @__PURE__ */ new WeakMap(); } return { get: get2, dispose }; } var OrthographicCamera = class extends Camera { constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2e3) { super(); this.isOrthographicCamera = true; 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, x2, y2, 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 = x2; this.view.offsetY = y2; 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.coordinateSystem); 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; } }; var LOD_MIN = 4; var EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; var MAX_SAMPLES = 20; var _flatCamera = /* @__PURE__ */ new OrthographicCamera(); var _clearColor = /* @__PURE__ */ new Color(); var _oldTarget = null; var _oldActiveCubeFace = 0; var _oldActiveMipmapLevel = 0; var _oldXrEnabled = false; var PHI = (1 + Math.sqrt(5)) / 2; var INV_PHI = 1 / PHI; var _axisDirections = [ /* @__PURE__ */ new Vector3(-PHI, INV_PHI, 0), /* @__PURE__ */ new Vector3(PHI, INV_PHI, 0), /* @__PURE__ */ new Vector3(-INV_PHI, 0, PHI), /* @__PURE__ */ new Vector3(INV_PHI, 0, PHI), /* @__PURE__ */ new Vector3(0, PHI, -INV_PHI), /* @__PURE__ */ new Vector3(0, PHI, INV_PHI), /* @__PURE__ */ new Vector3(-1, 1, -1), /* @__PURE__ */ new Vector3(1, 1, -1), /* @__PURE__ */ new Vector3(-1, 1, 1), /* @__PURE__ */ new Vector3(1, 1, 1) ]; var PMREMGenerator = class { constructor(renderer3) { this._renderer = renderer3; this._pingPongRenderTarget = null; this._lodMax = 0; this._cubeSize = 0; this._lodPlanes = []; this._sizeLods = []; this._sigmas = []; this._blurMaterial = null; this._cubemapMaterial = null; this._equirectMaterial = null; this._compileMaterial(this._blurMaterial); } /** * Generates a PMREM from a supplied Scene, which can be faster than using an * image if networking bandwidth is low. Optional sigma specifies a blur radius * in radians to be applied to the scene before PMREM generation. Optional near * and far planes ensure the scene is rendered in its entirety (the cubeCamera * is placed at the origin). */ fromScene(scene3, sigma = 0, near = 0.1, far = 100) { _oldTarget = this._renderer.getRenderTarget(); _oldActiveCubeFace = this._renderer.getActiveCubeFace(); _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); _oldXrEnabled = this._renderer.xr.enabled; this._renderer.xr.enabled = false; this._setSize(256); const cubeUVRenderTarget = this._allocateTargets(); cubeUVRenderTarget.depthBuffer = true; this._sceneToCubeUV(scene3, near, far, cubeUVRenderTarget); if (sigma > 0) { this._blur(cubeUVRenderTarget, 0, 0, sigma); } this._applyPMREM(cubeUVRenderTarget); this._cleanup(cubeUVRenderTarget); return cubeUVRenderTarget; } /** * Generates a PMREM from an equirectangular texture, which can be either LDR * or HDR. The ideal input image size is 1k (1024 x 512), * as this matches best with the 256 x 256 cubemap output. * The smallest supported equirectangular image size is 64 x 32. */ fromEquirectangular(equirectangular, renderTarget = null) { return this._fromTexture(equirectangular, renderTarget); } /** * Generates a PMREM from an cubemap texture, which can be either LDR * or HDR. The ideal input cube size is 256 x 256, * as this matches best with the 256 x 256 cubemap output. * The smallest supported cube size is 16 x 16. */ fromCubemap(cubemap, renderTarget = null) { return this._fromTexture(cubemap, renderTarget); } /** * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during * your texture's network fetch for increased concurrency. */ compileCubemapShader() { if (this._cubemapMaterial === null) { this._cubemapMaterial = _getCubemapMaterial(); this._compileMaterial(this._cubemapMaterial); } } /** * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during * your texture's network fetch for increased concurrency. */ compileEquirectangularShader() { if (this._equirectMaterial === null) { this._equirectMaterial = _getEquirectMaterial(); this._compileMaterial(this._equirectMaterial); } } /** * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on * one of them will cause any others to also become unusable. */ dispose() { this._dispose(); if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); } // private interface _setSize(cubeSize) { this._lodMax = Math.floor(Math.log2(cubeSize)); this._cubeSize = Math.pow(2, this._lodMax); } _dispose() { if (this._blurMaterial !== null) this._blurMaterial.dispose(); if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); for (let i = 0; i < this._lodPlanes.length; i++) { this._lodPlanes[i].dispose(); } } _cleanup(outputTarget) { this._renderer.setRenderTarget(_oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel); this._renderer.xr.enabled = _oldXrEnabled; outputTarget.scissorTest = false; _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); } _fromTexture(texture2, renderTarget) { if (texture2.mapping === CubeReflectionMapping || texture2.mapping === CubeRefractionMapping) { this._setSize(texture2.image.length === 0 ? 16 : texture2.image[0].width || texture2.image[0].image.width); } else { this._setSize(texture2.image.width / 4); } _oldTarget = this._renderer.getRenderTarget(); _oldActiveCubeFace = this._renderer.getActiveCubeFace(); _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); _oldXrEnabled = this._renderer.xr.enabled; this._renderer.xr.enabled = false; const cubeUVRenderTarget = renderTarget || this._allocateTargets(); this._textureToCubeUV(texture2, cubeUVRenderTarget); this._applyPMREM(cubeUVRenderTarget); this._cleanup(cubeUVRenderTarget); return cubeUVRenderTarget; } _allocateTargets() { const width = 3 * Math.max(this._cubeSize, 16 * 7); const height = 4 * this._cubeSize; const params = { magFilter: LinearFilter, minFilter: LinearFilter, generateMipmaps: false, type: HalfFloatType, format: RGBAFormat, colorSpace: LinearSRGBColorSpace, depthBuffer: false }; const cubeUVRenderTarget = _createRenderTarget(width, height, params); if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width || this._pingPongRenderTarget.height !== height) { if (this._pingPongRenderTarget !== null) { this._dispose(); } this._pingPongRenderTarget = _createRenderTarget(width, height, params); const { _lodMax } = this; ({ sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas } = _createPlanes(_lodMax)); this._blurMaterial = _getBlurShader(_lodMax, width, height); } return cubeUVRenderTarget; } _compileMaterial(material) { const tmpMesh = new Mesh(this._lodPlanes[0], material); this._renderer.compile(tmpMesh, _flatCamera); } _sceneToCubeUV(scene3, near, far, cubeUVRenderTarget) { const fov3 = 90; const aspect3 = 1; const cubeCamera = new PerspectiveCamera(fov3, aspect3, near, far); const upSign = [1, -1, 1, 1, 1, 1]; const forwardSign = [1, 1, 1, -1, -1, -1]; const renderer3 = this._renderer; const originalAutoClear = renderer3.autoClear; const toneMapping2 = renderer3.toneMapping; renderer3.getClearColor(_clearColor); renderer3.toneMapping = NoToneMapping; renderer3.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 = scene3.background; if (background) { if (background.isColor) { backgroundMaterial.color.copy(background); scene3.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]); } const size = this._cubeSize; _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); renderer3.setRenderTarget(cubeUVRenderTarget); if (useSolidColor) { renderer3.render(backgroundBox, cubeCamera); } renderer3.render(scene3, cubeCamera); } backgroundBox.geometry.dispose(); backgroundBox.material.dispose(); renderer3.toneMapping = toneMapping2; renderer3.autoClear = originalAutoClear; scene3.background = background; } _textureToCubeUV(texture2, cubeUVRenderTarget) { const renderer3 = this._renderer; const isCubeTexture = texture2.mapping === CubeReflectionMapping || texture2.mapping === CubeRefractionMapping; if (isCubeTexture) { if (this._cubemapMaterial === null) { this._cubemapMaterial = _getCubemapMaterial(); } this._cubemapMaterial.uniforms.flipEnvMap.value = texture2.isRenderTargetTexture === false ? -1 : 1; } else { if (this._equirectMaterial === null) { this._equirectMaterial = _getEquirectMaterial(); } } const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; const mesh = new Mesh(this._lodPlanes[0], material); const uniforms = material.uniforms; uniforms["envMap"].value = texture2; const size = this._cubeSize; _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); renderer3.setRenderTarget(cubeUVRenderTarget); renderer3.render(mesh, _flatCamera); } _applyPMREM(cubeUVRenderTarget) { const renderer3 = this._renderer; const autoClear = renderer3.autoClear; renderer3.autoClear = false; const n = this._lodPlanes.length; for (let i = 1; i < n; i++) { const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]); const poleAxis = _axisDirections[(n - i - 1) % _axisDirections.length]; this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); } renderer3.autoClear = autoClear; } /** * This is a two-pass Gaussian blur for a cubemap. Normally this is done * vertically and horizontally, but this breaks down on a cube. Here we apply * the blur latitudinally (around the poles), and then longitudinally (towards * the poles) to approximate the orthogonally-separable blur. It is least * accurate at the poles, but still does a decent job. */ _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, direction2, poleAxis) { const renderer3 = this._renderer; const blurMaterial = this._blurMaterial; if (direction2 !== "latitudinal" && direction2 !== "longitudinal") { console.error( "blur direction must be either latitudinal or longitudinal!" ); } const STANDARD_DEVIATIONS = 3; const blurMesh = new Mesh(this._lodPlanes[lodOut], blurMaterial); const blurUniforms = blurMaterial.uniforms; const pixels = this._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 x3 = i / sigmaPixels; const weight = Math.exp(-x3 * x3 / 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 = direction2 === "latitudinal"; if (poleAxis) { blurUniforms["poleAxis"].value = poleAxis; } const { _lodMax } = this; blurUniforms["dTheta"].value = radiansPerPixel; blurUniforms["mipInt"].value = _lodMax - lodIn; const outputSize = this._sizeLods[lodOut]; const x2 = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); const y2 = 4 * (this._cubeSize - outputSize); _setViewport(targetOut, x2, y2, 3 * outputSize, 2 * outputSize); renderer3.setRenderTarget(targetOut); renderer3.render(blurMesh, _flatCamera); } }; function _createPlanes(lodMax) { const lodPlanes = []; const sizeLods = []; const sigmas = []; let lod = lodMax; const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; for (let i = 0; i < totalLods; i++) { const sizeLod = Math.pow(2, lod); sizeLods.push(sizeLod); let sigma = 1 / sizeLod; if (i > lodMax - LOD_MIN) { sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; } else if (i === 0) { sigma = 0; } sigmas.push(sigma); const texelSize = 1 / (sizeLod - 2); const min2 = -texelSize; const max2 = 1 + texelSize; const uv1 = [min2, min2, max2, min2, max2, max2, min2, min2, max2, max2, min2, max2]; const cubeFaces = 6; const vertices = 6; const positionSize = 3; const uvSize = 2; const faceIndexSize = 1; const position = new Float32Array(positionSize * vertices * cubeFaces); const uv2 = new Float32Array(uvSize * vertices * cubeFaces); const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); for (let face = 0; face < cubeFaces; face++) { const x2 = face % 3 * 2 / 3 - 1; const y2 = face > 2 ? 0 : -1; const coordinates = [ x2, y2, 0, x2 + 2 / 3, y2, 0, x2 + 2 / 3, y2 + 1, 0, x2, y2, 0, x2 + 2 / 3, y2 + 1, 0, x2, y2 + 1, 0 ]; position.set(coordinates, positionSize * vertices * face); uv2.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(uv2, uvSize)); planes.setAttribute("faceIndex", new BufferAttribute(faceIndex, faceIndexSize)); lodPlanes.push(planes); if (lod > LOD_MIN) { lod--; } } return { lodPlanes, sizeLods, sigmas }; } function _createRenderTarget(width, height, params) { const cubeUVRenderTarget = new WebGLRenderTarget(width, height, params); cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; cubeUVRenderTarget.texture.name = "PMREM.cubeUv"; cubeUVRenderTarget.scissorTest = true; return cubeUVRenderTarget; } function _setViewport(target, x2, y2, width, height) { target.viewport.set(x2, y2, width, height); target.scissor.set(x2, y2, width, height); } function _getBlurShader(lodMax, width, height) { const weights = new Float32Array(MAX_SAMPLES); const poleAxis = new Vector3(0, 1, 0); const shaderMaterial = new ShaderMaterial({ name: "SphericalGaussianBlur", defines: { "n": MAX_SAMPLES, "CUBEUV_TEXEL_WIDTH": 1 / width, "CUBEUV_TEXEL_HEIGHT": 1 / height, "CUBEUV_MAX_MIP": `${lodMax}.0` }, uniforms: { "envMap": { value: null }, "samples": { value: 1 }, "weights": { value: weights }, "latitudinal": { value: false }, "dTheta": { value: 0 }, "mipInt": { value: 0 }, "poleAxis": { value: poleAxis } }, vertexShader: _getCommonVertexShader(), fragmentShader: ( /* glsl */ ` 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; #define ENVMAP_TYPE_CUBE_UV #include <cube_uv_reflection_fragment> 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 ); } } ` ), blending: NoBlending, depthTest: false, depthWrite: false }); return shaderMaterial; } function _getEquirectMaterial() { return new ShaderMaterial({ name: "EquirectangularToCubeUV", uniforms: { "envMap": { value: null } }, vertexShader: _getCommonVertexShader(), fragmentShader: ( /* glsl */ ` precision mediump float; precision mediump int; varying vec3 vOutputDirection; uniform sampler2D envMap; #include <common> void main() { vec3 outputDirection = normalize( vOutputDirection ); vec2 uv = equirectUv( outputDirection ); gl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 ); } ` ), blending: NoBlending, depthTest: false, depthWrite: false }); } function _getCubemapMaterial() { return new ShaderMaterial({ name: "CubemapToCubeUV", uniforms: { "envMap": { value: null }, "flipEnvMap": { value: -1 } }, vertexShader: _getCommonVertexShader(), fragmentShader: ( /* glsl */ ` precision mediump float; precision mediump int; uniform float flipEnvMap; varying vec3 vOutputDirection; uniform samplerCube envMap; void main() { gl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) ); } ` ), blending: NoBlending, depthTest: false, depthWrite: false }); } function _getCommonVertexShader() { return ( /* glsl */ ` precision mediump float; precision mediump int; 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 WebGLCubeUVMaps(renderer3) { let cubeUVmaps = /* @__PURE__ */ new WeakMap(); let pmremGenerator = null; function get2(texture2) { if (texture2 && texture2.isTexture) { const mapping = texture2.mapping; const isEquirectMap = mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping; const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping; if (isEquirectMap || isCubeMap) { let renderTarget = cubeUVmaps.get(texture2); const currentPMREMVersion = renderTarget !== void 0 ? renderTarget.texture.pmremVersion : 0; if (texture2.isRenderTargetTexture && texture2.pmremVersion !== currentPMREMVersion) { if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer3); renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture2, renderTarget) : pmremGenerator.fromCubemap(texture2, renderTarget); renderTarget.texture.pmremVersion = texture2.pmremVersion; cubeUVmaps.set(texture2, renderTarget); return renderTarget.texture; } else { if (renderTarget !== void 0) { return renderTarget.texture; } else { const image = texture2.image; if (isEquirectMap && image && image.height > 0 || isCubeMap && image && isCubeTextureComplete(image)) { if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer3); renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture2) : pmremGenerator.fromCubemap(texture2); renderTarget.texture.pmremVersion = texture2.pmremVersion; cubeUVmaps.set(texture2, renderTarget); texture2.addEventListener("dispose", onTextureDispose2); return renderTarget.texture; } else { return null; } } } } } return texture2; } function isCubeTextureComplete(image) { let count = 0; const length2 = 6; for (let i = 0; i < length2; i++) { if (image[i] !== void 0) count++; } return count === length2; } function onTextureDispose2(event) { const texture2 = event.target; texture2.removeEventListener("dispose", onTextureDispose2); const cubemapUV = cubeUVmaps.get(texture2); if (cubemapUV !== void 0) { cubeUVmaps.delete(texture2); cubemapUV.dispose(); } } function dispose() { cubeUVmaps = /* @__PURE__ */ new WeakMap(); if (pmremGenerator !== null) { pmremGenerator.dispose(); pmremGenerator = null; } } return { get: get2, 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() { getExtension("EXT_color_buffer_float"); getExtension("WEBGL_clip_cull_distance"); getExtension("OES_texture_float_linear"); getExtension("EXT_color_buffer_half_float"); getExtension("WEBGL_multisampled_render_to_texture"); getExtension("WEBGL_render_shared_exponent"); }, get: function(name) { const extension = getExtension(name); if (extension === null) { warnOnce("THREE.WebGLRenderer: " + name + " extension not supported."); } return extension; } }; } function WebGLGeometries(gl, attributes, info, bindingStates) { const geometries = {}; const wireframeAttributes = /* @__PURE__ */ 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]); } for (const name in geometry.morphAttributes) { const array = geometry.morphAttributes[name]; for (let i = 0, l = array.length; i < l; i++) { attributes.remove(array[i]); } } geometry.removeEventListener("dispose", onGeometryDispose); delete geometries[geometry.id]; const attribute2 = wireframeAttributes.get(geometry); if (attribute2) { attributes.remove(attribute2); wireframeAttributes.delete(geometry); } bindingStates.releaseStatesOfGeometry(geometry); if (geometry.isInstancedBufferGeometry === true) { delete geometry._maxInstanceCount; } info.memory.geometries--; } function get2(object, geometry) { if (geometries[geometry.id] === true) return geometry; geometry.addEventListener("dispose", onGeometryDispose); geometries[geometry.id] = true; info.memory.geometries++; return geometry; } function update4(geometry) { const geometryAttributes = geometry.attributes; for (const name in geometryAttributes) { attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER); } 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], gl.ARRAY_BUFFER); } } } 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 b = array[i + 1]; const c2 = array[i + 2]; indices.push(a2, b, b, c2, c2, a2); } } else if (geometryPosition !== void 0) { 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 b = i + 1; const c2 = i + 2; indices.push(a2, b, b, c2, c2, a2); } } else { return; } const attribute2 = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); attribute2.version = version; const previousAttribute = wireframeAttributes.get(geometry); if (previousAttribute) attributes.remove(previousAttribute); wireframeAttributes.set(geometry, attribute2); } 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: get2, update: update4, getWireframeAttribute }; } function WebGLIndexedBufferRenderer(gl, extensions, info) { 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; gl.drawElementsInstanced(mode, count, type, start * bytesPerElement, primcount); info.update(count, mode, primcount); } function renderMultiDraw(starts, counts, drawCount) { if (drawCount === 0) return; const extension = extensions.get("WEBGL_multi_draw"); extension.multiDrawElementsWEBGL(mode, counts, 0, type, starts, 0, drawCount); let elementCount = 0; for (let i = 0; i < drawCount; i++) { elementCount += counts[i]; } info.update(elementCount, mode, 1); } function renderMultiDrawInstances(starts, counts, drawCount, primcount) { if (drawCount === 0) return; const extension = extensions.get("WEBGL_multi_draw"); if (extension === null) { for (let i = 0; i < starts.length; i++) { renderInstances(starts[i] / bytesPerElement, counts[i], primcount[i]); } } else { extension.multiDrawElementsInstancedWEBGL(mode, counts, 0, type, starts, 0, primcount, 0, drawCount); let elementCount = 0; for (let i = 0; i < drawCount; i++) { elementCount += counts[i] * primcount[i]; } info.update(elementCount, mode, 1); } } this.setMode = setMode; this.setIndex = setIndex; this.render = render; this.renderInstances = renderInstances; this.renderMultiDraw = renderMultiDraw; this.renderMultiDrawInstances = renderMultiDrawInstances; } function WebGLInfo(gl) { const memory = { geometries: 0, textures: 0 }; const render = { frame: 0, calls: 0, triangles: 0, points: 0, lines: 0 }; function update4(count, mode, instanceCount) { render.calls++; switch (mode) { case gl.TRIANGLES: render.triangles += instanceCount * (count / 3); break; case gl.LINES: render.lines += instanceCount * (count / 2); break; case gl.LINE_STRIP: render.lines += instanceCount * (count - 1); break; case gl.LINE_LOOP: render.lines += instanceCount * count; break; case gl.POINTS: render.points += instanceCount * count; break; default: console.error("THREE.WebGLInfo: Unknown draw mode:", mode); break; } } function reset() { render.calls = 0; render.triangles = 0; render.points = 0; render.lines = 0; } return { memory, render, programs: null, autoReset: true, reset, update: update4 }; } function WebGLMorphtargets(gl, capabilities, textures) { const morphTextures = /* @__PURE__ */ new WeakMap(); const morph = new Vector4(); function update4(object, geometry, program) { const objectInfluences = object.morphTargetInfluences; const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; const morphTargetsCount = morphAttribute !== void 0 ? morphAttribute.length : 0; let entry = morphTextures.get(geometry); if (entry === void 0 || entry.count !== morphTargetsCount) { let disposeTexture = function() { texture2.dispose(); morphTextures.delete(geometry); geometry.removeEventListener("dispose", disposeTexture); }; if (entry !== void 0) entry.texture.dispose(); const hasMorphPosition = geometry.morphAttributes.position !== void 0; const hasMorphNormals = geometry.morphAttributes.normal !== void 0; const hasMorphColors = geometry.morphAttributes.color !== void 0; const morphTargets = geometry.morphAttributes.position || []; const morphNormals = geometry.morphAttributes.normal || []; const morphColors = geometry.morphAttributes.color || []; let vertexDataCount = 0; if (hasMorphPosition === true) vertexDataCount = 1; if (hasMorphNormals === true) vertexDataCount = 2; if (hasMorphColors === true) vertexDataCount = 3; let width = geometry.attributes.position.count * vertexDataCount; let height = 1; if (width > capabilities.maxTextureSize) { height = Math.ceil(width / capabilities.maxTextureSize); width = capabilities.maxTextureSize; } const buffer2 = new Float32Array(width * height * 4 * morphTargetsCount); const texture2 = new DataArrayTexture(buffer2, width, height, morphTargetsCount); texture2.type = FloatType; texture2.needsUpdate = true; const vertexDataStride = vertexDataCount * 4; for (let i = 0; i < morphTargetsCount; i++) { const morphTarget = morphTargets[i]; const morphNormal = morphNormals[i]; const morphColor = morphColors[i]; const offset = width * height * 4 * i; for (let j = 0; j < morphTarget.count; j++) { const stride = j * vertexDataStride; if (hasMorphPosition === true) { morph.fromBufferAttribute(morphTarget, j); buffer2[offset + stride + 0] = morph.x; buffer2[offset + stride + 1] = morph.y; buffer2[offset + stride + 2] = morph.z; buffer2[offset + stride + 3] = 0; } if (hasMorphNormals === true) { morph.fromBufferAttribute(morphNormal, j); buffer2[offset + stride + 4] = morph.x; buffer2[offset + stride + 5] = morph.y; buffer2[offset + stride + 6] = morph.z; buffer2[offset + stride + 7] = 0; } if (hasMorphColors === true) { morph.fromBufferAttribute(morphColor, j); buffer2[offset + stride + 8] = morph.x; buffer2[offset + stride + 9] = morph.y; buffer2[offset + stride + 10] = morph.z; buffer2[offset + stride + 11] = morphColor.itemSize === 4 ? morph.w : 1; } } } entry = { count: morphTargetsCount, texture: texture2, size: new Vector2(width, height) }; morphTextures.set(geometry, entry); geometry.addEventListener("dispose", disposeTexture); } if (object.isInstancedMesh === true && object.morphTexture !== null) { program.getUniforms().setValue(gl, "morphTexture", object.morphTexture, textures); } else { let morphInfluencesSum = 0; for (let i = 0; i < objectInfluences.length; i++) { morphInfluencesSum += objectInfluences[i]; } const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; program.getUniforms().setValue(gl, "morphTargetBaseInfluence", morphBaseInfluence); program.getUniforms().setValue(gl, "morphTargetInfluences", objectInfluences); } program.getUniforms().setValue(gl, "morphTargetsTexture", entry.texture, textures); program.getUniforms().setValue(gl, "morphTargetsTextureSize", entry.size); } return { update: update4 }; } function WebGLObjects(gl, geometries, attributes, info) { let updateMap = /* @__PURE__ */ new WeakMap(); function update4(object) { const frame2 = info.render.frame; const geometry = object.geometry; const buffergeometry = geometries.get(object, geometry); if (updateMap.get(buffergeometry) !== frame2) { geometries.update(buffergeometry); updateMap.set(buffergeometry, frame2); } if (object.isInstancedMesh) { if (object.hasEventListener("dispose", onInstancedMeshDispose) === false) { object.addEventListener("dispose", onInstancedMeshDispose); } if (updateMap.get(object) !== frame2) { attributes.update(object.instanceMatrix, gl.ARRAY_BUFFER); if (object.instanceColor !== null) { attributes.update(object.instanceColor, gl.ARRAY_BUFFER); } updateMap.set(object, frame2); } } if (object.isSkinnedMesh) { const skeleton = object.skeleton; if (updateMap.get(skeleton) !== frame2) { skeleton.update(); updateMap.set(skeleton, frame2); } } return buffergeometry; } function dispose() { updateMap = /* @__PURE__ */ 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: update4, dispose }; } var DepthTexture = class extends Texture { constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy2, format2 = DepthFormat) { if (format2 !== DepthFormat && format2 !== DepthStencilFormat) { throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat"); } if (type === void 0 && format2 === DepthFormat) type = UnsignedIntType; if (type === void 0 && format2 === DepthStencilFormat) type = UnsignedInt248Type; super(null, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy2); this.isDepthTexture = true; this.image = { width, height }; this.magFilter = magFilter !== void 0 ? magFilter : NearestFilter; this.minFilter = minFilter !== void 0 ? minFilter : NearestFilter; this.flipY = false; this.generateMipmaps = false; this.compareFunction = null; } copy(source) { super.copy(source); this.compareFunction = source.compareFunction; return this; } toJSON(meta) { const data = super.toJSON(meta); if (this.compareFunction !== null) data.compareFunction = this.compareFunction; return data; } }; var emptyTexture = /* @__PURE__ */ new Texture(); var emptyShadowTexture = /* @__PURE__ */ new DepthTexture(1, 1); var emptyArrayTexture = /* @__PURE__ */ new DataArrayTexture(); var empty3dTexture = /* @__PURE__ */ new Data3DTexture(); var emptyCubeTexture = /* @__PURE__ */ 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, b) { if (a2.length !== b.length) return false; for (let i = 0, l = a2.length; i < l; i++) { if (a2[i] !== b[i]) return false; } return true; } function copyArray(a2, b) { for (let i = 0, l = b.length; i < l; i++) { a2[i] = b[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 cache2 = this.cache; if (cache2[0] === v) return; gl.uniform1f(this.addr, v); cache2[0] = v; } function setValueV2f(gl, v) { const cache2 = this.cache; if (v.x !== void 0) { if (cache2[0] !== v.x || cache2[1] !== v.y) { gl.uniform2f(this.addr, v.x, v.y); cache2[0] = v.x; cache2[1] = v.y; } } else { if (arraysEqual(cache2, v)) return; gl.uniform2fv(this.addr, v); copyArray(cache2, v); } } function setValueV3f(gl, v) { const cache2 = this.cache; if (v.x !== void 0) { if (cache2[0] !== v.x || cache2[1] !== v.y || cache2[2] !== v.z) { gl.uniform3f(this.addr, v.x, v.y, v.z); cache2[0] = v.x; cache2[1] = v.y; cache2[2] = v.z; } } else if (v.r !== void 0) { if (cache2[0] !== v.r || cache2[1] !== v.g || cache2[2] !== v.b) { gl.uniform3f(this.addr, v.r, v.g, v.b); cache2[0] = v.r; cache2[1] = v.g; cache2[2] = v.b; } } else { if (arraysEqual(cache2, v)) return; gl.uniform3fv(this.addr, v); copyArray(cache2, v); } } function setValueV4f(gl, v) { const cache2 = this.cache; if (v.x !== void 0) { if (cache2[0] !== v.x || cache2[1] !== v.y || cache2[2] !== v.z || cache2[3] !== v.w) { gl.uniform4f(this.addr, v.x, v.y, v.z, v.w); cache2[0] = v.x; cache2[1] = v.y; cache2[2] = v.z; cache2[3] = v.w; } } else { if (arraysEqual(cache2, v)) return; gl.uniform4fv(this.addr, v); copyArray(cache2, v); } } function setValueM2(gl, v) { const cache2 = this.cache; const elements = v.elements; if (elements === void 0) { if (arraysEqual(cache2, v)) return; gl.uniformMatrix2fv(this.addr, false, v); copyArray(cache2, v); } else { if (arraysEqual(cache2, elements)) return; mat2array.set(elements); gl.uniformMatrix2fv(this.addr, false, mat2array); copyArray(cache2, elements); } } function setValueM3(gl, v) { const cache2 = this.cache; const elements = v.elements; if (elements === void 0) { if (arraysEqual(cache2, v)) return; gl.uniformMatrix3fv(this.addr, false, v); copyArray(cache2, v); } else { if (arraysEqual(cache2, elements)) return; mat3array.set(elements); gl.uniformMatrix3fv(this.addr, false, mat3array); copyArray(cache2, elements); } } function setValueM4(gl, v) { const cache2 = this.cache; const elements = v.elements; if (elements === void 0) { if (arraysEqual(cache2, v)) return; gl.uniformMatrix4fv(this.addr, false, v); copyArray(cache2, v); } else { if (arraysEqual(cache2, elements)) return; mat4array.set(elements); gl.uniformMatrix4fv(this.addr, false, mat4array); copyArray(cache2, elements); } } function setValueV1i(gl, v) { const cache2 = this.cache; if (cache2[0] === v) return; gl.uniform1i(this.addr, v); cache2[0] = v; } function setValueV2i(gl, v) { const cache2 = this.cache; if (v.x !== void 0) { if (cache2[0] !== v.x || cache2[1] !== v.y) { gl.uniform2i(this.addr, v.x, v.y); cache2[0] = v.x; cache2[1] = v.y; } } else { if (arraysEqual(cache2, v)) return; gl.uniform2iv(this.addr, v); copyArray(cache2, v); } } function setValueV3i(gl, v) { const cache2 = this.cache; if (v.x !== void 0) { if (cache2[0] !== v.x || cache2[1] !== v.y || cache2[2] !== v.z) { gl.uniform3i(this.addr, v.x, v.y, v.z); cache2[0] = v.x; cache2[1] = v.y; cache2[2] = v.z; } } else { if (arraysEqual(cache2, v)) return; gl.uniform3iv(this.addr, v); copyArray(cache2, v); } } function setValueV4i(gl, v) { const cache2 = this.cache; if (v.x !== void 0) { if (cache2[0] !== v.x || cache2[1] !== v.y || cache2[2] !== v.z || cache2[3] !== v.w) { gl.uniform4i(this.addr, v.x, v.y, v.z, v.w); cache2[0] = v.x; cache2[1] = v.y; cache2[2] = v.z; cache2[3] = v.w; } } else { if (arraysEqual(cache2, v)) return; gl.uniform4iv(this.addr, v); copyArray(cache2, v); } } function setValueV1ui(gl, v) { const cache2 = this.cache; if (cache2[0] === v) return; gl.uniform1ui(this.addr, v); cache2[0] = v; } function setValueV2ui(gl, v) { const cache2 = this.cache; if (v.x !== void 0) { if (cache2[0] !== v.x || cache2[1] !== v.y) { gl.uniform2ui(this.addr, v.x, v.y); cache2[0] = v.x; cache2[1] = v.y; } } else { if (arraysEqual(cache2, v)) return; gl.uniform2uiv(this.addr, v); copyArray(cache2, v); } } function setValueV3ui(gl, v) { const cache2 = this.cache; if (v.x !== void 0) { if (cache2[0] !== v.x || cache2[1] !== v.y || cache2[2] !== v.z) { gl.uniform3ui(this.addr, v.x, v.y, v.z); cache2[0] = v.x; cache2[1] = v.y; cache2[2] = v.z; } } else { if (arraysEqual(cache2, v)) return; gl.uniform3uiv(this.addr, v); copyArray(cache2, v); } } function setValueV4ui(gl, v) { const cache2 = this.cache; if (v.x !== void 0) { if (cache2[0] !== v.x || cache2[1] !== v.y || cache2[2] !== v.z || cache2[3] !== v.w) { gl.uniform4ui(this.addr, v.x, v.y, v.z, v.w); cache2[0] = v.x; cache2[1] = v.y; cache2[2] = v.z; cache2[3] = v.w; } } else { if (arraysEqual(cache2, v)) return; gl.uniform4uiv(this.addr, v); copyArray(cache2, v); } } function setValueT1(gl, v, textures) { const cache2 = this.cache; const unit = textures.allocateTextureUnit(); if (cache2[0] !== unit) { gl.uniform1i(this.addr, unit); cache2[0] = unit; } let emptyTexture2D; if (this.type === gl.SAMPLER_2D_SHADOW) { emptyShadowTexture.compareFunction = LessEqualCompare; emptyTexture2D = emptyShadowTexture; } else { emptyTexture2D = emptyTexture; } textures.setTexture2D(v || emptyTexture2D, unit); } function setValueT3D1(gl, v, textures) { const cache2 = this.cache; const unit = textures.allocateTextureUnit(); if (cache2[0] !== unit) { gl.uniform1i(this.addr, unit); cache2[0] = unit; } textures.setTexture3D(v || empty3dTexture, unit); } function setValueT6(gl, v, textures) { const cache2 = this.cache; const unit = textures.allocateTextureUnit(); if (cache2[0] !== unit) { gl.uniform1i(this.addr, unit); cache2[0] = unit; } textures.setTextureCube(v || emptyCubeTexture, unit); } function setValueT2DArray1(gl, v, textures) { const cache2 = this.cache; const unit = textures.allocateTextureUnit(); if (cache2[0] !== unit) { gl.uniform1i(this.addr, unit); cache2[0] = unit; } textures.setTexture2DArray(v || emptyArrayTexture, unit); } function getSingularSetter(type) { switch (type) { case 5126: return setValueV1f; // FLOAT case 35664: return setValueV2f; // _VEC2 case 35665: return setValueV3f; // _VEC3 case 35666: return setValueV4f; // _VEC4 case 35674: return setValueM2; // _MAT2 case 35675: return setValueM3; // _MAT3 case 35676: return setValueM4; // _MAT4 case 5124: case 35670: return setValueV1i; // INT, BOOL case 35667: case 35671: return setValueV2i; // _VEC2 case 35668: case 35672: return setValueV3i; // _VEC3 case 35669: case 35673: return setValueV4i; // _VEC4 case 5125: return setValueV1ui; // UINT case 36294: return setValueV2ui; // _VEC2 case 36295: return setValueV3ui; // _VEC3 case 36296: return setValueV4ui; // _VEC4 case 35678: // SAMPLER_2D case 36198: // SAMPLER_EXTERNAL_OES case 36298: // INT_SAMPLER_2D case 36306: // UNSIGNED_INT_SAMPLER_2D case 35682: return setValueT1; case 35679: // SAMPLER_3D case 36299: // INT_SAMPLER_3D case 36307: return setValueT3D1; case 35680: // SAMPLER_CUBE case 36300: // INT_SAMPLER_CUBE case 36308: // UNSIGNED_INT_SAMPLER_CUBE case 36293: return setValueT6; case 36289: // SAMPLER_2D_ARRAY case 36303: // INT_SAMPLER_2D_ARRAY case 36311: // UNSIGNED_INT_SAMPLER_2D_ARRAY 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 cache2 = this.cache; const n = v.length; const units = allocTexUnits(textures, n); if (!arraysEqual(cache2, units)) { gl.uniform1iv(this.addr, units); copyArray(cache2, units); } for (let i = 0; i !== n; ++i) { textures.setTexture2D(v[i] || emptyTexture, units[i]); } } function setValueT3DArray(gl, v, textures) { const cache2 = this.cache; const n = v.length; const units = allocTexUnits(textures, n); if (!arraysEqual(cache2, units)) { gl.uniform1iv(this.addr, units); copyArray(cache2, units); } for (let i = 0; i !== n; ++i) { textures.setTexture3D(v[i] || empty3dTexture, units[i]); } } function setValueT6Array(gl, v, textures) { const cache2 = this.cache; const n = v.length; const units = allocTexUnits(textures, n); if (!arraysEqual(cache2, units)) { gl.uniform1iv(this.addr, units); copyArray(cache2, units); } for (let i = 0; i !== n; ++i) { textures.setTextureCube(v[i] || emptyCubeTexture, units[i]); } } function setValueT2DArrayArray(gl, v, textures) { const cache2 = this.cache; const n = v.length; const units = allocTexUnits(textures, n); if (!arraysEqual(cache2, units)) { gl.uniform1iv(this.addr, units); copyArray(cache2, units); } for (let i = 0; i !== n; ++i) { textures.setTexture2DArray(v[i] || emptyArrayTexture, units[i]); } } function getPureArraySetter(type) { switch (type) { case 5126: return setValueV1fArray; // FLOAT case 35664: return setValueV2fArray; // _VEC2 case 35665: return setValueV3fArray; // _VEC3 case 35666: return setValueV4fArray; // _VEC4 case 35674: return setValueM2Array; // _MAT2 case 35675: return setValueM3Array; // _MAT3 case 35676: return setValueM4Array; // _MAT4 case 5124: case 35670: return setValueV1iArray; // INT, BOOL case 35667: case 35671: return setValueV2iArray; // _VEC2 case 35668: case 35672: return setValueV3iArray; // _VEC3 case 35669: case 35673: return setValueV4iArray; // _VEC4 case 5125: return setValueV1uiArray; // UINT case 36294: return setValueV2uiArray; // _VEC2 case 36295: return setValueV3uiArray; // _VEC3 case 36296: return setValueV4uiArray; // _VEC4 case 35678: // SAMPLER_2D case 36198: // SAMPLER_EXTERNAL_OES case 36298: // INT_SAMPLER_2D case 36306: // UNSIGNED_INT_SAMPLER_2D case 35682: return setValueT1Array; case 35679: // SAMPLER_3D case 36299: // INT_SAMPLER_3D case 36307: return setValueT3DArray; case 35680: // SAMPLER_CUBE case 36300: // INT_SAMPLER_CUBE case 36308: // UNSIGNED_INT_SAMPLER_CUBE case 36293: return setValueT6Array; case 36289: // SAMPLER_2D_ARRAY case 36303: // INT_SAMPLER_2D_ARRAY case 36311: // UNSIGNED_INT_SAMPLER_2D_ARRAY case 36292: return setValueT2DArrayArray; } } var SingleUniform = class { constructor(id2, activeInfo, addr) { this.id = id2; this.addr = addr; this.cache = []; this.type = activeInfo.type; this.setValue = getSingularSetter(activeInfo.type); } }; var PureArrayUniform = class { constructor(id2, activeInfo, addr) { this.id = id2; this.addr = addr; this.cache = []; this.type = activeInfo.type; this.size = activeInfo.size; this.setValue = getPureArraySetter(activeInfo.type); } }; var StructuredUniform = class { constructor(id2) { this.id = id2; this.seq = []; this.map = {}; } setValue(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 id2 = match[1]; const idIsIndex = match[2] === "]", subscript = match[3]; if (idIsIndex) id2 = id2 | 0; if (subscript === void 0 || subscript === "[" && matchEnd + 2 === pathLength) { addUniform(container, subscript === void 0 ? new SingleUniform(id2, activeInfo, addr) : new PureArrayUniform(id2, activeInfo, addr)); break; } else { const map = container.map; let next = map[id2]; if (next === void 0) { next = new StructuredUniform(id2); addUniform(container, next); } container = next; } } } var WebGLUniforms = class { constructor(gl, program) { this.seq = []; this.map = {}; const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); for (let i = 0; i < n; ++i) { const info = gl.getActiveUniform(program, i), addr = gl.getUniformLocation(program, info.name); parseUniform(info, addr, this); } } setValue(gl, name, value, textures) { const u = this.map[name]; if (u !== void 0) u.setValue(gl, value, textures); } setOptional(gl, object, name) { const v = object[name]; if (v !== void 0) this.setValue(gl, name, v); } static upload(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); } } } static seqWithValue(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 COMPLETION_STATUS_KHR = 37297; var programIdCount = 0; function handleSource(string, errorLine) { const lines = string.split("\n"); const lines2 = []; const from = Math.max(errorLine - 6, 0); const to = Math.min(errorLine + 6, lines.length); for (let i = from; i < to; i++) { const line = i + 1; lines2.push(`${line === errorLine ? ">" : " "} ${line}: ${lines[i]}`); } return lines2.join("\n"); } var _m0 = /* @__PURE__ */ new Matrix3(); function getEncodingComponents(colorSpace) { ColorManagement._getMatrix(_m0, ColorManagement.workingColorSpace, colorSpace); const encodingMatrix = `mat3( ${_m0.elements.map((v) => v.toFixed(4))} )`; switch (ColorManagement.getTransfer(colorSpace)) { case LinearTransfer: return [encodingMatrix, "LinearTransferOETF"]; case SRGBTransfer: return [encodingMatrix, "sRGBTransferOETF"]; default: console.warn("THREE.WebGLProgram: Unsupported color space: ", colorSpace); return [encodingMatrix, "LinearTransferOETF"]; } } function getShaderErrors(gl, shader, type) { const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); const errors = gl.getShaderInfoLog(shader).trim(); if (status && errors === "") return ""; const errorMatches = /ERROR: 0:(\d+)/.exec(errors); if (errorMatches) { const errorLine = parseInt(errorMatches[1]); return type.toUpperCase() + "\n\n" + errors + "\n\n" + handleSource(gl.getShaderSource(shader), errorLine); } else { return errors; } } function getTexelEncodingFunction(functionName, colorSpace) { const components = getEncodingComponents(colorSpace); return [ `vec4 ${functionName}( vec4 value ) {`, ` return ${components[1]}( vec4( value.rgb * ${components[0]}, value.a ) );`, "}" ].join("\n"); } function getToneMappingFunction(functionName, toneMapping2) { let toneMappingName; switch (toneMapping2) { case LinearToneMapping: toneMappingName = "Linear"; break; case ReinhardToneMapping: toneMappingName = "Reinhard"; break; case CineonToneMapping: toneMappingName = "Cineon"; break; case ACESFilmicToneMapping: toneMappingName = "ACESFilmic"; break; case AgXToneMapping: toneMappingName = "AgX"; break; case NeutralToneMapping: toneMappingName = "Neutral"; break; case CustomToneMapping: toneMappingName = "Custom"; break; default: console.warn("THREE.WebGLProgram: Unsupported toneMapping:", toneMapping2); toneMappingName = "Linear"; } return "vec3 " + functionName + "( vec3 color ) { return " + toneMappingName + "ToneMapping( color ); }"; } var _v0$1 = /* @__PURE__ */ new Vector3(); function getLuminanceFunction() { ColorManagement.getLuminanceCoefficients(_v0$1); const r = _v0$1.x.toFixed(4); const g = _v0$1.y.toFixed(4); const b = _v0$1.z.toFixed(4); return [ "float luminance( const in vec3 rgb ) {", ` const vec3 weights = vec3( ${r}, ${g}, ${b} );`, " return dot( weights, rgb );", "}" ].join("\n"); } function generateVertexExtensions(parameters) { const chunks = [ parameters.extensionClipCullDistance ? "#extension GL_ANGLE_clip_cull_distance : require" : "", parameters.extensionMultiDraw ? "#extension GL_ANGLE_multi_draw : require" : "" ]; 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, gl.ACTIVE_ATTRIBUTES); for (let i = 0; i < n; i++) { const info = gl.getActiveAttrib(program, i); const name = info.name; let locationSize = 1; if (info.type === gl.FLOAT_MAT2) locationSize = 2; if (info.type === gl.FLOAT_MAT3) locationSize = 3; if (info.type === gl.FLOAT_MAT4) locationSize = 4; attributes[name] = { type: info.type, location: gl.getAttribLocation(program, name), locationSize }; } return attributes; } function filterEmptyLine(string) { return string !== ""; } function replaceLightNums(string, parameters) { const numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps; return string.replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g, parameters.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g, numSpotLightCoords).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_WITH_MAPS/g, parameters.numSpotLightShadowsWithMaps).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); } var shaderChunkMap = /* @__PURE__ */ new Map(); function includeReplacer(match, include) { let string = ShaderChunk[include]; if (string === void 0) { const newInclude = shaderChunkMap.get(include); if (newInclude !== void 0) { string = ShaderChunk[newInclude]; console.warn('THREE.WebGLRenderer: Shader chunk "%s" has been deprecated. Use "%s" instead.', include, newInclude); } else { throw new Error("Can not resolve #include <" + include + ">"); } } return resolveIncludes(string); } 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); } 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; precision ${parameters.precision} int; precision ${parameters.precision} sampler2D; precision ${parameters.precision} samplerCube; precision ${parameters.precision} sampler3D; precision ${parameters.precision} sampler2DArray; precision ${parameters.precision} sampler2DShadow; precision ${parameters.precision} samplerCubeShadow; precision ${parameters.precision} sampler2DArrayShadow; precision ${parameters.precision} isampler2D; precision ${parameters.precision} isampler3D; precision ${parameters.precision} isamplerCube; precision ${parameters.precision} isampler2DArray; precision ${parameters.precision} usampler2D; precision ${parameters.precision} usampler3D; precision ${parameters.precision} usamplerCube; precision ${parameters.precision} usampler2DArray; `; 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: envMapTypeDefine = "ENVMAP_TYPE_CUBE_UV"; break; } } return envMapTypeDefine; } function generateEnvMapModeDefine(parameters) { let envMapModeDefine = "ENVMAP_MODE_REFLECTION"; if (parameters.envMap) { switch (parameters.envMapMode) { case CubeRefractionMapping: 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 generateCubeUVSize(parameters) { const imageHeight = parameters.envMapCubeUVHeight; if (imageHeight === null) return null; const maxMip = Math.log2(imageHeight) - 2; const texelHeight = 1 / imageHeight; const texelWidth = 1 / (3 * Math.max(Math.pow(2, maxMip), 7 * 16)); return { texelWidth, texelHeight, maxMip }; } function WebGLProgram(renderer3, cacheKey, parameters, bindingStates) { const gl = renderer3.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 envMapCubeUVSize = generateCubeUVSize(parameters); const customVertexExtensions = generateVertexExtensions(parameters); const customDefines = generateDefines(defines); const program = gl.createProgram(); let prefixVertex, prefixFragment; let versionString = parameters.glslVersion ? "#version " + parameters.glslVersion + "\n" : ""; if (parameters.isRawShaderMaterial) { prefixVertex = [ "#define SHADER_TYPE " + parameters.shaderType, "#define SHADER_NAME " + parameters.shaderName, customDefines ].filter(filterEmptyLine).join("\n"); if (prefixVertex.length > 0) { prefixVertex += "\n"; } prefixFragment = [ "#define SHADER_TYPE " + parameters.shaderType, "#define SHADER_NAME " + parameters.shaderName, customDefines ].filter(filterEmptyLine).join("\n"); if (prefixFragment.length > 0) { prefixFragment += "\n"; } } else { prefixVertex = [ generatePrecision(parameters), "#define SHADER_TYPE " + parameters.shaderType, "#define SHADER_NAME " + parameters.shaderName, customDefines, parameters.extensionClipCullDistance ? "#define USE_CLIP_DISTANCE" : "", parameters.batching ? "#define USE_BATCHING" : "", parameters.batchingColor ? "#define USE_BATCHING_COLOR" : "", parameters.instancing ? "#define USE_INSTANCING" : "", parameters.instancingColor ? "#define USE_INSTANCING_COLOR" : "", parameters.instancingMorph ? "#define USE_INSTANCING_MORPH" : "", 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.bumpMap ? "#define USE_BUMPMAP" : "", parameters.normalMap ? "#define USE_NORMALMAP" : "", parameters.normalMapObjectSpace ? "#define USE_NORMALMAP_OBJECTSPACE" : "", parameters.normalMapTangentSpace ? "#define USE_NORMALMAP_TANGENTSPACE" : "", parameters.displacementMap ? "#define USE_DISPLACEMENTMAP" : "", parameters.emissiveMap ? "#define USE_EMISSIVEMAP" : "", parameters.anisotropy ? "#define USE_ANISOTROPY" : "", parameters.anisotropyMap ? "#define USE_ANISOTROPYMAP" : "", parameters.clearcoatMap ? "#define USE_CLEARCOATMAP" : "", parameters.clearcoatRoughnessMap ? "#define USE_CLEARCOAT_ROUGHNESSMAP" : "", parameters.clearcoatNormalMap ? "#define USE_CLEARCOAT_NORMALMAP" : "", parameters.iridescenceMap ? "#define USE_IRIDESCENCEMAP" : "", parameters.iridescenceThicknessMap ? "#define USE_IRIDESCENCE_THICKNESSMAP" : "", parameters.specularMap ? "#define USE_SPECULARMAP" : "", parameters.specularColorMap ? "#define USE_SPECULAR_COLORMAP" : "", parameters.specularIntensityMap ? "#define USE_SPECULAR_INTENSITYMAP" : "", parameters.roughnessMap ? "#define USE_ROUGHNESSMAP" : "", parameters.metalnessMap ? "#define USE_METALNESSMAP" : "", parameters.alphaMap ? "#define USE_ALPHAMAP" : "", parameters.alphaHash ? "#define USE_ALPHAHASH" : "", parameters.transmission ? "#define USE_TRANSMISSION" : "", parameters.transmissionMap ? "#define USE_TRANSMISSIONMAP" : "", parameters.thicknessMap ? "#define USE_THICKNESSMAP" : "", parameters.sheenColorMap ? "#define USE_SHEEN_COLORMAP" : "", parameters.sheenRoughnessMap ? "#define USE_SHEEN_ROUGHNESSMAP" : "", // parameters.mapUv ? "#define MAP_UV " + parameters.mapUv : "", parameters.alphaMapUv ? "#define ALPHAMAP_UV " + parameters.alphaMapUv : "", parameters.lightMapUv ? "#define LIGHTMAP_UV " + parameters.lightMapUv : "", parameters.aoMapUv ? "#define AOMAP_UV " + parameters.aoMapUv : "", parameters.emissiveMapUv ? "#define EMISSIVEMAP_UV " + parameters.emissiveMapUv : "", parameters.bumpMapUv ? "#define BUMPMAP_UV " + parameters.bumpMapUv : "", parameters.normalMapUv ? "#define NORMALMAP_UV " + parameters.normalMapUv : "", parameters.displacementMapUv ? "#define DISPLACEMENTMAP_UV " + parameters.displacementMapUv : "", parameters.metalnessMapUv ? "#define METALNESSMAP_UV " + parameters.metalnessMapUv : "", parameters.roughnessMapUv ? "#define ROUGHNESSMAP_UV " + parameters.roughnessMapUv : "", parameters.anisotropyMapUv ? "#define ANISOTROPYMAP_UV " + parameters.anisotropyMapUv : "", parameters.clearcoatMapUv ? "#define CLEARCOATMAP_UV " + parameters.clearcoatMapUv : "", parameters.clearcoatNormalMapUv ? "#define CLEARCOAT_NORMALMAP_UV " + parameters.clearcoatNormalMapUv : "", parameters.clearcoatRoughnessMapUv ? "#define CLEARCOAT_ROUGHNESSMAP_UV " + parameters.clearcoatRoughnessMapUv : "", parameters.iridescenceMapUv ? "#define IRIDESCENCEMAP_UV " + parameters.iridescenceMapUv : "", parameters.iridescenceThicknessMapUv ? "#define IRIDESCENCE_THICKNESSMAP_UV " + parameters.iridescenceThicknessMapUv : "", parameters.sheenColorMapUv ? "#define SHEEN_COLORMAP_UV " + parameters.sheenColorMapUv : "", parameters.sheenRoughnessMapUv ? "#define SHEEN_ROUGHNESSMAP_UV " + parameters.sheenRoughnessMapUv : "", parameters.specularMapUv ? "#define SPECULARMAP_UV " + parameters.specularMapUv : "", parameters.specularColorMapUv ? "#define SPECULAR_COLORMAP_UV " + parameters.specularColorMapUv : "", parameters.specularIntensityMapUv ? "#define SPECULAR_INTENSITYMAP_UV " + parameters.specularIntensityMapUv : "", parameters.transmissionMapUv ? "#define TRANSMISSIONMAP_UV " + parameters.transmissionMapUv : "", parameters.thicknessMapUv ? "#define THICKNESSMAP_UV " + parameters.thicknessMapUv : "", // parameters.vertexTangents && parameters.flatShading === false ? "#define USE_TANGENT" : "", parameters.vertexColors ? "#define USE_COLOR" : "", parameters.vertexAlphas ? "#define USE_COLOR_ALPHA" : "", parameters.vertexUv1s ? "#define USE_UV1" : "", parameters.vertexUv2s ? "#define USE_UV2" : "", parameters.vertexUv3s ? "#define USE_UV3" : "", parameters.pointsUvs ? "#define USE_POINTS_UV" : "", parameters.flatShading ? "#define FLAT_SHADED" : "", parameters.skinning ? "#define USE_SKINNING" : "", parameters.morphTargets ? "#define USE_MORPHTARGETS" : "", parameters.morphNormals && parameters.flatShading === false ? "#define USE_MORPHNORMALS" : "", parameters.morphColors ? "#define USE_MORPHCOLORS" : "", parameters.morphTargetsCount > 0 ? "#define MORPHTARGETS_TEXTURE_STRIDE " + parameters.morphTextureStride : "", parameters.morphTargetsCount > 0 ? "#define MORPHTARGETS_COUNT " + parameters.morphTargetsCount : "", 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.numLightProbes > 0 ? "#define USE_LIGHT_PROBES" : "", parameters.logarithmicDepthBuffer ? "#define USE_LOGDEPTHBUF" : "", parameters.reverseDepthBuffer ? "#define USE_REVERSEDEPTHBUF" : "", "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", "#ifdef USE_INSTANCING_MORPH", " uniform sampler2D morphTexture;", "#endif", "attribute vec3 position;", "attribute vec3 normal;", "attribute vec2 uv;", "#ifdef USE_UV1", " attribute vec2 uv1;", "#endif", "#ifdef USE_UV2", " attribute vec2 uv2;", "#endif", "#ifdef USE_UV3", " attribute vec2 uv3;", "#endif", "#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_SKINNING", " attribute vec4 skinIndex;", " attribute vec4 skinWeight;", "#endif", "\n" ].filter(filterEmptyLine).join("\n"); prefixFragment = [ generatePrecision(parameters), "#define SHADER_TYPE " + parameters.shaderType, "#define SHADER_NAME " + parameters.shaderName, customDefines, parameters.useFog && parameters.fog ? "#define USE_FOG" : "", parameters.useFog && parameters.fogExp2 ? "#define FOG_EXP2" : "", parameters.alphaToCoverage ? "#define ALPHA_TO_COVERAGE" : "", 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 : "", envMapCubeUVSize ? "#define CUBEUV_TEXEL_WIDTH " + envMapCubeUVSize.texelWidth : "", envMapCubeUVSize ? "#define CUBEUV_TEXEL_HEIGHT " + envMapCubeUVSize.texelHeight : "", envMapCubeUVSize ? "#define CUBEUV_MAX_MIP " + envMapCubeUVSize.maxMip + ".0" : "", parameters.lightMap ? "#define USE_LIGHTMAP" : "", parameters.aoMap ? "#define USE_AOMAP" : "", parameters.bumpMap ? "#define USE_BUMPMAP" : "", parameters.normalMap ? "#define USE_NORMALMAP" : "", parameters.normalMapObjectSpace ? "#define USE_NORMALMAP_OBJECTSPACE" : "", parameters.normalMapTangentSpace ? "#define USE_NORMALMAP_TANGENTSPACE" : "", parameters.emissiveMap ? "#define USE_EMISSIVEMAP" : "", parameters.anisotropy ? "#define USE_ANISOTROPY" : "", parameters.anisotropyMap ? "#define USE_ANISOTROPYMAP" : "", parameters.clearcoat ? "#define USE_CLEARCOAT" : "", parameters.clearcoatMap ? "#define USE_CLEARCOATMAP" : "", parameters.clearcoatRoughnessMap ? "#define USE_CLEARCOAT_ROUGHNESSMAP" : "", parameters.clearcoatNormalMap ? "#define USE_CLEARCOAT_NORMALMAP" : "", parameters.dispersion ? "#define USE_DISPERSION" : "", parameters.iridescence ? "#define USE_IRIDESCENCE" : "", parameters.iridescenceMap ? "#define USE_IRIDESCENCEMAP" : "", parameters.iridescenceThicknessMap ? "#define USE_IRIDESCENCE_THICKNESSMAP" : "", parameters.specularMap ? "#define USE_SPECULARMAP" : "", parameters.specularColorMap ? "#define USE_SPECULAR_COLORMAP" : "", parameters.specularIntensityMap ? "#define USE_SPECULAR_INTENSITYMAP" : "", parameters.roughnessMap ? "#define USE_ROUGHNESSMAP" : "", parameters.metalnessMap ? "#define USE_METALNESSMAP" : "", parameters.alphaMap ? "#define USE_ALPHAMAP" : "", parameters.alphaTest ? "#define USE_ALPHATEST" : "", parameters.alphaHash ? "#define USE_ALPHAHASH" : "", parameters.sheen ? "#define USE_SHEEN" : "", parameters.sheenColorMap ? "#define USE_SHEEN_COLORMAP" : "", parameters.sheenRoughnessMap ? "#define USE_SHEEN_ROUGHNESSMAP" : "", parameters.transmission ? "#define USE_TRANSMISSION" : "", parameters.transmissionMap ? "#define USE_TRANSMISSIONMAP" : "", parameters.thicknessMap ? "#define USE_THICKNESSMAP" : "", parameters.vertexTangents && parameters.flatShading === false ? "#define USE_TANGENT" : "", parameters.vertexColors || parameters.instancingColor || parameters.batchingColor ? "#define USE_COLOR" : "", parameters.vertexAlphas ? "#define USE_COLOR_ALPHA" : "", parameters.vertexUv1s ? "#define USE_UV1" : "", parameters.vertexUv2s ? "#define USE_UV2" : "", parameters.vertexUv3s ? "#define USE_UV3" : "", parameters.pointsUvs ? "#define USE_POINTS_UV" : "", 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.numLightProbes > 0 ? "#define USE_LIGHT_PROBES" : "", parameters.decodeVideoTexture ? "#define DECODE_VIDEO_TEXTURE" : "", parameters.decodeVideoTextureEmissive ? "#define DECODE_VIDEO_TEXTURE_EMISSIVE" : "", parameters.logarithmicDepthBuffer ? "#define USE_LOGDEPTHBUF" : "", parameters.reverseDepthBuffer ? "#define USE_REVERSEDEPTHBUF" : "", "uniform mat4 viewMatrix;", "uniform vec3 cameraPosition;", "uniform bool isOrthographic;", parameters.toneMapping !== NoToneMapping ? "#define TONE_MAPPING" : "", parameters.toneMapping !== NoToneMapping ? ShaderChunk["tonemapping_pars_fragment"] : "", // this code is required here because it is used by the toneMapping() function defined below parameters.toneMapping !== NoToneMapping ? getToneMappingFunction("toneMapping", parameters.toneMapping) : "", parameters.dithering ? "#define DITHERING" : "", parameters.opaque ? "#define OPAQUE" : "", ShaderChunk["colorspace_pars_fragment"], // this code is required here because it is used by the various encoding/decoding function defined below getTexelEncodingFunction("linearToOutputTexel", parameters.outputColorSpace), getLuminanceFunction(), parameters.useDepthPacking ? "#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.isRawShaderMaterial !== true) { versionString = "#version 300 es\n"; prefixVertex = [ customVertexExtensions, "#define attribute in", "#define varying out", "#define texture2D texture" ].join("\n") + "\n" + prefixVertex; prefixFragment = [ "#define varying in", parameters.glslVersion === GLSL3 ? "" : "layout(location = 0) 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, gl.VERTEX_SHADER, vertexGlsl); const glFragmentShader = WebGLShader(gl, gl.FRAGMENT_SHADER, 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); function onFirstUse(self2) { if (renderer3.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, gl.LINK_STATUS) === false) { runnable = false; if (typeof renderer3.debug.onShaderError === "function") { renderer3.debug.onShaderError(gl, program, glVertexShader, glFragmentShader); } else { 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, gl.VALIDATE_STATUS) + "\n\nMaterial Name: " + self2.name + "\nMaterial Type: " + self2.type + "\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) { self2.diagnostics = { runnable, programLog, vertexShader: { log: vertexLog, prefix: prefixVertex }, fragmentShader: { log: fragmentLog, prefix: prefixFragment } }; } } gl.deleteShader(glVertexShader); gl.deleteShader(glFragmentShader); cachedUniforms = new WebGLUniforms(gl, program); cachedAttributes = fetchAttributeLocations(gl, program); } let cachedUniforms; this.getUniforms = function() { if (cachedUniforms === void 0) { onFirstUse(this); } return cachedUniforms; }; let cachedAttributes; this.getAttributes = function() { if (cachedAttributes === void 0) { onFirstUse(this); } return cachedAttributes; }; let programReady = parameters.rendererExtensionParallelShaderCompile === false; this.isReady = function() { if (programReady === false) { programReady = gl.getProgramParameter(program, COMPLETION_STATUS_KHR); } return programReady; }; this.destroy = function() { bindingStates.releaseStatesOfProgram(this); gl.deleteProgram(program); this.program = void 0; }; this.type = parameters.shaderType; this.name = parameters.shaderName; this.id = programIdCount++; this.cacheKey = cacheKey; this.usedTimes = 1; this.program = program; this.vertexShader = glVertexShader; this.fragmentShader = glFragmentShader; return this; } var _id$1 = 0; var WebGLShaderCache = class { constructor() { this.shaderCache = /* @__PURE__ */ new Map(); this.materialCache = /* @__PURE__ */ new Map(); } update(material) { const vertexShader = material.vertexShader; const fragmentShader = material.fragmentShader; const vertexShaderStage = this._getShaderStage(vertexShader); const fragmentShaderStage = this._getShaderStage(fragmentShader); const materialShaders = this._getShaderCacheForMaterial(material); if (materialShaders.has(vertexShaderStage) === false) { materialShaders.add(vertexShaderStage); vertexShaderStage.usedTimes++; } if (materialShaders.has(fragmentShaderStage) === false) { materialShaders.add(fragmentShaderStage); fragmentShaderStage.usedTimes++; } return this; } remove(material) { const materialShaders = this.materialCache.get(material); for (const shaderStage of materialShaders) { shaderStage.usedTimes--; if (shaderStage.usedTimes === 0) this.shaderCache.delete(shaderStage.code); } this.materialCache.delete(material); return this; } getVertexShaderID(material) { return this._getShaderStage(material.vertexShader).id; } getFragmentShaderID(material) { return this._getShaderStage(material.fragmentShader).id; } dispose() { this.shaderCache.clear(); this.materialCache.clear(); } _getShaderCacheForMaterial(material) { const cache2 = this.materialCache; let set2 = cache2.get(material); if (set2 === void 0) { set2 = /* @__PURE__ */ new Set(); cache2.set(material, set2); } return set2; } _getShaderStage(code) { const cache2 = this.shaderCache; let stage = cache2.get(code); if (stage === void 0) { stage = new WebGLShaderStage(code); cache2.set(code, stage); } return stage; } }; var WebGLShaderStage = class { constructor(code) { this.id = _id$1++; this.code = code; this.usedTimes = 0; } }; function WebGLPrograms(renderer3, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping2) { const _programLayers = new Layers(); const _customShaders = new WebGLShaderCache(); const _activeChannels = /* @__PURE__ */ new Set(); const programs = []; const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; const SUPPORTS_VERTEX_TEXTURES = 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" }; function getChannel(value) { _activeChannels.add(value); if (value === 0) return "uv"; return `uv${value}`; } function getParameters(material, lights, shadows, scene3, object) { const fog = scene3.fog; const geometry = object.geometry; const environment = material.isMeshStandardMaterial ? scene3.environment : null; const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment); const envMapCubeUVHeight = !!envMap && envMap.mapping === CubeUVReflectionMapping ? envMap.image.height : null; const shaderID = shaderIDs[material.type]; 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."); } } const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; const morphTargetsCount = morphAttribute !== void 0 ? morphAttribute.length : 0; let morphTextureStride = 0; if (geometry.morphAttributes.position !== void 0) morphTextureStride = 1; if (geometry.morphAttributes.normal !== void 0) morphTextureStride = 2; if (geometry.morphAttributes.color !== void 0) morphTextureStride = 3; let vertexShader, fragmentShader; let customVertexShaderID, customFragmentShaderID; if (shaderID) { const shader = ShaderLib[shaderID]; vertexShader = shader.vertexShader; fragmentShader = shader.fragmentShader; } else { vertexShader = material.vertexShader; fragmentShader = material.fragmentShader; _customShaders.update(material); customVertexShaderID = _customShaders.getVertexShaderID(material); customFragmentShaderID = _customShaders.getFragmentShaderID(material); } const currentRenderTarget = renderer3.getRenderTarget(); const reverseDepthBuffer = renderer3.state.buffers.depth.getReversed(); const IS_INSTANCEDMESH = object.isInstancedMesh === true; const IS_BATCHEDMESH = object.isBatchedMesh === true; const HAS_MAP = !!material.map; const HAS_MATCAP = !!material.matcap; const HAS_ENVMAP = !!envMap; const HAS_AOMAP = !!material.aoMap; const HAS_LIGHTMAP = !!material.lightMap; const HAS_BUMPMAP = !!material.bumpMap; const HAS_NORMALMAP = !!material.normalMap; const HAS_DISPLACEMENTMAP = !!material.displacementMap; const HAS_EMISSIVEMAP = !!material.emissiveMap; const HAS_METALNESSMAP = !!material.metalnessMap; const HAS_ROUGHNESSMAP = !!material.roughnessMap; const HAS_ANISOTROPY = material.anisotropy > 0; const HAS_CLEARCOAT = material.clearcoat > 0; const HAS_DISPERSION = material.dispersion > 0; const HAS_IRIDESCENCE = material.iridescence > 0; const HAS_SHEEN = material.sheen > 0; const HAS_TRANSMISSION = material.transmission > 0; const HAS_ANISOTROPYMAP = HAS_ANISOTROPY && !!material.anisotropyMap; const HAS_CLEARCOATMAP = HAS_CLEARCOAT && !!material.clearcoatMap; const HAS_CLEARCOAT_NORMALMAP = HAS_CLEARCOAT && !!material.clearcoatNormalMap; const HAS_CLEARCOAT_ROUGHNESSMAP = HAS_CLEARCOAT && !!material.clearcoatRoughnessMap; const HAS_IRIDESCENCEMAP = HAS_IRIDESCENCE && !!material.iridescenceMap; const HAS_IRIDESCENCE_THICKNESSMAP = HAS_IRIDESCENCE && !!material.iridescenceThicknessMap; const HAS_SHEEN_COLORMAP = HAS_SHEEN && !!material.sheenColorMap; const HAS_SHEEN_ROUGHNESSMAP = HAS_SHEEN && !!material.sheenRoughnessMap; const HAS_SPECULARMAP = !!material.specularMap; const HAS_SPECULAR_COLORMAP = !!material.specularColorMap; const HAS_SPECULAR_INTENSITYMAP = !!material.specularIntensityMap; const HAS_TRANSMISSIONMAP = HAS_TRANSMISSION && !!material.transmissionMap; const HAS_THICKNESSMAP = HAS_TRANSMISSION && !!material.thicknessMap; const HAS_GRADIENTMAP = !!material.gradientMap; const HAS_ALPHAMAP = !!material.alphaMap; const HAS_ALPHATEST = material.alphaTest > 0; const HAS_ALPHAHASH = !!material.alphaHash; const HAS_EXTENSIONS = !!material.extensions; let toneMapping2 = NoToneMapping; if (material.toneMapped) { if (currentRenderTarget === null || currentRenderTarget.isXRRenderTarget === true) { toneMapping2 = renderer3.toneMapping; } } const parameters = { shaderID, shaderType: material.type, shaderName: material.name, vertexShader, fragmentShader, defines: material.defines, customVertexShaderID, customFragmentShaderID, isRawShaderMaterial: material.isRawShaderMaterial === true, glslVersion: material.glslVersion, precision, batching: IS_BATCHEDMESH, batchingColor: IS_BATCHEDMESH && object._colorsTexture !== null, instancing: IS_INSTANCEDMESH, instancingColor: IS_INSTANCEDMESH && object.instanceColor !== null, instancingMorph: IS_INSTANCEDMESH && object.morphTexture !== null, supportsVertexTextures: SUPPORTS_VERTEX_TEXTURES, outputColorSpace: currentRenderTarget === null ? renderer3.outputColorSpace : currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace, alphaToCoverage: !!material.alphaToCoverage, map: HAS_MAP, matcap: HAS_MATCAP, envMap: HAS_ENVMAP, envMapMode: HAS_ENVMAP && envMap.mapping, envMapCubeUVHeight, aoMap: HAS_AOMAP, lightMap: HAS_LIGHTMAP, bumpMap: HAS_BUMPMAP, normalMap: HAS_NORMALMAP, displacementMap: SUPPORTS_VERTEX_TEXTURES && HAS_DISPLACEMENTMAP, emissiveMap: HAS_EMISSIVEMAP, normalMapObjectSpace: HAS_NORMALMAP && material.normalMapType === ObjectSpaceNormalMap, normalMapTangentSpace: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap, metalnessMap: HAS_METALNESSMAP, roughnessMap: HAS_ROUGHNESSMAP, anisotropy: HAS_ANISOTROPY, anisotropyMap: HAS_ANISOTROPYMAP, clearcoat: HAS_CLEARCOAT, clearcoatMap: HAS_CLEARCOATMAP, clearcoatNormalMap: HAS_CLEARCOAT_NORMALMAP, clearcoatRoughnessMap: HAS_CLEARCOAT_ROUGHNESSMAP, dispersion: HAS_DISPERSION, iridescence: HAS_IRIDESCENCE, iridescenceMap: HAS_IRIDESCENCEMAP, iridescenceThicknessMap: HAS_IRIDESCENCE_THICKNESSMAP, sheen: HAS_SHEEN, sheenColorMap: HAS_SHEEN_COLORMAP, sheenRoughnessMap: HAS_SHEEN_ROUGHNESSMAP, specularMap: HAS_SPECULARMAP, specularColorMap: HAS_SPECULAR_COLORMAP, specularIntensityMap: HAS_SPECULAR_INTENSITYMAP, transmission: HAS_TRANSMISSION, transmissionMap: HAS_TRANSMISSIONMAP, thicknessMap: HAS_THICKNESSMAP, gradientMap: HAS_GRADIENTMAP, opaque: material.transparent === false && material.blending === NormalBlending && material.alphaToCoverage === false, alphaMap: HAS_ALPHAMAP, alphaTest: HAS_ALPHATEST, alphaHash: HAS_ALPHAHASH, combine: material.combine, // mapUv: HAS_MAP && getChannel(material.map.channel), aoMapUv: HAS_AOMAP && getChannel(material.aoMap.channel), lightMapUv: HAS_LIGHTMAP && getChannel(material.lightMap.channel), bumpMapUv: HAS_BUMPMAP && getChannel(material.bumpMap.channel), normalMapUv: HAS_NORMALMAP && getChannel(material.normalMap.channel), displacementMapUv: HAS_DISPLACEMENTMAP && getChannel(material.displacementMap.channel), emissiveMapUv: HAS_EMISSIVEMAP && getChannel(material.emissiveMap.channel), metalnessMapUv: HAS_METALNESSMAP && getChannel(material.metalnessMap.channel), roughnessMapUv: HAS_ROUGHNESSMAP && getChannel(material.roughnessMap.channel), anisotropyMapUv: HAS_ANISOTROPYMAP && getChannel(material.anisotropyMap.channel), clearcoatMapUv: HAS_CLEARCOATMAP && getChannel(material.clearcoatMap.channel), clearcoatNormalMapUv: HAS_CLEARCOAT_NORMALMAP && getChannel(material.clearcoatNormalMap.channel), clearcoatRoughnessMapUv: HAS_CLEARCOAT_ROUGHNESSMAP && getChannel(material.clearcoatRoughnessMap.channel), iridescenceMapUv: HAS_IRIDESCENCEMAP && getChannel(material.iridescenceMap.channel), iridescenceThicknessMapUv: HAS_IRIDESCENCE_THICKNESSMAP && getChannel(material.iridescenceThicknessMap.channel), sheenColorMapUv: HAS_SHEEN_COLORMAP && getChannel(material.sheenColorMap.channel), sheenRoughnessMapUv: HAS_SHEEN_ROUGHNESSMAP && getChannel(material.sheenRoughnessMap.channel), specularMapUv: HAS_SPECULARMAP && getChannel(material.specularMap.channel), specularColorMapUv: HAS_SPECULAR_COLORMAP && getChannel(material.specularColorMap.channel), specularIntensityMapUv: HAS_SPECULAR_INTENSITYMAP && getChannel(material.specularIntensityMap.channel), transmissionMapUv: HAS_TRANSMISSIONMAP && getChannel(material.transmissionMap.channel), thicknessMapUv: HAS_THICKNESSMAP && getChannel(material.thicknessMap.channel), alphaMapUv: HAS_ALPHAMAP && getChannel(material.alphaMap.channel), // vertexTangents: !!geometry.attributes.tangent && (HAS_NORMALMAP || HAS_ANISOTROPY), vertexColors: material.vertexColors, vertexAlphas: material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4, pointsUvs: object.isPoints === true && !!geometry.attributes.uv && (HAS_MAP || HAS_ALPHAMAP), fog: !!fog, useFog: material.fog === true, fogExp2: !!fog && fog.isFogExp2, flatShading: material.flatShading === true, sizeAttenuation: material.sizeAttenuation === true, logarithmicDepthBuffer, reverseDepthBuffer, skinning: object.isSkinnedMesh === true, morphTargets: geometry.morphAttributes.position !== void 0, morphNormals: geometry.morphAttributes.normal !== void 0, morphColors: geometry.morphAttributes.color !== void 0, morphTargetsCount, morphTextureStride, numDirLights: lights.directional.length, numPointLights: lights.point.length, numSpotLights: lights.spot.length, numSpotLightMaps: lights.spotLightMap.length, numRectAreaLights: lights.rectArea.length, numHemiLights: lights.hemi.length, numDirLightShadows: lights.directionalShadowMap.length, numPointLightShadows: lights.pointShadowMap.length, numSpotLightShadows: lights.spotShadowMap.length, numSpotLightShadowsWithMaps: lights.numSpotLightShadowsWithMaps, numLightProbes: lights.numLightProbes, numClippingPlanes: clipping2.numPlanes, numClipIntersection: clipping2.numIntersection, dithering: material.dithering, shadowMapEnabled: renderer3.shadowMap.enabled && shadows.length > 0, shadowMapType: renderer3.shadowMap.type, toneMapping: toneMapping2, decodeVideoTexture: HAS_MAP && material.map.isVideoTexture === true && ColorManagement.getTransfer(material.map.colorSpace) === SRGBTransfer, decodeVideoTextureEmissive: HAS_EMISSIVEMAP && material.emissiveMap.isVideoTexture === true && ColorManagement.getTransfer(material.emissiveMap.colorSpace) === SRGBTransfer, premultipliedAlpha: material.premultipliedAlpha, doubleSided: material.side === DoubleSide, flipSided: material.side === BackSide, useDepthPacking: material.depthPacking >= 0, depthPacking: material.depthPacking || 0, index0AttributeName: material.index0AttributeName, extensionClipCullDistance: HAS_EXTENSIONS && material.extensions.clipCullDistance === true && extensions.has("WEBGL_clip_cull_distance"), extensionMultiDraw: (HAS_EXTENSIONS && material.extensions.multiDraw === true || IS_BATCHEDMESH) && extensions.has("WEBGL_multi_draw"), rendererExtensionParallelShaderCompile: extensions.has("KHR_parallel_shader_compile"), customProgramCacheKey: material.customProgramCacheKey() }; parameters.vertexUv1s = _activeChannels.has(1); parameters.vertexUv2s = _activeChannels.has(2); parameters.vertexUv3s = _activeChannels.has(3); _activeChannels.clear(); return parameters; } function getProgramCacheKey(parameters) { const array = []; if (parameters.shaderID) { array.push(parameters.shaderID); } else { array.push(parameters.customVertexShaderID); array.push(parameters.customFragmentShaderID); } if (parameters.defines !== void 0) { for (const name in parameters.defines) { array.push(name); array.push(parameters.defines[name]); } } if (parameters.isRawShaderMaterial === false) { getProgramCacheKeyParameters(array, parameters); getProgramCacheKeyBooleans(array, parameters); array.push(renderer3.outputColorSpace); } array.push(parameters.customProgramCacheKey); return array.join(); } function getProgramCacheKeyParameters(array, parameters) { array.push(parameters.precision); array.push(parameters.outputColorSpace); array.push(parameters.envMapMode); array.push(parameters.envMapCubeUVHeight); array.push(parameters.mapUv); array.push(parameters.alphaMapUv); array.push(parameters.lightMapUv); array.push(parameters.aoMapUv); array.push(parameters.bumpMapUv); array.push(parameters.normalMapUv); array.push(parameters.displacementMapUv); array.push(parameters.emissiveMapUv); array.push(parameters.metalnessMapUv); array.push(parameters.roughnessMapUv); array.push(parameters.anisotropyMapUv); array.push(parameters.clearcoatMapUv); array.push(parameters.clearcoatNormalMapUv); array.push(parameters.clearcoatRoughnessMapUv); array.push(parameters.iridescenceMapUv); array.push(parameters.iridescenceThicknessMapUv); array.push(parameters.sheenColorMapUv); array.push(parameters.sheenRoughnessMapUv); array.push(parameters.specularMapUv); array.push(parameters.specularColorMapUv); array.push(parameters.specularIntensityMapUv); array.push(parameters.transmissionMapUv); array.push(parameters.thicknessMapUv); array.push(parameters.combine); array.push(parameters.fogExp2); array.push(parameters.sizeAttenuation); array.push(parameters.morphTargetsCount); array.push(parameters.morphAttributeCount); array.push(parameters.numDirLights); array.push(parameters.numPointLights); array.push(parameters.numSpotLights); array.push(parameters.numSpotLightMaps); array.push(parameters.numHemiLights); array.push(parameters.numRectAreaLights); array.push(parameters.numDirLightShadows); array.push(parameters.numPointLightShadows); array.push(parameters.numSpotLightShadows); array.push(parameters.numSpotLightShadowsWithMaps); array.push(parameters.numLightProbes); array.push(parameters.shadowMapType); array.push(parameters.toneMapping); array.push(parameters.numClippingPlanes); array.push(parameters.numClipIntersection); array.push(parameters.depthPacking); } function getProgramCacheKeyBooleans(array, parameters) { _programLayers.disableAll(); if (parameters.supportsVertexTextures) _programLayers.enable(0); if (parameters.instancing) _programLayers.enable(1); if (parameters.instancingColor) _programLayers.enable(2); if (parameters.instancingMorph) _programLayers.enable(3); if (parameters.matcap) _programLayers.enable(4); if (parameters.envMap) _programLayers.enable(5); if (parameters.normalMapObjectSpace) _programLayers.enable(6); if (parameters.normalMapTangentSpace) _programLayers.enable(7); if (parameters.clearcoat) _programLayers.enable(8); if (parameters.iridescence) _programLayers.enable(9); if (parameters.alphaTest) _programLayers.enable(10); if (parameters.vertexColors) _programLayers.enable(11); if (parameters.vertexAlphas) _programLayers.enable(12); if (parameters.vertexUv1s) _programLayers.enable(13); if (parameters.vertexUv2s) _programLayers.enable(14); if (parameters.vertexUv3s) _programLayers.enable(15); if (parameters.vertexTangents) _programLayers.enable(16); if (parameters.anisotropy) _programLayers.enable(17); if (parameters.alphaHash) _programLayers.enable(18); if (parameters.batching) _programLayers.enable(19); if (parameters.dispersion) _programLayers.enable(20); if (parameters.batchingColor) _programLayers.enable(21); array.push(_programLayers.mask); _programLayers.disableAll(); if (parameters.fog) _programLayers.enable(0); if (parameters.useFog) _programLayers.enable(1); if (parameters.flatShading) _programLayers.enable(2); if (parameters.logarithmicDepthBuffer) _programLayers.enable(3); if (parameters.reverseDepthBuffer) _programLayers.enable(4); if (parameters.skinning) _programLayers.enable(5); if (parameters.morphTargets) _programLayers.enable(6); if (parameters.morphNormals) _programLayers.enable(7); if (parameters.morphColors) _programLayers.enable(8); if (parameters.premultipliedAlpha) _programLayers.enable(9); if (parameters.shadowMapEnabled) _programLayers.enable(10); if (parameters.doubleSided) _programLayers.enable(11); if (parameters.flipSided) _programLayers.enable(12); if (parameters.useDepthPacking) _programLayers.enable(13); if (parameters.dithering) _programLayers.enable(14); if (parameters.transmission) _programLayers.enable(15); if (parameters.sheen) _programLayers.enable(16); if (parameters.opaque) _programLayers.enable(17); if (parameters.pointsUvs) _programLayers.enable(18); if (parameters.decodeVideoTexture) _programLayers.enable(19); if (parameters.decodeVideoTextureEmissive) _programLayers.enable(20); if (parameters.alphaToCoverage) _programLayers.enable(21); array.push(_programLayers.mask); } 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 p = 0, pl = programs.length; p < pl; p++) { const preexistingProgram = programs[p]; if (preexistingProgram.cacheKey === cacheKey) { program = preexistingProgram; ++program.usedTimes; break; } } if (program === void 0) { program = new WebGLProgram(renderer3, 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(); } } function releaseShaderCache(material) { _customShaders.remove(material); } function dispose() { _customShaders.dispose(); } return { getParameters, getProgramCacheKey, getUniforms, acquireProgram, releaseProgram, releaseShaderCache, // Exposed for resource monitoring & error feedback via renderer.info: programs, dispose }; } function WebGLProperties() { let properties = /* @__PURE__ */ new WeakMap(); function has(object) { return properties.has(object); } function get2(object) { let map = properties.get(object); if (map === void 0) { map = {}; properties.set(object, map); } return map; } function remove2(object) { properties.delete(object); } function update4(object, key, value) { properties.get(object)[key] = value; } function dispose() { properties = /* @__PURE__ */ new WeakMap(); } return { has, get: get2, remove: remove2, update: update4, dispose }; } function painterSortStable(a2, b) { if (a2.groupOrder !== b.groupOrder) { return a2.groupOrder - b.groupOrder; } else if (a2.renderOrder !== b.renderOrder) { return a2.renderOrder - b.renderOrder; } else if (a2.material.id !== b.material.id) { return a2.material.id - b.material.id; } else if (a2.z !== b.z) { return a2.z - b.z; } else { return a2.id - b.id; } } function reversePainterSortStable(a2, b) { if (a2.groupOrder !== b.groupOrder) { return a2.groupOrder - b.groupOrder; } else if (a2.renderOrder !== b.renderOrder) { return a2.renderOrder - b.renderOrder; } else if (a2.z !== b.z) { return b.z - a2.z; } else { return a2.id - b.id; } } function WebGLRenderList() { const renderItems = []; let renderItemsIndex = 0; const opaque = []; const transmissive = []; const transparent = []; function init4() { renderItemsIndex = 0; opaque.length = 0; transmissive.length = 0; transparent.length = 0; } function getNextRenderItem(object, geometry, material, groupOrder, z2, group) { let renderItem = renderItems[renderItemsIndex]; if (renderItem === void 0) { renderItem = { id: object.id, object, geometry, material, groupOrder, renderOrder: object.renderOrder, z: z2, group }; renderItems[renderItemsIndex] = renderItem; } else { renderItem.id = object.id; renderItem.object = object; renderItem.geometry = geometry; renderItem.material = material; renderItem.groupOrder = groupOrder; renderItem.renderOrder = object.renderOrder; renderItem.z = z2; renderItem.group = group; } renderItemsIndex++; return renderItem; } function push(object, geometry, material, groupOrder, z2, group) { const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z2, 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, z2, group) { const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z2, 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.group = null; } } return { opaque, transmissive, transparent, init: init4, push, unshift, finish, sort }; } function WebGLRenderLists() { let lists = /* @__PURE__ */ new WeakMap(); function get2(scene3, renderCallDepth) { const listArray = lists.get(scene3); let list; if (listArray === void 0) { list = new WebGLRenderList(); lists.set(scene3, [list]); } else { if (renderCallDepth >= listArray.length) { list = new WebGLRenderList(); listArray.push(list); } else { list = listArray[renderCallDepth]; } } return list; } function dispose() { lists = /* @__PURE__ */ new WeakMap(); } return { get: get2, 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 = { shadowIntensity: 1, shadowBias: 0, shadowNormalBias: 0, shadowRadius: 1, shadowMapSize: new Vector2() }; break; case "SpotLight": uniforms = { shadowIntensity: 1, shadowBias: 0, shadowNormalBias: 0, shadowRadius: 1, shadowMapSize: new Vector2() }; break; case "PointLight": uniforms = { shadowIntensity: 1, shadowBias: 0, shadowNormalBias: 0, shadowRadius: 1, shadowMapSize: new Vector2(), shadowCameraNear: 1, shadowCameraFar: 1e3 }; break; } lights[light.id] = uniforms; return uniforms; } }; } var nextVersion = 0; function shadowCastingAndTexturingLightsFirst(lightA, lightB) { return (lightB.castShadow ? 2 : 0) - (lightA.castShadow ? 2 : 0) + (lightB.map ? 1 : 0) - (lightA.map ? 1 : 0); } function WebGLLights(extensions) { const cache2 = 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, numSpotMaps: -1, numLightProbes: -1 }, ambient: [0, 0, 0], probe: [], directional: [], directionalShadow: [], directionalShadowMap: [], directionalShadowMatrix: [], spot: [], spotLightMap: [], spotShadow: [], spotShadowMap: [], spotLightMatrix: [], rectArea: [], rectAreaLTC1: null, rectAreaLTC2: null, point: [], pointShadow: [], pointShadowMap: [], pointShadowMatrix: [], hemi: [], numSpotLightShadowsWithMaps: 0, numLightProbes: 0 }; 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) { let r = 0, g = 0, b = 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; let numSpotMaps = 0; let numSpotShadowsWithMaps = 0; let numLightProbes = 0; lights.sort(shadowCastingAndTexturingLightsFirst); for (let i = 0, l = lights.length; i < l; i++) { const light = lights[i]; const color2 = light.color; const intensity = light.intensity; const distance2 = light.distance; const shadowMap = light.shadow && light.shadow.map ? light.shadow.map.texture : null; if (light.isAmbientLight) { r += color2.r * intensity; g += color2.g * intensity; b += color2.b * intensity; } else if (light.isLightProbe) { for (let j = 0; j < 9; j++) { state.probe[j].addScaledVector(light.sh.coefficients[j], intensity); } numLightProbes++; } else if (light.isDirectionalLight) { const uniforms = cache2.get(light); uniforms.color.copy(light.color).multiplyScalar(light.intensity); if (light.castShadow) { const shadow2 = light.shadow; const shadowUniforms = shadowCache.get(light); shadowUniforms.shadowIntensity = shadow2.intensity; shadowUniforms.shadowBias = shadow2.bias; shadowUniforms.shadowNormalBias = shadow2.normalBias; shadowUniforms.shadowRadius = shadow2.radius; shadowUniforms.shadowMapSize = shadow2.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 = cache2.get(light); uniforms.position.setFromMatrixPosition(light.matrixWorld); uniforms.color.copy(color2).multiplyScalar(intensity); uniforms.distance = distance2; uniforms.coneCos = Math.cos(light.angle); uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra)); uniforms.decay = light.decay; state.spot[spotLength] = uniforms; const shadow2 = light.shadow; if (light.map) { state.spotLightMap[numSpotMaps] = light.map; numSpotMaps++; shadow2.updateMatrices(light); if (light.castShadow) numSpotShadowsWithMaps++; } state.spotLightMatrix[spotLength] = shadow2.matrix; if (light.castShadow) { const shadowUniforms = shadowCache.get(light); shadowUniforms.shadowIntensity = shadow2.intensity; shadowUniforms.shadowBias = shadow2.bias; shadowUniforms.shadowNormalBias = shadow2.normalBias; shadowUniforms.shadowRadius = shadow2.radius; shadowUniforms.shadowMapSize = shadow2.mapSize; state.spotShadow[spotLength] = shadowUniforms; state.spotShadowMap[spotLength] = shadowMap; numSpotShadows++; } spotLength++; } else if (light.isRectAreaLight) { const uniforms = cache2.get(light); uniforms.color.copy(color2).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 = cache2.get(light); uniforms.color.copy(light.color).multiplyScalar(light.intensity); uniforms.distance = light.distance; uniforms.decay = light.decay; if (light.castShadow) { const shadow2 = light.shadow; const shadowUniforms = shadowCache.get(light); shadowUniforms.shadowIntensity = shadow2.intensity; shadowUniforms.shadowBias = shadow2.bias; shadowUniforms.shadowNormalBias = shadow2.normalBias; shadowUniforms.shadowRadius = shadow2.radius; shadowUniforms.shadowMapSize = shadow2.mapSize; shadowUniforms.shadowCameraNear = shadow2.camera.near; shadowUniforms.shadowCameraFar = shadow2.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 = cache2.get(light); uniforms.skyColor.copy(light.color).multiplyScalar(intensity); uniforms.groundColor.copy(light.groundColor).multiplyScalar(intensity); state.hemi[hemiLength] = uniforms; hemiLength++; } } if (rectAreaLength > 0) { if (extensions.has("OES_texture_float_linear") === true) { state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; } else { state.rectAreaLTC1 = UniformsLib.LTC_HALF_1; state.rectAreaLTC2 = UniformsLib.LTC_HALF_2; } } state.ambient[0] = r; state.ambient[1] = g; state.ambient[2] = b; 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 || hash.numSpotMaps !== numSpotMaps || hash.numLightProbes !== numLightProbes) { 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.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps; state.spotLightMap.length = numSpotMaps; state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps; state.numLightProbes = numLightProbes; hash.directionalLength = directionalLength; hash.pointLength = pointLength; hash.spotLength = spotLength; hash.rectAreaLength = rectAreaLength; hash.hemiLength = hemiLength; hash.numDirectionalShadows = numDirectionalShadows; hash.numPointShadows = numPointShadows; hash.numSpotShadows = numSpotShadows; hash.numSpotMaps = numSpotMaps; hash.numLightProbes = numLightProbes; state.version = nextVersion++; } } function setupView(lights, camera3) { let directionalLength = 0; let pointLength = 0; let spotLength = 0; let rectAreaLength = 0; let hemiLength = 0; const viewMatrix = camera3.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); hemiLength++; } } } return { setup, setupView, state }; } function WebGLRenderState(extensions) { const lights = new WebGLLights(extensions); const lightsArray = []; const shadowsArray = []; function init4(camera3) { state.camera = camera3; lightsArray.length = 0; shadowsArray.length = 0; } function pushLight(light) { lightsArray.push(light); } function pushShadow(shadowLight) { shadowsArray.push(shadowLight); } function setupLights() { lights.setup(lightsArray); } function setupLightsView(camera3) { lights.setupView(lightsArray, camera3); } const state = { lightsArray, shadowsArray, camera: null, lights, transmissionRenderTarget: {} }; return { init: init4, state, setupLights, setupLightsView, pushLight, pushShadow }; } function WebGLRenderStates(extensions) { let renderStates = /* @__PURE__ */ new WeakMap(); function get2(scene3, renderCallDepth = 0) { const renderStateArray = renderStates.get(scene3); let renderState; if (renderStateArray === void 0) { renderState = new WebGLRenderState(extensions); renderStates.set(scene3, [renderState]); } else { if (renderCallDepth >= renderStateArray.length) { renderState = new WebGLRenderState(extensions); renderStateArray.push(renderState); } else { renderState = renderStateArray[renderCallDepth]; } } return renderState; } function dispose() { renderStates = /* @__PURE__ */ new WeakMap(); } return { get: get2, dispose }; } var MeshDepthMaterial = class extends Material { static get type() { return "MeshDepthMaterial"; } constructor(parameters) { super(); this.isMeshDepthMaterial = true; 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.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; } }; var MeshDistanceMaterial = class extends Material { static get type() { return "MeshDistanceMaterial"; } constructor(parameters) { super(); this.isMeshDistanceMaterial = true; this.map = null; this.alphaMap = null; this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.setValues(parameters); } copy(source) { super.copy(source); this.map = source.map; this.alphaMap = source.alphaMap; this.displacementMap = source.displacementMap; this.displacementScale = source.displacementScale; this.displacementBias = source.displacementBias; return this; } }; var vertex = "void main() {\n gl_Position = vec4( position, 1.0 );\n}"; var fragment = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n const float samples = float( VSM_SAMPLES );\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}"; function WebGLShadowMap(renderer3, objects, capabilities) { let _frustum2 = 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 = { [FrontSide]: BackSide, [BackSide]: FrontSide, [DoubleSide]: DoubleSide }; const shadowMaterialVertical = new ShaderMaterial({ defines: { VSM_SAMPLES: 8 }, uniforms: { shadow_pass: { value: null }, resolution: { value: new Vector2() }, radius: { value: 4 } }, vertexShader: vertex, fragmentShader: fragment }); 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; let _previousType = this.type; this.render = function(lights, scene3, camera3) { if (scope.enabled === false) return; if (scope.autoUpdate === false && scope.needsUpdate === false) return; if (lights.length === 0) return; const currentRenderTarget = renderer3.getRenderTarget(); const activeCubeFace = renderer3.getActiveCubeFace(); const activeMipmapLevel = renderer3.getActiveMipmapLevel(); const _state = renderer3.state; _state.setBlending(NoBlending); _state.buffers.color.setClear(1, 1, 1, 1); _state.buffers.depth.setTest(true); _state.setScissorTest(false); const toVSM = _previousType !== VSMShadowMap && this.type === VSMShadowMap; const fromVSM = _previousType === VSMShadowMap && this.type !== VSMShadowMap; for (let i = 0, il = lights.length; i < il; i++) { const light = lights[i]; const shadow2 = light.shadow; if (shadow2 === void 0) { console.warn("THREE.WebGLShadowMap:", light, "has no shadow."); continue; } if (shadow2.autoUpdate === false && shadow2.needsUpdate === false) continue; _shadowMapSize.copy(shadow2.mapSize); const shadowFrameExtents = shadow2.getFrameExtents(); _shadowMapSize.multiply(shadowFrameExtents); _viewportSize.copy(shadow2.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; shadow2.mapSize.x = _viewportSize.x; } if (_shadowMapSize.y > _maxTextureSize) { _viewportSize.y = Math.floor(_maxTextureSize / shadowFrameExtents.y); _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; shadow2.mapSize.y = _viewportSize.y; } } if (shadow2.map === null || toVSM === true || fromVSM === true) { const pars = this.type !== VSMShadowMap ? { minFilter: NearestFilter, magFilter: NearestFilter } : {}; if (shadow2.map !== null) { shadow2.map.dispose(); } shadow2.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars); shadow2.map.texture.name = light.name + ".shadowMap"; shadow2.camera.updateProjectionMatrix(); } renderer3.setRenderTarget(shadow2.map); renderer3.clear(); const viewportCount = shadow2.getViewportCount(); for (let vp = 0; vp < viewportCount; vp++) { const viewport2 = shadow2.getViewport(vp); _viewport.set( _viewportSize.x * viewport2.x, _viewportSize.y * viewport2.y, _viewportSize.x * viewport2.z, _viewportSize.y * viewport2.w ); _state.viewport(_viewport); shadow2.updateMatrices(light, vp); _frustum2 = shadow2.getFrustum(); renderObject(scene3, camera3, shadow2.camera, light, this.type); } if (shadow2.isPointLightShadow !== true && this.type === VSMShadowMap) { VSMPass(shadow2, camera3); } shadow2.needsUpdate = false; } _previousType = this.type; scope.needsUpdate = false; renderer3.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel); }; function VSMPass(shadow2, camera3) { const geometry = objects.update(fullScreenMesh); if (shadowMaterialVertical.defines.VSM_SAMPLES !== shadow2.blurSamples) { shadowMaterialVertical.defines.VSM_SAMPLES = shadow2.blurSamples; shadowMaterialHorizontal.defines.VSM_SAMPLES = shadow2.blurSamples; shadowMaterialVertical.needsUpdate = true; shadowMaterialHorizontal.needsUpdate = true; } if (shadow2.mapPass === null) { shadow2.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y); } shadowMaterialVertical.uniforms.shadow_pass.value = shadow2.map.texture; shadowMaterialVertical.uniforms.resolution.value = shadow2.mapSize; shadowMaterialVertical.uniforms.radius.value = shadow2.radius; renderer3.setRenderTarget(shadow2.mapPass); renderer3.clear(); renderer3.renderBufferDirect(camera3, null, geometry, shadowMaterialVertical, fullScreenMesh, null); shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow2.mapPass.texture; shadowMaterialHorizontal.uniforms.resolution.value = shadow2.mapSize; shadowMaterialHorizontal.uniforms.radius.value = shadow2.radius; renderer3.setRenderTarget(shadow2.map); renderer3.clear(); renderer3.renderBufferDirect(camera3, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null); } function getDepthMaterial(object, material, light, 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 (renderer3.localClippingEnabled && material.clipShadows === true && Array.isArray(material.clippingPlanes) && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0 || material.map && 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; material.addEventListener("dispose", onMaterialDispose); } 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.map = material.map; 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) { const materialProperties = renderer3.properties.get(result); materialProperties.light = light; } return result; } function renderObject(object, camera3, shadowCamera, light, type) { if (object.visible === false) return; const visible = object.layers.test(camera3.layers); if (visible && (object.isMesh || object.isLine || object.isPoints)) { if ((object.castShadow || object.receiveShadow && type === VSMShadowMap) && (!object.frustumCulled || _frustum2.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, groupMaterial, light, type); object.onBeforeShadow(renderer3, object, camera3, shadowCamera, geometry, depthMaterial, group); renderer3.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group); object.onAfterShadow(renderer3, object, camera3, shadowCamera, geometry, depthMaterial, group); } } } else if (material.visible) { const depthMaterial = getDepthMaterial(object, material, light, type); object.onBeforeShadow(renderer3, object, camera3, shadowCamera, geometry, depthMaterial, null); renderer3.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null); object.onAfterShadow(renderer3, object, camera3, shadowCamera, geometry, depthMaterial, null); } } } const children = object.children; for (let i = 0, l = children.length; i < l; i++) { renderObject(children[i], camera3, shadowCamera, light, type); } } function onMaterialDispose(event) { const material = event.target; material.removeEventListener("dispose", onMaterialDispose); for (const id2 in _materialCache) { const cache2 = _materialCache[id2]; const uuid = event.target.uuid; if (uuid in cache2) { const shadowMaterial = cache2[uuid]; shadowMaterial.dispose(); delete cache2[uuid]; } } } } var reversedFuncs = { [NeverDepth]: AlwaysDepth, [LessDepth]: GreaterDepth, [EqualDepth]: NotEqualDepth, [LessEqualDepth]: GreaterEqualDepth, [AlwaysDepth]: NeverDepth, [GreaterDepth]: LessDepth, [NotEqualDepth]: EqualDepth, [GreaterEqualDepth]: LessEqualDepth }; function WebGLState(gl, extensions) { function ColorBuffer() { let locked = false; const color2 = 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, b, a2, premultipliedAlpha) { if (premultipliedAlpha === true) { r *= a2; g *= a2; b *= a2; } color2.set(r, g, b, a2); if (currentColorClear.equals(color2) === false) { gl.clearColor(r, g, b, a2); currentColorClear.copy(color2); } }, reset: function() { locked = false; currentColorMask = null; currentColorClear.set(-1, 0, 0, 0); } }; } function DepthBuffer() { let locked = false; let reversed = false; let currentDepthMask = null; let currentDepthFunc = null; let currentDepthClear = null; return { setReversed: function(value) { if (reversed !== value) { const ext = extensions.get("EXT_clip_control"); if (reversed) { ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.ZERO_TO_ONE_EXT); } else { ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.NEGATIVE_ONE_TO_ONE_EXT); } const oldDepth = currentDepthClear; currentDepthClear = null; this.setClear(oldDepth); } reversed = value; }, getReversed: function() { return reversed; }, setTest: function(depthTest) { if (depthTest) { enable(gl.DEPTH_TEST); } else { disable(gl.DEPTH_TEST); } }, setMask: function(depthMask) { if (currentDepthMask !== depthMask && !locked) { gl.depthMask(depthMask); currentDepthMask = depthMask; } }, setFunc: function(depthFunc) { if (reversed) depthFunc = reversedFuncs[depthFunc]; if (currentDepthFunc !== depthFunc) { switch (depthFunc) { case NeverDepth: gl.depthFunc(gl.NEVER); break; case AlwaysDepth: gl.depthFunc(gl.ALWAYS); break; case LessDepth: gl.depthFunc(gl.LESS); break; case LessEqualDepth: gl.depthFunc(gl.LEQUAL); break; case EqualDepth: gl.depthFunc(gl.EQUAL); break; case GreaterEqualDepth: gl.depthFunc(gl.GEQUAL); break; case GreaterDepth: gl.depthFunc(gl.GREATER); break; case NotEqualDepth: gl.depthFunc(gl.NOTEQUAL); break; default: gl.depthFunc(gl.LEQUAL); } currentDepthFunc = depthFunc; } }, setLocked: function(lock) { locked = lock; }, setClear: function(depth2) { if (currentDepthClear !== depth2) { if (reversed) { depth2 = 1 - depth2; } gl.clearDepth(depth2); currentDepthClear = depth2; } }, reset: function() { locked = false; currentDepthMask = null; currentDepthFunc = null; currentDepthClear = null; reversed = false; } }; } 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(gl.STENCIL_TEST); } else { disable(gl.STENCIL_TEST); } } }, 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(); const uboBindings = /* @__PURE__ */ new WeakMap(); const uboProgramMap = /* @__PURE__ */ new WeakMap(); let enabledCapabilities = {}; let currentBoundFramebuffers = {}; let currentDrawbuffers = /* @__PURE__ */ new WeakMap(); let defaultDrawbuffers = []; 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 currentBlendColor = new Color(0, 0, 0); let currentBlendAlpha = 0; let currentPremultipledAlpha = false; let currentFlipSided = null; let currentCullFace = null; let currentLineWidth = null; let currentPolygonOffsetFactor = null; let currentPolygonOffsetUnits = null; const maxTextures = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS); let lineWidthAvailable = false; let version = 0; const glVersion = gl.getParameter(gl.VERSION); 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(gl.SCISSOR_BOX); const viewportParam = gl.getParameter(gl.VIEWPORT); const currentScissor = new Vector4().fromArray(scissorParam); const currentViewport = new Vector4().fromArray(viewportParam); function createTexture(type, target, count, dimensions) { const data = new Uint8Array(4); const texture2 = gl.createTexture(); gl.bindTexture(type, texture2); gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, gl.NEAREST); for (let i = 0; i < count; i++) { if (type === gl.TEXTURE_3D || type === gl.TEXTURE_2D_ARRAY) { gl.texImage3D(target, 0, gl.RGBA, 1, 1, dimensions, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); } else { gl.texImage2D(target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); } } return texture2; } const emptyTextures = {}; emptyTextures[gl.TEXTURE_2D] = createTexture(gl.TEXTURE_2D, gl.TEXTURE_2D, 1); emptyTextures[gl.TEXTURE_CUBE_MAP] = createTexture(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6); emptyTextures[gl.TEXTURE_2D_ARRAY] = createTexture(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_2D_ARRAY, 1, 1); emptyTextures[gl.TEXTURE_3D] = createTexture(gl.TEXTURE_3D, gl.TEXTURE_3D, 1, 1); colorBuffer.setClear(0, 0, 0, 1); depthBuffer.setClear(1); stencilBuffer.setClear(0); enable(gl.DEPTH_TEST); depthBuffer.setFunc(LessEqualDepth); setFlipSided(false); setCullFace(CullFaceBack); enable(gl.CULL_FACE); setBlending(NoBlending); function enable(id2) { if (enabledCapabilities[id2] !== true) { gl.enable(id2); enabledCapabilities[id2] = true; } } function disable(id2) { if (enabledCapabilities[id2] !== false) { gl.disable(id2); enabledCapabilities[id2] = false; } } function bindFramebuffer(target, framebuffer) { if (currentBoundFramebuffers[target] !== framebuffer) { gl.bindFramebuffer(target, framebuffer); currentBoundFramebuffers[target] = framebuffer; if (target === gl.DRAW_FRAMEBUFFER) { currentBoundFramebuffers[gl.FRAMEBUFFER] = framebuffer; } if (target === gl.FRAMEBUFFER) { currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer; } return true; } return false; } function drawBuffers(renderTarget, framebuffer) { let drawBuffers2 = defaultDrawbuffers; let needsUpdate = false; if (renderTarget) { drawBuffers2 = currentDrawbuffers.get(framebuffer); if (drawBuffers2 === void 0) { drawBuffers2 = []; currentDrawbuffers.set(framebuffer, drawBuffers2); } const textures = renderTarget.textures; if (drawBuffers2.length !== textures.length || drawBuffers2[0] !== gl.COLOR_ATTACHMENT0) { for (let i = 0, il = textures.length; i < il; i++) { drawBuffers2[i] = gl.COLOR_ATTACHMENT0 + i; } drawBuffers2.length = textures.length; needsUpdate = true; } } else { if (drawBuffers2[0] !== gl.BACK) { drawBuffers2[0] = gl.BACK; needsUpdate = true; } } if (needsUpdate) { gl.drawBuffers(drawBuffers2); } } function useProgram(program) { if (currentProgram !== program) { gl.useProgram(program); currentProgram = program; return true; } return false; } const equationToGL2 = { [AddEquation]: gl.FUNC_ADD, [SubtractEquation]: gl.FUNC_SUBTRACT, [ReverseSubtractEquation]: gl.FUNC_REVERSE_SUBTRACT }; equationToGL2[MinEquation] = gl.MIN; equationToGL2[MaxEquation] = gl.MAX; const factorToGL2 = { [ZeroFactor]: gl.ZERO, [OneFactor]: gl.ONE, [SrcColorFactor]: gl.SRC_COLOR, [SrcAlphaFactor]: gl.SRC_ALPHA, [SrcAlphaSaturateFactor]: gl.SRC_ALPHA_SATURATE, [DstColorFactor]: gl.DST_COLOR, [DstAlphaFactor]: gl.DST_ALPHA, [OneMinusSrcColorFactor]: gl.ONE_MINUS_SRC_COLOR, [OneMinusSrcAlphaFactor]: gl.ONE_MINUS_SRC_ALPHA, [OneMinusDstColorFactor]: gl.ONE_MINUS_DST_COLOR, [OneMinusDstAlphaFactor]: gl.ONE_MINUS_DST_ALPHA, [ConstantColorFactor]: gl.CONSTANT_COLOR, [OneMinusConstantColorFactor]: gl.ONE_MINUS_CONSTANT_COLOR, [ConstantAlphaFactor]: gl.CONSTANT_ALPHA, [OneMinusConstantAlphaFactor]: gl.ONE_MINUS_CONSTANT_ALPHA }; function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, blendColor, blendAlpha, premultipliedAlpha) { if (blending === NoBlending) { if (currentBlendingEnabled === true) { disable(gl.BLEND); currentBlendingEnabled = false; } return; } if (currentBlendingEnabled === false) { enable(gl.BLEND); currentBlendingEnabled = true; } if (blending !== CustomBlending) { if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) { if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) { gl.blendEquation(gl.FUNC_ADD); currentBlendEquation = AddEquation; currentBlendEquationAlpha = AddEquation; } if (premultipliedAlpha) { switch (blending) { case NormalBlending: gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); break; case AdditiveBlending: gl.blendFunc(gl.ONE, gl.ONE); break; case SubtractiveBlending: gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); break; case MultiplyBlending: gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA); break; default: console.error("THREE.WebGLState: Invalid blending: ", blending); break; } } else { switch (blending) { case NormalBlending: gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); break; case AdditiveBlending: gl.blendFunc(gl.SRC_ALPHA, gl.ONE); break; case SubtractiveBlending: gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); break; case MultiplyBlending: gl.blendFunc(gl.ZERO, gl.SRC_COLOR); break; default: console.error("THREE.WebGLState: Invalid blending: ", blending); break; } } currentBlendSrc = null; currentBlendDst = null; currentBlendSrcAlpha = null; currentBlendDstAlpha = null; currentBlendColor.set(0, 0, 0); currentBlendAlpha = 0; currentBlending = blending; currentPremultipledAlpha = premultipliedAlpha; } return; } blendEquationAlpha = blendEquationAlpha || blendEquation; blendSrcAlpha = blendSrcAlpha || blendSrc; blendDstAlpha = blendDstAlpha || blendDst; if (blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha) { gl.blendEquationSeparate(equationToGL2[blendEquation], equationToGL2[blendEquationAlpha]); currentBlendEquation = blendEquation; currentBlendEquationAlpha = blendEquationAlpha; } if (blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha) { gl.blendFuncSeparate(factorToGL2[blendSrc], factorToGL2[blendDst], factorToGL2[blendSrcAlpha], factorToGL2[blendDstAlpha]); currentBlendSrc = blendSrc; currentBlendDst = blendDst; currentBlendSrcAlpha = blendSrcAlpha; currentBlendDstAlpha = blendDstAlpha; } if (blendColor.equals(currentBlendColor) === false || blendAlpha !== currentBlendAlpha) { gl.blendColor(blendColor.r, blendColor.g, blendColor.b, blendAlpha); currentBlendColor.copy(blendColor); currentBlendAlpha = blendAlpha; } currentBlending = blending; currentPremultipledAlpha = false; } function setMaterial(material, frontFaceCW) { material.side === DoubleSide ? disable(gl.CULL_FACE) : enable(gl.CULL_FACE); 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.blendColor, material.blendAlpha, 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(gl.SAMPLE_ALPHA_TO_COVERAGE) : disable(gl.SAMPLE_ALPHA_TO_COVERAGE); } function setFlipSided(flipSided) { if (currentFlipSided !== flipSided) { if (flipSided) { gl.frontFace(gl.CW); } else { gl.frontFace(gl.CCW); } currentFlipSided = flipSided; } } function setCullFace(cullFace) { if (cullFace !== CullFaceNone) { enable(gl.CULL_FACE); if (cullFace !== currentCullFace) { if (cullFace === CullFaceBack) { gl.cullFace(gl.BACK); } else if (cullFace === CullFaceFront) { gl.cullFace(gl.FRONT); } else { gl.cullFace(gl.FRONT_AND_BACK); } } } else { disable(gl.CULL_FACE); } currentCullFace = cullFace; } function setLineWidth(width) { if (width !== currentLineWidth) { if (lineWidthAvailable) gl.lineWidth(width); currentLineWidth = width; } } function setPolygonOffset(polygonOffset, factor, units) { if (polygonOffset) { enable(gl.POLYGON_OFFSET_FILL); if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) { gl.polygonOffset(factor, units); currentPolygonOffsetFactor = factor; currentPolygonOffsetUnits = units; } } else { disable(gl.POLYGON_OFFSET_FILL); } } function setScissorTest(scissorTest) { if (scissorTest) { enable(gl.SCISSOR_TEST); } else { disable(gl.SCISSOR_TEST); } } function activeTexture(webglSlot) { if (webglSlot === void 0) webglSlot = gl.TEXTURE0 + maxTextures - 1; if (currentTextureSlot !== webglSlot) { gl.activeTexture(webglSlot); currentTextureSlot = webglSlot; } } function bindTexture(webglType, webglTexture, webglSlot) { if (webglSlot === void 0) { if (currentTextureSlot === null) { webglSlot = gl.TEXTURE0 + maxTextures - 1; } else { webglSlot = currentTextureSlot; } } let boundTexture = currentBoundTextures[webglSlot]; if (boundTexture === void 0) { boundTexture = { type: void 0, texture: void 0 }; currentBoundTextures[webglSlot] = boundTexture; } if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) { if (currentTextureSlot !== webglSlot) { gl.activeTexture(webglSlot); currentTextureSlot = webglSlot; } 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 compressedTexImage3D() { try { gl.compressedTexImage3D.apply(gl, arguments); } catch (error) { console.error("THREE.WebGLState:", error); } } function texSubImage2D() { try { gl.texSubImage2D.apply(gl, arguments); } catch (error) { console.error("THREE.WebGLState:", error); } } function texSubImage3D() { try { gl.texSubImage3D.apply(gl, arguments); } catch (error) { console.error("THREE.WebGLState:", error); } } function compressedTexSubImage2D() { try { gl.compressedTexSubImage2D.apply(gl, arguments); } catch (error) { console.error("THREE.WebGLState:", error); } } function compressedTexSubImage3D() { try { gl.compressedTexSubImage3D.apply(gl, arguments); } catch (error) { console.error("THREE.WebGLState:", error); } } function texStorage2D() { try { gl.texStorage2D.apply(gl, arguments); } catch (error) { console.error("THREE.WebGLState:", error); } } function texStorage3D() { try { gl.texStorage3D.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 viewport2(viewport3) { if (currentViewport.equals(viewport3) === false) { gl.viewport(viewport3.x, viewport3.y, viewport3.z, viewport3.w); currentViewport.copy(viewport3); } } function updateUBOMapping(uniformsGroup, program) { let mapping = uboProgramMap.get(program); if (mapping === void 0) { mapping = /* @__PURE__ */ new WeakMap(); uboProgramMap.set(program, mapping); } let blockIndex = mapping.get(uniformsGroup); if (blockIndex === void 0) { blockIndex = gl.getUniformBlockIndex(program, uniformsGroup.name); mapping.set(uniformsGroup, blockIndex); } } function uniformBlockBinding(uniformsGroup, program) { const mapping = uboProgramMap.get(program); const blockIndex = mapping.get(uniformsGroup); if (uboBindings.get(program) !== blockIndex) { gl.uniformBlockBinding(program, blockIndex, uniformsGroup.__bindingPointIndex); uboBindings.set(program, blockIndex); } } function reset() { gl.disable(gl.BLEND); gl.disable(gl.CULL_FACE); gl.disable(gl.DEPTH_TEST); gl.disable(gl.POLYGON_OFFSET_FILL); gl.disable(gl.SCISSOR_TEST); gl.disable(gl.STENCIL_TEST); gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE); gl.blendEquation(gl.FUNC_ADD); gl.blendFunc(gl.ONE, gl.ZERO); gl.blendFuncSeparate(gl.ONE, gl.ZERO, gl.ONE, gl.ZERO); gl.blendColor(0, 0, 0, 0); gl.colorMask(true, true, true, true); gl.clearColor(0, 0, 0, 0); gl.depthMask(true); gl.depthFunc(gl.LESS); depthBuffer.setReversed(false); gl.clearDepth(1); gl.stencilMask(4294967295); gl.stencilFunc(gl.ALWAYS, 0, 4294967295); gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); gl.clearStencil(0); gl.cullFace(gl.BACK); gl.frontFace(gl.CCW); gl.polygonOffset(0, 0); gl.activeTexture(gl.TEXTURE0); gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); gl.bindFramebuffer(gl.READ_FRAMEBUFFER, 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 = {}; currentBoundFramebuffers = {}; currentDrawbuffers = /* @__PURE__ */ new WeakMap(); defaultDrawbuffers = []; currentProgram = null; currentBlendingEnabled = false; currentBlending = null; currentBlendEquation = null; currentBlendSrc = null; currentBlendDst = null; currentBlendEquationAlpha = null; currentBlendSrcAlpha = null; currentBlendDstAlpha = null; currentBlendColor = new Color(0, 0, 0); currentBlendAlpha = 0; 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, drawBuffers, useProgram, setBlending, setMaterial, setFlipSided, setCullFace, setLineWidth, setPolygonOffset, setScissorTest, activeTexture, bindTexture, unbindTexture, compressedTexImage2D, compressedTexImage3D, texImage2D, texImage3D, updateUBOMapping, uniformBlockBinding, texStorage2D, texStorage3D, texSubImage2D, texSubImage3D, compressedTexSubImage2D, compressedTexSubImage3D, scissor, viewport: viewport2, reset }; } function getByteLength(width, height, format2, type) { const typeByteLength = getTextureTypeByteLength(type); switch (format2) { // https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml case AlphaFormat: return width * height; case LuminanceFormat: return width * height; case LuminanceAlphaFormat: return width * height * 2; case RedFormat: return width * height / typeByteLength.components * typeByteLength.byteLength; case RedIntegerFormat: return width * height / typeByteLength.components * typeByteLength.byteLength; case RGFormat: return width * height * 2 / typeByteLength.components * typeByteLength.byteLength; case RGIntegerFormat: return width * height * 2 / typeByteLength.components * typeByteLength.byteLength; case RGBFormat: return width * height * 3 / typeByteLength.components * typeByteLength.byteLength; case RGBAFormat: return width * height * 4 / typeByteLength.components * typeByteLength.byteLength; case RGBAIntegerFormat: return width * height * 4 / typeByteLength.components * typeByteLength.byteLength; // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_s3tc_srgb/ case RGB_S3TC_DXT1_Format: case RGBA_S3TC_DXT1_Format: return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8; case RGBA_S3TC_DXT3_Format: case RGBA_S3TC_DXT5_Format: return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16; // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_pvrtc/ case RGB_PVRTC_2BPPV1_Format: case RGBA_PVRTC_2BPPV1_Format: return Math.max(width, 16) * Math.max(height, 8) / 4; case RGB_PVRTC_4BPPV1_Format: case RGBA_PVRTC_4BPPV1_Format: return Math.max(width, 8) * Math.max(height, 8) / 2; // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc/ case RGB_ETC1_Format: case RGB_ETC2_Format: return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8; case RGBA_ETC2_EAC_Format: return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16; // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/ case RGBA_ASTC_4x4_Format: return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16; case RGBA_ASTC_5x4_Format: return Math.floor((width + 4) / 5) * Math.floor((height + 3) / 4) * 16; case RGBA_ASTC_5x5_Format: return Math.floor((width + 4) / 5) * Math.floor((height + 4) / 5) * 16; case RGBA_ASTC_6x5_Format: return Math.floor((width + 5) / 6) * Math.floor((height + 4) / 5) * 16; case RGBA_ASTC_6x6_Format: return Math.floor((width + 5) / 6) * Math.floor((height + 5) / 6) * 16; case RGBA_ASTC_8x5_Format: return Math.floor((width + 7) / 8) * Math.floor((height + 4) / 5) * 16; case RGBA_ASTC_8x6_Format: return Math.floor((width + 7) / 8) * Math.floor((height + 5) / 6) * 16; case RGBA_ASTC_8x8_Format: return Math.floor((width + 7) / 8) * Math.floor((height + 7) / 8) * 16; case RGBA_ASTC_10x5_Format: return Math.floor((width + 9) / 10) * Math.floor((height + 4) / 5) * 16; case RGBA_ASTC_10x6_Format: return Math.floor((width + 9) / 10) * Math.floor((height + 5) / 6) * 16; case RGBA_ASTC_10x8_Format: return Math.floor((width + 9) / 10) * Math.floor((height + 7) / 8) * 16; case RGBA_ASTC_10x10_Format: return Math.floor((width + 9) / 10) * Math.floor((height + 9) / 10) * 16; case RGBA_ASTC_12x10_Format: return Math.floor((width + 11) / 12) * Math.floor((height + 9) / 10) * 16; case RGBA_ASTC_12x12_Format: return Math.floor((width + 11) / 12) * Math.floor((height + 11) / 12) * 16; // https://registry.khronos.org/webgl/extensions/EXT_texture_compression_bptc/ case RGBA_BPTC_Format: case RGB_BPTC_SIGNED_Format: case RGB_BPTC_UNSIGNED_Format: return Math.ceil(width / 4) * Math.ceil(height / 4) * 16; // https://registry.khronos.org/webgl/extensions/EXT_texture_compression_rgtc/ case RED_RGTC1_Format: case SIGNED_RED_RGTC1_Format: return Math.ceil(width / 4) * Math.ceil(height / 4) * 8; case RED_GREEN_RGTC2_Format: case SIGNED_RED_GREEN_RGTC2_Format: return Math.ceil(width / 4) * Math.ceil(height / 4) * 16; } throw new Error( `Unable to determine texture byte length for ${format2} format.` ); } function getTextureTypeByteLength(type) { switch (type) { case UnsignedByteType: case ByteType: return { byteLength: 1, components: 1 }; case UnsignedShortType: case ShortType: case HalfFloatType: return { byteLength: 2, components: 1 }; case UnsignedShort4444Type: case UnsignedShort5551Type: return { byteLength: 2, components: 4 }; case UnsignedIntType: case IntType: case FloatType: return { byteLength: 4, components: 1 }; case UnsignedInt5999Type: return { byteLength: 4, components: 3 }; } throw new Error(`Unknown texture type ${type}.`); } function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info) { const multisampledRTTExt = extensions.has("WEBGL_multisampled_render_to_texture") ? extensions.get("WEBGL_multisampled_render_to_texture") : null; const supportsInvalidateFramebuffer = typeof navigator === "undefined" ? false : /OculusBrowser/g.test(navigator.userAgent); const _imageDimensions = new Vector2(); const _videoTextures = /* @__PURE__ */ new WeakMap(); let _canvas3; const _sources = /* @__PURE__ */ new WeakMap(); let useOffscreenCanvas = false; try { useOffscreenCanvas = typeof OffscreenCanvas !== "undefined" && new OffscreenCanvas(1, 1).getContext("2d") !== null; } catch (err) { } function createCanvas(width, height) { return useOffscreenCanvas ? ( // eslint-disable-next-line compat/compat new OffscreenCanvas(width, height) ) : createElementNS("canvas"); } function resizeImage(image, needsNewCanvas, maxSize) { let scale = 1; const dimensions = getDimensions(image); if (dimensions.width > maxSize || dimensions.height > maxSize) { scale = maxSize / Math.max(dimensions.width, dimensions.height); } if (scale < 1) { if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap || typeof VideoFrame !== "undefined" && image instanceof VideoFrame) { const width = Math.floor(scale * dimensions.width); const height = Math.floor(scale * dimensions.height); if (_canvas3 === void 0) _canvas3 = createCanvas(width, height); const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas3; canvas.width = width; canvas.height = height; const context2 = canvas.getContext("2d"); context2.drawImage(image, 0, 0, width, height); console.warn("THREE.WebGLRenderer: Texture has been resized from (" + dimensions.width + "x" + dimensions.height + ") to (" + width + "x" + height + ")."); return canvas; } else { if ("data" in image) { console.warn("THREE.WebGLRenderer: Image in DataTexture is too big (" + dimensions.width + "x" + dimensions.height + ")."); } return image; } } return image; } function textureNeedsGenerateMipmaps(texture2) { return texture2.generateMipmaps; } function generateMipmap(target) { _gl.generateMipmap(target); } function getTargetType(texture2) { if (texture2.isWebGLCubeRenderTarget) return _gl.TEXTURE_CUBE_MAP; if (texture2.isWebGL3DRenderTarget) return _gl.TEXTURE_3D; if (texture2.isWebGLArrayRenderTarget || texture2.isCompressedArrayTexture) return _gl.TEXTURE_2D_ARRAY; return _gl.TEXTURE_2D; } function getInternalFormat(internalFormatName, glFormat, glType, colorSpace, forceLinearTransfer = false) { 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 === _gl.RED) { if (glType === _gl.FLOAT) internalFormat = _gl.R32F; if (glType === _gl.HALF_FLOAT) internalFormat = _gl.R16F; if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8; } if (glFormat === _gl.RED_INTEGER) { if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8UI; if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.R16UI; if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.R32UI; if (glType === _gl.BYTE) internalFormat = _gl.R8I; if (glType === _gl.SHORT) internalFormat = _gl.R16I; if (glType === _gl.INT) internalFormat = _gl.R32I; } if (glFormat === _gl.RG) { if (glType === _gl.FLOAT) internalFormat = _gl.RG32F; if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RG16F; if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RG8; } if (glFormat === _gl.RG_INTEGER) { if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RG8UI; if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.RG16UI; if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.RG32UI; if (glType === _gl.BYTE) internalFormat = _gl.RG8I; if (glType === _gl.SHORT) internalFormat = _gl.RG16I; if (glType === _gl.INT) internalFormat = _gl.RG32I; } if (glFormat === _gl.RGB_INTEGER) { if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RGB8UI; if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.RGB16UI; if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.RGB32UI; if (glType === _gl.BYTE) internalFormat = _gl.RGB8I; if (glType === _gl.SHORT) internalFormat = _gl.RGB16I; if (glType === _gl.INT) internalFormat = _gl.RGB32I; } if (glFormat === _gl.RGBA_INTEGER) { if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RGBA8UI; if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.RGBA16UI; if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.RGBA32UI; if (glType === _gl.BYTE) internalFormat = _gl.RGBA8I; if (glType === _gl.SHORT) internalFormat = _gl.RGBA16I; if (glType === _gl.INT) internalFormat = _gl.RGBA32I; } if (glFormat === _gl.RGB) { if (glType === _gl.UNSIGNED_INT_5_9_9_9_REV) internalFormat = _gl.RGB9_E5; } if (glFormat === _gl.RGBA) { const transfer = forceLinearTransfer ? LinearTransfer : ColorManagement.getTransfer(colorSpace); if (glType === _gl.FLOAT) internalFormat = _gl.RGBA32F; if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RGBA16F; if (glType === _gl.UNSIGNED_BYTE) internalFormat = transfer === SRGBTransfer ? _gl.SRGB8_ALPHA8 : _gl.RGBA8; if (glType === _gl.UNSIGNED_SHORT_4_4_4_4) internalFormat = _gl.RGBA4; if (glType === _gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = _gl.RGB5_A1; } if (internalFormat === _gl.R16F || internalFormat === _gl.R32F || internalFormat === _gl.RG16F || internalFormat === _gl.RG32F || internalFormat === _gl.RGBA16F || internalFormat === _gl.RGBA32F) { extensions.get("EXT_color_buffer_float"); } return internalFormat; } function getInternalDepthFormat(useStencil, depthType) { let glInternalFormat; if (useStencil) { if (depthType === null || depthType === UnsignedIntType || depthType === UnsignedInt248Type) { glInternalFormat = _gl.DEPTH24_STENCIL8; } else if (depthType === FloatType) { glInternalFormat = _gl.DEPTH32F_STENCIL8; } else if (depthType === UnsignedShortType) { glInternalFormat = _gl.DEPTH24_STENCIL8; console.warn("DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment."); } } else { if (depthType === null || depthType === UnsignedIntType || depthType === UnsignedInt248Type) { glInternalFormat = _gl.DEPTH_COMPONENT24; } else if (depthType === FloatType) { glInternalFormat = _gl.DEPTH_COMPONENT32F; } else if (depthType === UnsignedShortType) { glInternalFormat = _gl.DEPTH_COMPONENT16; } } return glInternalFormat; } function getMipLevels(texture2, image) { if (textureNeedsGenerateMipmaps(texture2) === true || texture2.isFramebufferTexture && texture2.minFilter !== NearestFilter && texture2.minFilter !== LinearFilter) { return Math.log2(Math.max(image.width, image.height)) + 1; } else if (texture2.mipmaps !== void 0 && texture2.mipmaps.length > 0) { return texture2.mipmaps.length; } else if (texture2.isCompressedTexture && Array.isArray(texture2.image)) { return image.mipmaps.length; } else { return 1; } } function onTextureDispose2(event) { const texture2 = event.target; texture2.removeEventListener("dispose", onTextureDispose2); deallocateTexture(texture2); if (texture2.isVideoTexture) { _videoTextures.delete(texture2); } } function onRenderTargetDispose(event) { const renderTarget = event.target; renderTarget.removeEventListener("dispose", onRenderTargetDispose); deallocateRenderTarget(renderTarget); } function deallocateTexture(texture2) { const textureProperties = properties.get(texture2); if (textureProperties.__webglInit === void 0) return; const source = texture2.source; const webglTextures = _sources.get(source); if (webglTextures) { const webglTexture = webglTextures[textureProperties.__cacheKey]; webglTexture.usedTimes--; if (webglTexture.usedTimes === 0) { deleteTexture(texture2); } if (Object.keys(webglTextures).length === 0) { _sources.delete(source); } } properties.remove(texture2); } function deleteTexture(texture2) { const textureProperties = properties.get(texture2); _gl.deleteTexture(textureProperties.__webglTexture); const source = texture2.source; const webglTextures = _sources.get(source); delete webglTextures[textureProperties.__cacheKey]; info.memory.textures--; } function deallocateRenderTarget(renderTarget) { const renderTargetProperties = properties.get(renderTarget); if (renderTarget.depthTexture) { renderTarget.depthTexture.dispose(); properties.remove(renderTarget.depthTexture); } if (renderTarget.isWebGLCubeRenderTarget) { for (let i = 0; i < 6; i++) { if (Array.isArray(renderTargetProperties.__webglFramebuffer[i])) { for (let level = 0; level < renderTargetProperties.__webglFramebuffer[i].length; level++) _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i][level]); } else { _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]); } if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]); } } else { if (Array.isArray(renderTargetProperties.__webglFramebuffer)) { for (let level = 0; level < renderTargetProperties.__webglFramebuffer.length; level++) _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[level]); } else { _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer); } if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer); if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer); if (renderTargetProperties.__webglColorRenderbuffer) { for (let i = 0; i < renderTargetProperties.__webglColorRenderbuffer.length; i++) { if (renderTargetProperties.__webglColorRenderbuffer[i]) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer[i]); } } if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer); } const textures = renderTarget.textures; for (let i = 0, il = textures.length; i < il; i++) { const attachmentProperties = properties.get(textures[i]); if (attachmentProperties.__webglTexture) { _gl.deleteTexture(attachmentProperties.__webglTexture); info.memory.textures--; } properties.remove(textures[i]); } properties.remove(renderTarget); } let textureUnits = 0; function resetTextureUnits() { textureUnits = 0; } function allocateTextureUnit() { const textureUnit = textureUnits; if (textureUnit >= capabilities.maxTextures) { console.warn("THREE.WebGLTextures: Trying to use " + textureUnit + " texture units while this GPU supports only " + capabilities.maxTextures); } textureUnits += 1; return textureUnit; } function getTextureCacheKey(texture2) { const array = []; array.push(texture2.wrapS); array.push(texture2.wrapT); array.push(texture2.wrapR || 0); array.push(texture2.magFilter); array.push(texture2.minFilter); array.push(texture2.anisotropy); array.push(texture2.internalFormat); array.push(texture2.format); array.push(texture2.type); array.push(texture2.generateMipmaps); array.push(texture2.premultiplyAlpha); array.push(texture2.flipY); array.push(texture2.unpackAlignment); array.push(texture2.colorSpace); return array.join(); } function setTexture2D(texture2, slot) { const textureProperties = properties.get(texture2); if (texture2.isVideoTexture) updateVideoTexture(texture2); if (texture2.isRenderTargetTexture === false && texture2.version > 0 && textureProperties.__version !== texture2.version) { const image = texture2.image; if (image === null) { console.warn("THREE.WebGLRenderer: Texture marked for update but no image data found."); } else if (image.complete === false) { console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete"); } else { uploadTexture(textureProperties, texture2, slot); return; } } state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } function setTexture2DArray(texture2, slot) { const textureProperties = properties.get(texture2); if (texture2.version > 0 && textureProperties.__version !== texture2.version) { uploadTexture(textureProperties, texture2, slot); return; } state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } function setTexture3D(texture2, slot) { const textureProperties = properties.get(texture2); if (texture2.version > 0 && textureProperties.__version !== texture2.version) { uploadTexture(textureProperties, texture2, slot); return; } state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } function setTextureCube(texture2, slot) { const textureProperties = properties.get(texture2); if (texture2.version > 0 && textureProperties.__version !== texture2.version) { uploadCubeTexture(textureProperties, texture2, slot); return; } state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); } const wrappingToGL2 = { [RepeatWrapping]: _gl.REPEAT, [ClampToEdgeWrapping]: _gl.CLAMP_TO_EDGE, [MirroredRepeatWrapping]: _gl.MIRRORED_REPEAT }; const filterToGL2 = { [NearestFilter]: _gl.NEAREST, [NearestMipmapNearestFilter]: _gl.NEAREST_MIPMAP_NEAREST, [NearestMipmapLinearFilter]: _gl.NEAREST_MIPMAP_LINEAR, [LinearFilter]: _gl.LINEAR, [LinearMipmapNearestFilter]: _gl.LINEAR_MIPMAP_NEAREST, [LinearMipmapLinearFilter]: _gl.LINEAR_MIPMAP_LINEAR }; const compareToGL2 = { [NeverCompare]: _gl.NEVER, [AlwaysCompare]: _gl.ALWAYS, [LessCompare]: _gl.LESS, [LessEqualCompare]: _gl.LEQUAL, [EqualCompare]: _gl.EQUAL, [GreaterEqualCompare]: _gl.GEQUAL, [GreaterCompare]: _gl.GREATER, [NotEqualCompare]: _gl.NOTEQUAL }; function setTextureParameters(textureType, texture2) { if (texture2.type === FloatType && extensions.has("OES_texture_float_linear") === false && (texture2.magFilter === LinearFilter || texture2.magFilter === LinearMipmapNearestFilter || texture2.magFilter === NearestMipmapLinearFilter || texture2.magFilter === LinearMipmapLinearFilter || texture2.minFilter === LinearFilter || texture2.minFilter === LinearMipmapNearestFilter || texture2.minFilter === NearestMipmapLinearFilter || texture2.minFilter === LinearMipmapLinearFilter)) { console.warn("THREE.WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device."); } _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, wrappingToGL2[texture2.wrapS]); _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, wrappingToGL2[texture2.wrapT]); if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) { _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, wrappingToGL2[texture2.wrapR]); } _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterToGL2[texture2.magFilter]); _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterToGL2[texture2.minFilter]); if (texture2.compareFunction) { _gl.texParameteri(textureType, _gl.TEXTURE_COMPARE_MODE, _gl.COMPARE_REF_TO_TEXTURE); _gl.texParameteri(textureType, _gl.TEXTURE_COMPARE_FUNC, compareToGL2[texture2.compareFunction]); } if (extensions.has("EXT_texture_filter_anisotropic") === true) { if (texture2.magFilter === NearestFilter) return; if (texture2.minFilter !== NearestMipmapLinearFilter && texture2.minFilter !== LinearMipmapLinearFilter) return; if (texture2.type === FloatType && extensions.has("OES_texture_float_linear") === false) return; if (texture2.anisotropy > 1 || properties.get(texture2).__currentAnisotropy) { const extension = extensions.get("EXT_texture_filter_anisotropic"); _gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture2.anisotropy, capabilities.getMaxAnisotropy())); properties.get(texture2).__currentAnisotropy = texture2.anisotropy; } } } function initTexture(textureProperties, texture2) { let forceUpload = false; if (textureProperties.__webglInit === void 0) { textureProperties.__webglInit = true; texture2.addEventListener("dispose", onTextureDispose2); } const source = texture2.source; let webglTextures = _sources.get(source); if (webglTextures === void 0) { webglTextures = {}; _sources.set(source, webglTextures); } const textureCacheKey = getTextureCacheKey(texture2); if (textureCacheKey !== textureProperties.__cacheKey) { if (webglTextures[textureCacheKey] === void 0) { webglTextures[textureCacheKey] = { texture: _gl.createTexture(), usedTimes: 0 }; info.memory.textures++; forceUpload = true; } webglTextures[textureCacheKey].usedTimes++; const webglTexture = webglTextures[textureProperties.__cacheKey]; if (webglTexture !== void 0) { webglTextures[textureProperties.__cacheKey].usedTimes--; if (webglTexture.usedTimes === 0) { deleteTexture(texture2); } } textureProperties.__cacheKey = textureCacheKey; textureProperties.__webglTexture = webglTextures[textureCacheKey].texture; } return forceUpload; } function uploadTexture(textureProperties, texture2, slot) { let textureType = _gl.TEXTURE_2D; if (texture2.isDataArrayTexture || texture2.isCompressedArrayTexture) textureType = _gl.TEXTURE_2D_ARRAY; if (texture2.isData3DTexture) textureType = _gl.TEXTURE_3D; const forceUpload = initTexture(textureProperties, texture2); const source = texture2.source; state.bindTexture(textureType, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); const sourceProperties = properties.get(source); if (source.version !== sourceProperties.__version || forceUpload === true) { state.activeTexture(_gl.TEXTURE0 + slot); const workingPrimaries = ColorManagement.getPrimaries(ColorManagement.workingColorSpace); const texturePrimaries = texture2.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries(texture2.colorSpace); const unpackConversion = texture2.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL; _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture2.flipY); _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture2.premultiplyAlpha); _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture2.unpackAlignment); _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion); let image = resizeImage(texture2.image, false, capabilities.maxTextureSize); image = verifyColorSpace(texture2, image); const glFormat = utils.convert(texture2.format, texture2.colorSpace); const glType = utils.convert(texture2.type); let glInternalFormat = getInternalFormat(texture2.internalFormat, glFormat, glType, texture2.colorSpace, texture2.isVideoTexture); setTextureParameters(textureType, texture2); let mipmap; const mipmaps = texture2.mipmaps; const useTexStorage = texture2.isVideoTexture !== true; const allocateMemory = sourceProperties.__version === void 0 || forceUpload === true; const dataReady = source.dataReady; const levels = getMipLevels(texture2, image); if (texture2.isDepthTexture) { glInternalFormat = getInternalDepthFormat(texture2.format === DepthStencilFormat, texture2.type); if (allocateMemory) { if (useTexStorage) { state.texStorage2D(_gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height); } else { state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null); } } } else if (texture2.isDataTexture) { if (mipmaps.length > 0) { if (useTexStorage && allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); } for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; if (useTexStorage) { if (dataReady) { state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); } } else { state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); } } texture2.generateMipmaps = false; } else { if (useTexStorage) { if (allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); } if (dataReady) { state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data); } } else { state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data); } } } else if (texture2.isCompressedTexture) { if (texture2.isCompressedArrayTexture) { if (useTexStorage && allocateMemory) { state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height, image.depth); } for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; if (texture2.format !== RGBAFormat) { if (glFormat !== null) { if (useTexStorage) { if (dataReady) { if (texture2.layerUpdates.size > 0) { const layerByteLength = getByteLength(mipmap.width, mipmap.height, texture2.format, texture2.type); for (const layerIndex of texture2.layerUpdates) { const layerData = mipmap.data.subarray( layerIndex * layerByteLength / mipmap.data.BYTES_PER_ELEMENT, (layerIndex + 1) * layerByteLength / mipmap.data.BYTES_PER_ELEMENT ); state.compressedTexSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, layerIndex, mipmap.width, mipmap.height, 1, glFormat, layerData); } texture2.clearLayerUpdates(); } else { state.compressedTexSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data); } } } else { state.compressedTexImage3D(_gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, mipmap.data, 0, 0); } } else { console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"); } } else { if (useTexStorage) { if (dataReady) { state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data); } } else { state.texImage3D(_gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data); } } } } else { if (useTexStorage && allocateMemory) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); } for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; if (texture2.format !== RGBAFormat) { if (glFormat !== null) { if (useTexStorage) { if (dataReady) { state.compressedTexSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); } } else { state.compressedTexImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); } } else { console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"); } } else { if (useTexStorage) { if (dataReady) { state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); } } else { state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); } } } } } else if (texture2.isDataArrayTexture) { if (useTexStorage) { if (allocateMemory) { state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth); } if (dataReady) { if (texture2.layerUpdates.size > 0) { const layerByteLength = getByteLength(image.width, image.height, texture2.format, texture2.type); for (const layerIndex of texture2.layerUpdates) { const layerData = image.data.subarray( layerIndex * layerByteLength / image.data.BYTES_PER_ELEMENT, (layerIndex + 1) * layerByteLength / image.data.BYTES_PER_ELEMENT ); state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, layerIndex, image.width, image.height, 1, glFormat, glType, layerData); } texture2.clearLayerUpdates(); } else { state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); } } } else { state.texImage3D(_gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); } } else if (texture2.isData3DTexture) { if (useTexStorage) { if (allocateMemory) { state.texStorage3D(_gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth); } if (dataReady) { state.texSubImage3D(_gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); } } else { state.texImage3D(_gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); } } else if (texture2.isFramebufferTexture) { if (allocateMemory) { if (useTexStorage) { state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); } else { let width = image.width, height = image.height; for (let i = 0; i < levels; i++) { state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, width, height, 0, glFormat, glType, null); width >>= 1; height >>= 1; } } } } else { if (mipmaps.length > 0) { if (useTexStorage && allocateMemory) { const dimensions = getDimensions(mipmaps[0]); state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, dimensions.width, dimensions.height); } for (let i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; if (useTexStorage) { if (dataReady) { state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap); } } else { state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap); } } texture2.generateMipmaps = false; } else { if (useTexStorage) { if (allocateMemory) { const dimensions = getDimensions(image); state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, dimensions.width, dimensions.height); } if (dataReady) { state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image); } } else { state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image); } } } if (textureNeedsGenerateMipmaps(texture2)) { generateMipmap(textureType); } sourceProperties.__version = source.version; if (texture2.onUpdate) texture2.onUpdate(texture2); } textureProperties.__version = texture2.version; } function uploadCubeTexture(textureProperties, texture2, slot) { if (texture2.image.length !== 6) return; const forceUpload = initTexture(textureProperties, texture2); const source = texture2.source; state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot); const sourceProperties = properties.get(source); if (source.version !== sourceProperties.__version || forceUpload === true) { state.activeTexture(_gl.TEXTURE0 + slot); const workingPrimaries = ColorManagement.getPrimaries(ColorManagement.workingColorSpace); const texturePrimaries = texture2.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries(texture2.colorSpace); const unpackConversion = texture2.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL; _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture2.flipY); _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture2.premultiplyAlpha); _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture2.unpackAlignment); _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion); const isCompressed = texture2.isCompressedTexture || texture2.image[0].isCompressedTexture; const isDataTexture = texture2.image[0] && texture2.image[0].isDataTexture; const cubeImage = []; for (let i = 0; i < 6; i++) { if (!isCompressed && !isDataTexture) { cubeImage[i] = resizeImage(texture2.image[i], true, capabilities.maxCubemapSize); } else { cubeImage[i] = isDataTexture ? texture2.image[i].image : texture2.image[i]; } cubeImage[i] = verifyColorSpace(texture2, cubeImage[i]); } const image = cubeImage[0], glFormat = utils.convert(texture2.format, texture2.colorSpace), glType = utils.convert(texture2.type), glInternalFormat = getInternalFormat(texture2.internalFormat, glFormat, glType, texture2.colorSpace); const useTexStorage = texture2.isVideoTexture !== true; const allocateMemory = sourceProperties.__version === void 0 || forceUpload === true; const dataReady = source.dataReady; let levels = getMipLevels(texture2, image); setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture2); let mipmaps; if (isCompressed) { if (useTexStorage && allocateMemory) { state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height); } for (let i = 0; i < 6; i++) { mipmaps = cubeImage[i].mipmaps; for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; if (texture2.format !== RGBAFormat) { if (glFormat !== null) { if (useTexStorage) { if (dataReady) { state.compressedTexSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); } } else { state.compressedTexImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + 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 { if (useTexStorage) { if (dataReady) { state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); } } else { state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); } } } } } else { mipmaps = texture2.mipmaps; if (useTexStorage && allocateMemory) { if (mipmaps.length > 0) levels++; const dimensions = getDimensions(cubeImage[0]); state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, dimensions.width, dimensions.height); } for (let i = 0; i < 6; i++) { if (isDataTexture) { if (useTexStorage) { if (dataReady) { state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[i].width, cubeImage[i].height, glFormat, glType, cubeImage[i].data); } } else { state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + 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; if (useTexStorage) { if (dataReady) { state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data); } } else { state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data); } } } else { if (useTexStorage) { if (dataReady) { state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]); } } else { state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); } for (let j = 0; j < mipmaps.length; j++) { const mipmap = mipmaps[j]; if (useTexStorage) { if (dataReady) { state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]); } } else { state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]); } } } } } if (textureNeedsGenerateMipmaps(texture2)) { generateMipmap(_gl.TEXTURE_CUBE_MAP); } sourceProperties.__version = source.version; if (texture2.onUpdate) texture2.onUpdate(texture2); } textureProperties.__version = texture2.version; } function setupFrameBufferTexture(framebuffer, renderTarget, texture2, attachment, textureTarget, level) { const glFormat = utils.convert(texture2.format, texture2.colorSpace); const glType = utils.convert(texture2.type); const glInternalFormat = getInternalFormat(texture2.internalFormat, glFormat, glType, texture2.colorSpace); const renderTargetProperties = properties.get(renderTarget); const textureProperties = properties.get(texture2); textureProperties.__renderTarget = renderTarget; if (!renderTargetProperties.__hasExternalTextures) { const width = Math.max(1, renderTarget.width >> level); const height = Math.max(1, renderTarget.height >> level); if (textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY) { state.texImage3D(textureTarget, level, glInternalFormat, width, height, renderTarget.depth, 0, glFormat, glType, null); } else { state.texImage2D(textureTarget, level, glInternalFormat, width, height, 0, glFormat, glType, null); } } state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); if (useMultisampledRTT(renderTarget)) { multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, attachment, textureTarget, textureProperties.__webglTexture, 0, getRenderTargetSamples(renderTarget)); } else if (textureTarget === _gl.TEXTURE_2D || textureTarget >= _gl.TEXTURE_CUBE_MAP_POSITIVE_X && textureTarget <= _gl.TEXTURE_CUBE_MAP_NEGATIVE_Z) { _gl.framebufferTexture2D(_gl.FRAMEBUFFER, attachment, textureTarget, textureProperties.__webglTexture, level); } state.bindFramebuffer(_gl.FRAMEBUFFER, null); } function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) { _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); if (renderTarget.depthBuffer) { const depthTexture = renderTarget.depthTexture; const depthType = depthTexture && depthTexture.isDepthTexture ? depthTexture.type : null; const glInternalFormat = getInternalDepthFormat(renderTarget.stencilBuffer, depthType); const glAttachmentType = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; const samples = getRenderTargetSamples(renderTarget); const isUseMultisampledRTT = useMultisampledRTT(renderTarget); if (isUseMultisampledRTT) { multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); } else if (isMultisample) { _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); } else { _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height); } _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, glAttachmentType, _gl.RENDERBUFFER, renderbuffer); } else { const textures = renderTarget.textures; for (let i = 0; i < textures.length; i++) { const texture2 = textures[i]; const glFormat = utils.convert(texture2.format, texture2.colorSpace); const glType = utils.convert(texture2.type); const glInternalFormat = getInternalFormat(texture2.internalFormat, glFormat, glType, texture2.colorSpace); const samples = getRenderTargetSamples(renderTarget); if (isMultisample && useMultisampledRTT(renderTarget) === false) { _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); } else if (useMultisampledRTT(renderTarget)) { multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); } else { _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height); } } } _gl.bindRenderbuffer(_gl.RENDERBUFFER, 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(_gl.FRAMEBUFFER, framebuffer); if (!(renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture)) { throw new Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture"); } const textureProperties = properties.get(renderTarget.depthTexture); textureProperties.__renderTarget = renderTarget; if (!textureProperties.__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 = textureProperties.__webglTexture; const samples = getRenderTargetSamples(renderTarget); if (renderTarget.depthTexture.format === DepthFormat) { if (useMultisampledRTT(renderTarget)) { multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples); } else { _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0); } } else if (renderTarget.depthTexture.format === DepthStencilFormat) { if (useMultisampledRTT(renderTarget)) { multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples); } else { _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0); } } else { throw new Error("Unknown depthTexture format"); } } function setupDepthRenderbuffer(renderTarget) { const renderTargetProperties = properties.get(renderTarget); const isCube = renderTarget.isWebGLCubeRenderTarget === true; if (renderTargetProperties.__boundDepthTexture !== renderTarget.depthTexture) { const depthTexture = renderTarget.depthTexture; if (renderTargetProperties.__depthDisposeCallback) { renderTargetProperties.__depthDisposeCallback(); } if (depthTexture) { const disposeEvent = () => { delete renderTargetProperties.__boundDepthTexture; delete renderTargetProperties.__depthDisposeCallback; depthTexture.removeEventListener("dispose", disposeEvent); }; depthTexture.addEventListener("dispose", disposeEvent); renderTargetProperties.__depthDisposeCallback = disposeEvent; } renderTargetProperties.__boundDepthTexture = depthTexture; } if (renderTarget.depthTexture && !renderTargetProperties.__autoAllocateDepthBuffer) { 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(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[i]); if (renderTargetProperties.__webglDepthbuffer[i] === void 0) { renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer(); setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false); } else { const glAttachmentType = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; const renderbuffer = renderTargetProperties.__webglDepthbuffer[i]; _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, glAttachmentType, _gl.RENDERBUFFER, renderbuffer); } } } else { state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); if (renderTargetProperties.__webglDepthbuffer === void 0) { renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false); } else { const glAttachmentType = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; const renderbuffer = renderTargetProperties.__webglDepthbuffer; _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer); _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, glAttachmentType, _gl.RENDERBUFFER, renderbuffer); } } } state.bindFramebuffer(_gl.FRAMEBUFFER, null); } function rebindTextures(renderTarget, colorTexture, depthTexture) { const renderTargetProperties = properties.get(renderTarget); if (colorTexture !== void 0) { setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, 0); } if (depthTexture !== void 0) { setupDepthRenderbuffer(renderTarget); } } function setupRenderTarget(renderTarget) { const texture2 = renderTarget.texture; const renderTargetProperties = properties.get(renderTarget); const textureProperties = properties.get(texture2); renderTarget.addEventListener("dispose", onRenderTargetDispose); const textures = renderTarget.textures; const isCube = renderTarget.isWebGLCubeRenderTarget === true; const isMultipleRenderTargets = textures.length > 1; if (!isMultipleRenderTargets) { if (textureProperties.__webglTexture === void 0) { textureProperties.__webglTexture = _gl.createTexture(); } textureProperties.__version = texture2.version; info.memory.textures++; } if (isCube) { renderTargetProperties.__webglFramebuffer = []; for (let i = 0; i < 6; i++) { if (texture2.mipmaps && texture2.mipmaps.length > 0) { renderTargetProperties.__webglFramebuffer[i] = []; for (let level = 0; level < texture2.mipmaps.length; level++) { renderTargetProperties.__webglFramebuffer[i][level] = _gl.createFramebuffer(); } } else { renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer(); } } } else { if (texture2.mipmaps && texture2.mipmaps.length > 0) { renderTargetProperties.__webglFramebuffer = []; for (let level = 0; level < texture2.mipmaps.length; level++) { renderTargetProperties.__webglFramebuffer[level] = _gl.createFramebuffer(); } } else { renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer(); } if (isMultipleRenderTargets) { 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++; } } } if (renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) { renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); renderTargetProperties.__webglColorRenderbuffer = []; state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); for (let i = 0; i < textures.length; i++) { const texture3 = textures[i]; renderTargetProperties.__webglColorRenderbuffer[i] = _gl.createRenderbuffer(); _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); const glFormat = utils.convert(texture3.format, texture3.colorSpace); const glType = utils.convert(texture3.type); const glInternalFormat = getInternalFormat(texture3.internalFormat, glFormat, glType, texture3.colorSpace, renderTarget.isXRRenderTarget === true); const samples = getRenderTargetSamples(renderTarget); _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height); _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); } _gl.bindRenderbuffer(_gl.RENDERBUFFER, null); if (renderTarget.depthBuffer) { renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer(); setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true); } state.bindFramebuffer(_gl.FRAMEBUFFER, null); } } if (isCube) { state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture); setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture2); for (let i = 0; i < 6; i++) { if (texture2.mipmaps && texture2.mipmaps.length > 0) { for (let level = 0; level < texture2.mipmaps.length; level++) { setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i][level], renderTarget, texture2, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level); } } else { setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, texture2, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0); } } if (textureNeedsGenerateMipmaps(texture2)) { generateMipmap(_gl.TEXTURE_CUBE_MAP); } state.unbindTexture(); } else if (isMultipleRenderTargets) { for (let i = 0, il = textures.length; i < il; i++) { const attachment = textures[i]; const attachmentProperties = properties.get(attachment); state.bindTexture(_gl.TEXTURE_2D, attachmentProperties.__webglTexture); setTextureParameters(_gl.TEXTURE_2D, attachment); setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, attachment, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, 0); if (textureNeedsGenerateMipmaps(attachment)) { generateMipmap(_gl.TEXTURE_2D); } } state.unbindTexture(); } else { let glTextureType = _gl.TEXTURE_2D; if (renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget) { glTextureType = renderTarget.isWebGL3DRenderTarget ? _gl.TEXTURE_3D : _gl.TEXTURE_2D_ARRAY; } state.bindTexture(glTextureType, textureProperties.__webglTexture); setTextureParameters(glTextureType, texture2); if (texture2.mipmaps && texture2.mipmaps.length > 0) { for (let level = 0; level < texture2.mipmaps.length; level++) { setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[level], renderTarget, texture2, _gl.COLOR_ATTACHMENT0, glTextureType, level); } } else { setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture2, _gl.COLOR_ATTACHMENT0, glTextureType, 0); } if (textureNeedsGenerateMipmaps(texture2)) { generateMipmap(glTextureType); } state.unbindTexture(); } if (renderTarget.depthBuffer) { setupDepthRenderbuffer(renderTarget); } } function updateRenderTargetMipmap(renderTarget) { const textures = renderTarget.textures; for (let i = 0, il = textures.length; i < il; i++) { const texture2 = textures[i]; if (textureNeedsGenerateMipmaps(texture2)) { const targetType = getTargetType(renderTarget); const webglTexture = properties.get(texture2).__webglTexture; state.bindTexture(targetType, webglTexture); generateMipmap(targetType); state.unbindTexture(); } } } const invalidationArrayRead = []; const invalidationArrayDraw = []; function updateMultisampleRenderTarget(renderTarget) { if (renderTarget.samples > 0) { if (useMultisampledRTT(renderTarget) === false) { const textures = renderTarget.textures; const width = renderTarget.width; const height = renderTarget.height; let mask = _gl.COLOR_BUFFER_BIT; const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; const renderTargetProperties = properties.get(renderTarget); const isMultipleRenderTargets = textures.length > 1; if (isMultipleRenderTargets) { for (let i = 0; i < textures.length; i++) { state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, null); state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, null, 0); } } state.bindFramebuffer(_gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); for (let i = 0; i < textures.length; i++) { if (renderTarget.resolveDepthBuffer) { if (renderTarget.depthBuffer) mask |= _gl.DEPTH_BUFFER_BIT; if (renderTarget.stencilBuffer && renderTarget.resolveStencilBuffer) mask |= _gl.STENCIL_BUFFER_BIT; } if (isMultipleRenderTargets) { _gl.framebufferRenderbuffer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); const webglTexture = properties.get(textures[i]).__webglTexture; _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, webglTexture, 0); } _gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST); if (supportsInvalidateFramebuffer === true) { invalidationArrayRead.length = 0; invalidationArrayDraw.length = 0; invalidationArrayRead.push(_gl.COLOR_ATTACHMENT0 + i); if (renderTarget.depthBuffer && renderTarget.resolveDepthBuffer === false) { invalidationArrayRead.push(depthStyle); invalidationArrayDraw.push(depthStyle); _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, invalidationArrayDraw); } _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, invalidationArrayRead); } } state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null); state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null); if (isMultipleRenderTargets) { for (let i = 0; i < textures.length; i++) { state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]); const webglTexture = properties.get(textures[i]).__webglTexture; state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer); _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, webglTexture, 0); } } state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer); } else { if (renderTarget.depthBuffer && renderTarget.resolveDepthBuffer === false && supportsInvalidateFramebuffer) { const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT; _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [depthStyle]); } } } } function getRenderTargetSamples(renderTarget) { return Math.min(capabilities.maxSamples, renderTarget.samples); } function useMultisampledRTT(renderTarget) { const renderTargetProperties = properties.get(renderTarget); return renderTarget.samples > 0 && extensions.has("WEBGL_multisampled_render_to_texture") === true && renderTargetProperties.__useRenderToTexture !== false; } function updateVideoTexture(texture2) { const frame2 = info.render.frame; if (_videoTextures.get(texture2) !== frame2) { _videoTextures.set(texture2, frame2); texture2.update(); } } function verifyColorSpace(texture2, image) { const colorSpace = texture2.colorSpace; const format2 = texture2.format; const type = texture2.type; if (texture2.isCompressedTexture === true || texture2.isVideoTexture === true) return image; if (colorSpace !== LinearSRGBColorSpace && colorSpace !== NoColorSpace) { if (ColorManagement.getTransfer(colorSpace) === SRGBTransfer) { if (format2 !== RGBAFormat || type !== UnsignedByteType) { console.warn("THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType."); } } else { console.error("THREE.WebGLTextures: Unsupported texture color space:", colorSpace); } } return image; } function getDimensions(image) { if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement) { _imageDimensions.width = image.naturalWidth || image.width; _imageDimensions.height = image.naturalHeight || image.height; } else if (typeof VideoFrame !== "undefined" && image instanceof VideoFrame) { _imageDimensions.width = image.displayWidth; _imageDimensions.height = image.displayHeight; } else { _imageDimensions.width = image.width; _imageDimensions.height = image.height; } return _imageDimensions; } this.allocateTextureUnit = allocateTextureUnit; this.resetTextureUnits = resetTextureUnits; this.setTexture2D = setTexture2D; this.setTexture2DArray = setTexture2DArray; this.setTexture3D = setTexture3D; this.setTextureCube = setTextureCube; this.rebindTextures = rebindTextures; this.setupRenderTarget = setupRenderTarget; this.updateRenderTargetMipmap = updateRenderTargetMipmap; this.updateMultisampleRenderTarget = updateMultisampleRenderTarget; this.setupDepthRenderbuffer = setupDepthRenderbuffer; this.setupFrameBufferTexture = setupFrameBufferTexture; this.useMultisampledRTT = useMultisampledRTT; } function WebGLUtils(gl, extensions) { function convert2(p, colorSpace = NoColorSpace) { let extension; const transfer = ColorManagement.getTransfer(colorSpace); if (p === UnsignedByteType) return gl.UNSIGNED_BYTE; if (p === UnsignedShort4444Type) return gl.UNSIGNED_SHORT_4_4_4_4; if (p === UnsignedShort5551Type) return gl.UNSIGNED_SHORT_5_5_5_1; if (p === UnsignedInt5999Type) return gl.UNSIGNED_INT_5_9_9_9_REV; if (p === ByteType) return gl.BYTE; if (p === ShortType) return gl.SHORT; if (p === UnsignedShortType) return gl.UNSIGNED_SHORT; if (p === IntType) return gl.INT; if (p === UnsignedIntType) return gl.UNSIGNED_INT; if (p === FloatType) return gl.FLOAT; if (p === HalfFloatType) return gl.HALF_FLOAT; if (p === AlphaFormat) return gl.ALPHA; if (p === RGBFormat) return gl.RGB; if (p === RGBAFormat) return gl.RGBA; if (p === LuminanceFormat) return gl.LUMINANCE; if (p === LuminanceAlphaFormat) return gl.LUMINANCE_ALPHA; if (p === DepthFormat) return gl.DEPTH_COMPONENT; if (p === DepthStencilFormat) return gl.DEPTH_STENCIL; if (p === RedFormat) return gl.RED; if (p === RedIntegerFormat) return gl.RED_INTEGER; if (p === RGFormat) return gl.RG; if (p === RGIntegerFormat) return gl.RG_INTEGER; if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER; if (p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) { if (transfer === SRGBTransfer) { extension = extensions.get("WEBGL_compressed_texture_s3tc_srgb"); if (extension !== null) { if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT; if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; } else { return null; } } else { extension = extensions.get("WEBGL_compressed_texture_s3tc"); if (extension !== null) { if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; } else { return null; } } } if (p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format) { extension = extensions.get("WEBGL_compressed_texture_pvrtc"); if (extension !== null) { if (p === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; if (p === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; if (p === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; if (p === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; } else { return null; } } if (p === RGB_ETC1_Format || p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format) { extension = extensions.get("WEBGL_compressed_texture_etc"); if (extension !== null) { if (p === RGB_ETC1_Format || p === RGB_ETC2_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2; if (p === RGBA_ETC2_EAC_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC; } else { return null; } } if (p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format) { extension = extensions.get("WEBGL_compressed_texture_astc"); if (extension !== null) { if (p === RGBA_ASTC_4x4_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR; if (p === RGBA_ASTC_5x4_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR; if (p === RGBA_ASTC_5x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR; if (p === RGBA_ASTC_6x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR; if (p === RGBA_ASTC_6x6_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR; if (p === RGBA_ASTC_8x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR; if (p === RGBA_ASTC_8x6_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR; if (p === RGBA_ASTC_8x8_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR; if (p === RGBA_ASTC_10x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR; if (p === RGBA_ASTC_10x6_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR; if (p === RGBA_ASTC_10x8_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR; if (p === RGBA_ASTC_10x10_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR; if (p === RGBA_ASTC_12x10_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR; if (p === RGBA_ASTC_12x12_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR; } else { return null; } } if (p === RGBA_BPTC_Format || p === RGB_BPTC_SIGNED_Format || p === RGB_BPTC_UNSIGNED_Format) { extension = extensions.get("EXT_texture_compression_bptc"); if (extension !== null) { if (p === RGBA_BPTC_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT; if (p === RGB_BPTC_SIGNED_Format) return extension.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT; if (p === RGB_BPTC_UNSIGNED_Format) return extension.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT; } else { return null; } } if (p === RED_RGTC1_Format || p === SIGNED_RED_RGTC1_Format || p === RED_GREEN_RGTC2_Format || p === SIGNED_RED_GREEN_RGTC2_Format) { extension = extensions.get("EXT_texture_compression_rgtc"); if (extension !== null) { if (p === RGBA_BPTC_Format) return extension.COMPRESSED_RED_RGTC1_EXT; if (p === SIGNED_RED_RGTC1_Format) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT; if (p === RED_GREEN_RGTC2_Format) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT; if (p === SIGNED_RED_GREEN_RGTC2_Format) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT; } else { return null; } } if (p === UnsignedInt248Type) return gl.UNSIGNED_INT_24_8; return gl[p] !== void 0 ? gl[p] : null; } return { convert: convert2 }; } var ArrayCamera = class extends PerspectiveCamera { constructor(array = []) { super(); this.isArrayCamera = true; this.cameras = array; } }; var Group = class extends Object3D { constructor() { super(); this.isGroup = true; this.type = "Group"; } }; 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; } connect(inputSource) { if (inputSource && inputSource.hand) { const hand = this._hand; if (hand) { for (const inputjoint of inputSource.hand.values()) { this._getHandJoint(hand, inputjoint); } } } this.dispatchEvent({ type: "connected", data: inputSource }); 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, frame2, referenceSpace) { let inputPose = null; let gripPose = null; let handPose = null; const targetRay = this._targetRay; const grip = this._grip; const hand = this._hand; if (inputSource && frame2.session.visibilityState !== "visible-blurred") { if (hand && inputSource.hand) { handPose = true; for (const inputjoint of inputSource.hand.values()) { const jointPose = frame2.getJointPose(inputjoint, referenceSpace); const joint = this._getHandJoint(hand, inputjoint); if (jointPose !== null) { joint.matrix.fromArray(jointPose.transform.matrix); joint.matrix.decompose(joint.position, joint.rotation, joint.scale); joint.matrixWorldNeedsUpdate = true; joint.jointRadius = jointPose.radius; } joint.visible = jointPose !== null; } const indexTip = hand.joints["index-finger-tip"]; const thumbTip = hand.joints["thumb-tip"]; const distance2 = indexTip.position.distanceTo(thumbTip.position); const distanceToPinch = 0.02; const threshold = 5e-3; if (hand.inputState.pinching && distance2 > distanceToPinch + threshold) { hand.inputState.pinching = false; this.dispatchEvent({ type: "pinchend", handedness: inputSource.handedness, target: this }); } else if (!hand.inputState.pinching && distance2 <= distanceToPinch - threshold) { hand.inputState.pinching = true; this.dispatchEvent({ type: "pinchstart", handedness: inputSource.handedness, target: this }); } } else { if (grip !== null && inputSource.gripSpace) { gripPose = frame2.getPose(inputSource.gripSpace, referenceSpace); if (gripPose !== null) { grip.matrix.fromArray(gripPose.transform.matrix); grip.matrix.decompose(grip.position, grip.rotation, grip.scale); grip.matrixWorldNeedsUpdate = true; 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) { inputPose = frame2.getPose(inputSource.targetRaySpace, referenceSpace); if (inputPose === null && gripPose !== null) { inputPose = gripPose; } if (inputPose !== null) { targetRay.matrix.fromArray(inputPose.transform.matrix); targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale); targetRay.matrixWorldNeedsUpdate = true; 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 (targetRay !== null) { targetRay.visible = inputPose !== null; } if (grip !== null) { grip.visible = gripPose !== null; } if (hand !== null) { hand.visible = handPose !== null; } return this; } // private method _getHandJoint(hand, inputjoint) { if (hand.joints[inputjoint.jointName] === void 0) { const joint = new Group(); joint.matrixAutoUpdate = false; joint.visible = false; hand.joints[inputjoint.jointName] = joint; hand.add(joint); } return hand.joints[inputjoint.jointName]; } }; var _occlusion_vertex = ` void main() { gl_Position = vec4( position, 1.0 ); }`; var _occlusion_fragment = ` uniform sampler2DArray depthColor; uniform float depthWidth; uniform float depthHeight; void main() { vec2 coord = vec2( gl_FragCoord.x / depthWidth, gl_FragCoord.y / depthHeight ); if ( coord.x >= 1.0 ) { gl_FragDepth = texture( depthColor, vec3( coord.x - 1.0, coord.y, 1 ) ).r; } else { gl_FragDepth = texture( depthColor, vec3( coord.x, coord.y, 0 ) ).r; } }`; var WebXRDepthSensing = class { constructor() { this.texture = null; this.mesh = null; this.depthNear = 0; this.depthFar = 0; } init(renderer3, depthData, renderState) { if (this.texture === null) { const texture2 = new Texture(); const texProps = renderer3.properties.get(texture2); texProps.__webglTexture = depthData.texture; if (depthData.depthNear != renderState.depthNear || depthData.depthFar != renderState.depthFar) { this.depthNear = depthData.depthNear; this.depthFar = depthData.depthFar; } this.texture = texture2; } } getMesh(cameraXR) { if (this.texture !== null) { if (this.mesh === null) { const viewport2 = cameraXR.cameras[0].viewport; const material = new ShaderMaterial({ vertexShader: _occlusion_vertex, fragmentShader: _occlusion_fragment, uniforms: { depthColor: { value: this.texture }, depthWidth: { value: viewport2.z }, depthHeight: { value: viewport2.w } } }); this.mesh = new Mesh(new PlaneGeometry(20, 20), material); } } return this.mesh; } reset() { this.texture = null; this.mesh = null; } getDepthTexture() { return this.texture; } }; var WebXRManager = class extends EventDispatcher { constructor(renderer3, gl) { super(); const scope = this; let session = null; let framebufferScaleFactor = 1; let referenceSpace = null; let referenceSpaceType = "local-floor"; let foveation = 1; let customReferenceSpace = null; let pose = null; let glBinding = null; let glProjLayer = null; let glBaseLayer = null; let xrFrame = null; const depthSensing = new WebXRDepthSensing(); const attributes = gl.getContextAttributes(); let initialRenderTarget = null; let newRenderTarget = null; const controllers = []; const controllerInputSources = []; const currentSize = new Vector2(); let currentPixelRatio = null; const cameraL = new PerspectiveCamera(); cameraL.viewport = new Vector4(); const cameraR = new PerspectiveCamera(); cameraR.viewport = new Vector4(); const cameras = [cameraL, cameraR]; const cameraXR = new ArrayCamera(); let _currentDepthNear = null; let _currentDepthFar = null; this.cameraAutoUpdate = true; this.enabled = false; this.isPresenting = false; this.getController = function(index5) { let controller = controllers[index5]; if (controller === void 0) { controller = new WebXRController(); controllers[index5] = controller; } return controller.getTargetRaySpace(); }; this.getControllerGrip = function(index5) { let controller = controllers[index5]; if (controller === void 0) { controller = new WebXRController(); controllers[index5] = controller; } return controller.getGripSpace(); }; this.getHand = function(index5) { let controller = controllers[index5]; if (controller === void 0) { controller = new WebXRController(); controllers[index5] = controller; } return controller.getHandSpace(); }; function onSessionEvent(event) { const controllerIndex = controllerInputSources.indexOf(event.inputSource); if (controllerIndex === -1) { return; } const controller = controllers[controllerIndex]; if (controller !== void 0) { controller.update(event.inputSource, event.frame, customReferenceSpace || referenceSpace); controller.dispatchEvent({ type: event.type, data: event.inputSource }); } } function onSessionEnd() { session.removeEventListener("select", onSessionEvent); session.removeEventListener("selectstart", onSessionEvent); session.removeEventListener("selectend", onSessionEvent); session.removeEventListener("squeeze", onSessionEvent); session.removeEventListener("squeezestart", onSessionEvent); session.removeEventListener("squeezeend", onSessionEvent); session.removeEventListener("end", onSessionEnd); session.removeEventListener("inputsourceschange", onInputSourcesChange); for (let i = 0; i < controllers.length; i++) { const inputSource = controllerInputSources[i]; if (inputSource === null) continue; controllerInputSources[i] = null; controllers[i].disconnect(inputSource); } _currentDepthNear = null; _currentDepthFar = null; depthSensing.reset(); renderer3.setRenderTarget(initialRenderTarget); glBaseLayer = null; glProjLayer = null; glBinding = null; session = null; newRenderTarget = null; animation.stop(); scope.isPresenting = false; renderer3.setPixelRatio(currentPixelRatio); renderer3.setSize(currentSize.width, currentSize.height, 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 customReferenceSpace || referenceSpace; }; this.setReferenceSpace = function(space) { customReferenceSpace = space; }; 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 = async function(value) { session = value; if (session !== null) { initialRenderTarget = renderer3.getRenderTarget(); 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); if (attributes.xrCompatible !== true) { await gl.makeXRCompatible(); } currentPixelRatio = renderer3.getPixelRatio(); renderer3.getSize(currentSize); if (session.renderState.layers === void 0) { const layerInit = { antialias: attributes.antialias, alpha: true, depth: attributes.depth, stencil: attributes.stencil, framebufferScaleFactor }; glBaseLayer = new XRWebGLLayer(session, gl, layerInit); session.updateRenderState({ baseLayer: glBaseLayer }); renderer3.setPixelRatio(1); renderer3.setSize(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, false); newRenderTarget = new WebGLRenderTarget( glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, { format: RGBAFormat, type: UnsignedByteType, colorSpace: renderer3.outputColorSpace, stencilBuffer: attributes.stencil } ); } else { let depthFormat = null; let depthType = null; let glDepthFormat = null; if (attributes.depth) { glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24; depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat; depthType = attributes.stencil ? UnsignedInt248Type : UnsignedIntType; } const projectionlayerInit = { colorFormat: gl.RGBA8, depthFormat: glDepthFormat, scaleFactor: framebufferScaleFactor }; glBinding = new XRWebGLBinding(session, gl); glProjLayer = glBinding.createProjectionLayer(projectionlayerInit); session.updateRenderState({ layers: [glProjLayer] }); renderer3.setPixelRatio(1); renderer3.setSize(glProjLayer.textureWidth, glProjLayer.textureHeight, false); newRenderTarget = new WebGLRenderTarget( glProjLayer.textureWidth, glProjLayer.textureHeight, { format: RGBAFormat, type: UnsignedByteType, depthTexture: new DepthTexture(glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, void 0, void 0, void 0, void 0, void 0, void 0, depthFormat), stencilBuffer: attributes.stencil, colorSpace: renderer3.outputColorSpace, samples: attributes.antialias ? 4 : 0, resolveDepthBuffer: glProjLayer.ignoreDepthValues === false } ); } newRenderTarget.isXRRenderTarget = true; this.setFoveation(foveation); customReferenceSpace = null; referenceSpace = await session.requestReferenceSpace(referenceSpaceType); animation.setContext(session); animation.start(); scope.isPresenting = true; scope.dispatchEvent({ type: "sessionstart" }); } }; this.getEnvironmentBlendMode = function() { if (session !== null) { return session.environmentBlendMode; } }; this.getDepthTexture = function() { return depthSensing.getDepthTexture(); }; function onInputSourcesChange(event) { for (let i = 0; i < event.removed.length; i++) { const inputSource = event.removed[i]; const index5 = controllerInputSources.indexOf(inputSource); if (index5 >= 0) { controllerInputSources[index5] = null; controllers[index5].disconnect(inputSource); } } for (let i = 0; i < event.added.length; i++) { const inputSource = event.added[i]; let controllerIndex = controllerInputSources.indexOf(inputSource); if (controllerIndex === -1) { for (let i2 = 0; i2 < controllers.length; i2++) { if (i2 >= controllerInputSources.length) { controllerInputSources.push(inputSource); controllerIndex = i2; break; } else if (controllerInputSources[i2] === null) { controllerInputSources[i2] = inputSource; controllerIndex = i2; break; } } if (controllerIndex === -1) break; } const controller = controllers[controllerIndex]; if (controller) { controller.connect(inputSource); } } } const cameraLPos = new Vector3(); const cameraRPos = new Vector3(); function setProjectionFromUnion(camera3, 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(camera3.position, camera3.quaternion, camera3.scale); camera3.translateX(xOffset); camera3.translateZ(zOffset); camera3.matrixWorld.compose(camera3.position, camera3.quaternion, camera3.scale); camera3.matrixWorldInverse.copy(camera3.matrixWorld).invert(); if (projL[10] === -1) { camera3.projectionMatrix.copy(cameraL2.projectionMatrix); camera3.projectionMatrixInverse.copy(cameraL2.projectionMatrixInverse); } else { 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; camera3.projectionMatrix.makePerspective(left2, right2, top2, bottom2, near2, far2); camera3.projectionMatrixInverse.copy(camera3.projectionMatrix).invert(); } } function updateCamera(camera3, parent) { if (parent === null) { camera3.matrixWorld.copy(camera3.matrix); } else { camera3.matrixWorld.multiplyMatrices(parent.matrixWorld, camera3.matrix); } camera3.matrixWorldInverse.copy(camera3.matrixWorld).invert(); } this.updateCamera = function(camera3) { if (session === null) return; let depthNear = camera3.near; let depthFar = camera3.far; if (depthSensing.texture !== null) { if (depthSensing.depthNear > 0) depthNear = depthSensing.depthNear; if (depthSensing.depthFar > 0) depthFar = depthSensing.depthFar; } cameraXR.near = cameraR.near = cameraL.near = depthNear; cameraXR.far = cameraR.far = cameraL.far = depthFar; if (_currentDepthNear !== cameraXR.near || _currentDepthFar !== cameraXR.far) { session.updateRenderState({ depthNear: cameraXR.near, depthFar: cameraXR.far }); _currentDepthNear = cameraXR.near; _currentDepthFar = cameraXR.far; } cameraL.layers.mask = camera3.layers.mask | 2; cameraR.layers.mask = camera3.layers.mask | 4; cameraXR.layers.mask = cameraL.layers.mask | cameraR.layers.mask; const parent = camera3.parent; const cameras2 = cameraXR.cameras; updateCamera(cameraXR, parent); for (let i = 0; i < cameras2.length; i++) { updateCamera(cameras2[i], parent); } if (cameras2.length === 2) { setProjectionFromUnion(cameraXR, cameraL, cameraR); } else { cameraXR.projectionMatrix.copy(cameraL.projectionMatrix); } updateUserCamera(camera3, cameraXR, parent); }; function updateUserCamera(camera3, cameraXR2, parent) { if (parent === null) { camera3.matrix.copy(cameraXR2.matrixWorld); } else { camera3.matrix.copy(parent.matrixWorld); camera3.matrix.invert(); camera3.matrix.multiply(cameraXR2.matrixWorld); } camera3.matrix.decompose(camera3.position, camera3.quaternion, camera3.scale); camera3.updateMatrixWorld(true); camera3.projectionMatrix.copy(cameraXR2.projectionMatrix); camera3.projectionMatrixInverse.copy(cameraXR2.projectionMatrixInverse); if (camera3.isPerspectiveCamera) { camera3.fov = RAD2DEG * 2 * Math.atan(1 / camera3.projectionMatrix.elements[5]); camera3.zoom = 1; } } this.getCamera = function() { return cameraXR; }; this.getFoveation = function() { if (glProjLayer === null && glBaseLayer === null) { return void 0; } return foveation; }; this.setFoveation = function(value) { foveation = value; if (glProjLayer !== null) { glProjLayer.fixedFoveation = value; } if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== void 0) { glBaseLayer.fixedFoveation = value; } }; this.hasDepthSensing = function() { return depthSensing.texture !== null; }; this.getDepthSensingMesh = function() { return depthSensing.getMesh(cameraXR); }; let onAnimationFrameCallback = null; function onAnimationFrame(time, frame2) { pose = frame2.getViewerPose(customReferenceSpace || referenceSpace); xrFrame = frame2; if (pose !== null) { const views = pose.views; if (glBaseLayer !== null) { renderer3.setRenderTargetFramebuffer(newRenderTarget, glBaseLayer.framebuffer); renderer3.setRenderTarget(newRenderTarget); } let cameraXRNeedsUpdate = false; if (views.length !== cameraXR.cameras.length) { cameraXR.cameras.length = 0; cameraXRNeedsUpdate = true; } for (let i = 0; i < views.length; i++) { const view = views[i]; let viewport2 = null; if (glBaseLayer !== null) { viewport2 = glBaseLayer.getViewport(view); } else { const glSubImage = glBinding.getViewSubImage(glProjLayer, view); viewport2 = glSubImage.viewport; if (i === 0) { renderer3.setRenderTargetTextures( newRenderTarget, glSubImage.colorTexture, glProjLayer.ignoreDepthValues ? void 0 : glSubImage.depthStencilTexture ); renderer3.setRenderTarget(newRenderTarget); } } let camera3 = cameras[i]; if (camera3 === void 0) { camera3 = new PerspectiveCamera(); camera3.layers.enable(i); camera3.viewport = new Vector4(); cameras[i] = camera3; } camera3.matrix.fromArray(view.transform.matrix); camera3.matrix.decompose(camera3.position, camera3.quaternion, camera3.scale); camera3.projectionMatrix.fromArray(view.projectionMatrix); camera3.projectionMatrixInverse.copy(camera3.projectionMatrix).invert(); camera3.viewport.set(viewport2.x, viewport2.y, viewport2.width, viewport2.height); if (i === 0) { cameraXR.matrix.copy(camera3.matrix); cameraXR.matrix.decompose(cameraXR.position, cameraXR.quaternion, cameraXR.scale); } if (cameraXRNeedsUpdate === true) { cameraXR.cameras.push(camera3); } } const enabledFeatures = session.enabledFeatures; if (enabledFeatures && enabledFeatures.includes("depth-sensing")) { const depthData = glBinding.getDepthInformation(views[0]); if (depthData && depthData.isValid && depthData.texture) { depthSensing.init(renderer3, depthData, session.renderState); } } } for (let i = 0; i < controllers.length; i++) { const inputSource = controllerInputSources[i]; const controller = controllers[i]; if (inputSource !== null && controller !== void 0) { controller.update(inputSource, frame2, customReferenceSpace || referenceSpace); } } if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame2); if (frame2.detectedPlanes) { scope.dispatchEvent({ type: "planesdetected", data: frame2 }); } xrFrame = null; } const animation = new WebGLAnimation(); animation.setAnimationLoop(onAnimationFrame); this.setAnimationLoop = function(callback) { onAnimationFrameCallback = callback; }; this.dispose = function() { }; } }; var _e1 = /* @__PURE__ */ new Euler(); var _m1 = /* @__PURE__ */ new Matrix4(); function WebGLMaterials(renderer3, properties) { function refreshTransformUniform(map, uniform2) { if (map.matrixAutoUpdate === true) { map.updateMatrix(); } uniform2.value.copy(map.matrix); } function refreshFogUniforms(uniforms, fog) { fog.color.getRGB(uniforms.fogColor.value, getUnlitUniformColorSpace(renderer3)); 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); } 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); refreshUniformsStandard(uniforms, material); if (material.isMeshPhysicalMaterial) { refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); } } else if (material.isMeshMatcapMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsMatcap(uniforms, material); } else if (material.isMeshDepthMaterial) { refreshUniformsCommon(uniforms, material); } else if (material.isMeshDistanceMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsDistance(uniforms, material); } else if (material.isMeshNormalMaterial) { refreshUniformsCommon(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; refreshTransformUniform(material.map, uniforms.mapTransform); } if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; refreshTransformUniform(material.alphaMap, uniforms.alphaMapTransform); } if (material.bumpMap) { uniforms.bumpMap.value = material.bumpMap; refreshTransformUniform(material.bumpMap, uniforms.bumpMapTransform); uniforms.bumpScale.value = material.bumpScale; if (material.side === BackSide) { uniforms.bumpScale.value *= -1; } } if (material.normalMap) { uniforms.normalMap.value = material.normalMap; refreshTransformUniform(material.normalMap, uniforms.normalMapTransform); uniforms.normalScale.value.copy(material.normalScale); if (material.side === BackSide) { uniforms.normalScale.value.negate(); } } if (material.displacementMap) { uniforms.displacementMap.value = material.displacementMap; refreshTransformUniform(material.displacementMap, uniforms.displacementMapTransform); uniforms.displacementScale.value = material.displacementScale; uniforms.displacementBias.value = material.displacementBias; } if (material.emissiveMap) { uniforms.emissiveMap.value = material.emissiveMap; refreshTransformUniform(material.emissiveMap, uniforms.emissiveMapTransform); } if (material.specularMap) { uniforms.specularMap.value = material.specularMap; refreshTransformUniform(material.specularMap, uniforms.specularMapTransform); } if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; } const materialProperties = properties.get(material); const envMap = materialProperties.envMap; const envMapRotation = materialProperties.envMapRotation; if (envMap) { uniforms.envMap.value = envMap; _e1.copy(envMapRotation); _e1.x *= -1; _e1.y *= -1; _e1.z *= -1; if (envMap.isCubeTexture && envMap.isRenderTargetTexture === false) { _e1.y *= -1; _e1.z *= -1; } uniforms.envMapRotation.value.setFromMatrix4(_m1.makeRotationFromEuler(_e1)); 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; } if (material.lightMap) { uniforms.lightMap.value = material.lightMap; uniforms.lightMapIntensity.value = material.lightMapIntensity; refreshTransformUniform(material.lightMap, uniforms.lightMapTransform); } if (material.aoMap) { uniforms.aoMap.value = material.aoMap; uniforms.aoMapIntensity.value = material.aoMapIntensity; refreshTransformUniform(material.aoMap, uniforms.aoMapTransform); } } function refreshUniformsLine(uniforms, material) { uniforms.diffuse.value.copy(material.color); uniforms.opacity.value = material.opacity; if (material.map) { uniforms.map.value = material.map; refreshTransformUniform(material.map, uniforms.mapTransform); } } 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; refreshTransformUniform(material.map, uniforms.uvTransform); } if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; refreshTransformUniform(material.alphaMap, uniforms.alphaMapTransform); } if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; } } 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; refreshTransformUniform(material.map, uniforms.mapTransform); } if (material.alphaMap) { uniforms.alphaMap.value = material.alphaMap; refreshTransformUniform(material.alphaMap, uniforms.alphaMapTransform); } if (material.alphaTest > 0) { uniforms.alphaTest.value = material.alphaTest; } } function refreshUniformsPhong(uniforms, material) { uniforms.specular.value.copy(material.specular); uniforms.shininess.value = Math.max(material.shininess, 1e-4); } function refreshUniformsToon(uniforms, material) { if (material.gradientMap) { uniforms.gradientMap.value = material.gradientMap; } } function refreshUniformsStandard(uniforms, material) { uniforms.metalness.value = material.metalness; if (material.metalnessMap) { uniforms.metalnessMap.value = material.metalnessMap; refreshTransformUniform(material.metalnessMap, uniforms.metalnessMapTransform); } uniforms.roughness.value = material.roughness; if (material.roughnessMap) { uniforms.roughnessMap.value = material.roughnessMap; refreshTransformUniform(material.roughnessMap, uniforms.roughnessMapTransform); } if (material.envMap) { uniforms.envMapIntensity.value = material.envMapIntensity; } } function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) { uniforms.ior.value = material.ior; if (material.sheen > 0) { uniforms.sheenColor.value.copy(material.sheenColor).multiplyScalar(material.sheen); uniforms.sheenRoughness.value = material.sheenRoughness; if (material.sheenColorMap) { uniforms.sheenColorMap.value = material.sheenColorMap; refreshTransformUniform(material.sheenColorMap, uniforms.sheenColorMapTransform); } if (material.sheenRoughnessMap) { uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap; refreshTransformUniform(material.sheenRoughnessMap, uniforms.sheenRoughnessMapTransform); } } if (material.clearcoat > 0) { uniforms.clearcoat.value = material.clearcoat; uniforms.clearcoatRoughness.value = material.clearcoatRoughness; if (material.clearcoatMap) { uniforms.clearcoatMap.value = material.clearcoatMap; refreshTransformUniform(material.clearcoatMap, uniforms.clearcoatMapTransform); } if (material.clearcoatRoughnessMap) { uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; refreshTransformUniform(material.clearcoatRoughnessMap, uniforms.clearcoatRoughnessMapTransform); } if (material.clearcoatNormalMap) { uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; refreshTransformUniform(material.clearcoatNormalMap, uniforms.clearcoatNormalMapTransform); uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale); if (material.side === BackSide) { uniforms.clearcoatNormalScale.value.negate(); } } } if (material.dispersion > 0) { uniforms.dispersion.value = material.dispersion; } if (material.iridescence > 0) { uniforms.iridescence.value = material.iridescence; uniforms.iridescenceIOR.value = material.iridescenceIOR; uniforms.iridescenceThicknessMinimum.value = material.iridescenceThicknessRange[0]; uniforms.iridescenceThicknessMaximum.value = material.iridescenceThicknessRange[1]; if (material.iridescenceMap) { uniforms.iridescenceMap.value = material.iridescenceMap; refreshTransformUniform(material.iridescenceMap, uniforms.iridescenceMapTransform); } if (material.iridescenceThicknessMap) { uniforms.iridescenceThicknessMap.value = material.iridescenceThicknessMap; refreshTransformUniform(material.iridescenceThicknessMap, uniforms.iridescenceThicknessMapTransform); } } 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; refreshTransformUniform(material.transmissionMap, uniforms.transmissionMapTransform); } uniforms.thickness.value = material.thickness; if (material.thicknessMap) { uniforms.thicknessMap.value = material.thicknessMap; refreshTransformUniform(material.thicknessMap, uniforms.thicknessMapTransform); } uniforms.attenuationDistance.value = material.attenuationDistance; uniforms.attenuationColor.value.copy(material.attenuationColor); } if (material.anisotropy > 0) { uniforms.anisotropyVector.value.set(material.anisotropy * Math.cos(material.anisotropyRotation), material.anisotropy * Math.sin(material.anisotropyRotation)); if (material.anisotropyMap) { uniforms.anisotropyMap.value = material.anisotropyMap; refreshTransformUniform(material.anisotropyMap, uniforms.anisotropyMapTransform); } } uniforms.specularIntensity.value = material.specularIntensity; uniforms.specularColor.value.copy(material.specularColor); if (material.specularColorMap) { uniforms.specularColorMap.value = material.specularColorMap; refreshTransformUniform(material.specularColorMap, uniforms.specularColorMapTransform); } if (material.specularIntensityMap) { uniforms.specularIntensityMap.value = material.specularIntensityMap; refreshTransformUniform(material.specularIntensityMap, uniforms.specularIntensityMapTransform); } } function refreshUniformsMatcap(uniforms, material) { if (material.matcap) { uniforms.matcap.value = material.matcap; } } function refreshUniformsDistance(uniforms, material) { const light = properties.get(material).light; uniforms.referencePosition.value.setFromMatrixPosition(light.matrixWorld); uniforms.nearDistance.value = light.shadow.camera.near; uniforms.farDistance.value = light.shadow.camera.far; } return { refreshFogUniforms, refreshMaterialUniforms }; } function WebGLUniformsGroups(gl, info, capabilities, state) { let buffers = {}; let updateList = {}; let allocatedBindingPoints = []; const maxBindingPoints = gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS); function bind(uniformsGroup, program) { const webglProgram = program.program; state.uniformBlockBinding(uniformsGroup, webglProgram); } function update4(uniformsGroup, program) { let buffer2 = buffers[uniformsGroup.id]; if (buffer2 === void 0) { prepareUniformsGroup(uniformsGroup); buffer2 = createBuffer(uniformsGroup); buffers[uniformsGroup.id] = buffer2; uniformsGroup.addEventListener("dispose", onUniformsGroupsDispose); } const webglProgram = program.program; state.updateUBOMapping(uniformsGroup, webglProgram); const frame2 = info.render.frame; if (updateList[uniformsGroup.id] !== frame2) { updateBufferData(uniformsGroup); updateList[uniformsGroup.id] = frame2; } } function createBuffer(uniformsGroup) { const bindingPointIndex = allocateBindingPointIndex(); uniformsGroup.__bindingPointIndex = bindingPointIndex; const buffer2 = gl.createBuffer(); const size = uniformsGroup.__size; const usage = uniformsGroup.usage; gl.bindBuffer(gl.UNIFORM_BUFFER, buffer2); gl.bufferData(gl.UNIFORM_BUFFER, size, usage); gl.bindBuffer(gl.UNIFORM_BUFFER, null); gl.bindBufferBase(gl.UNIFORM_BUFFER, bindingPointIndex, buffer2); return buffer2; } function allocateBindingPointIndex() { for (let i = 0; i < maxBindingPoints; i++) { if (allocatedBindingPoints.indexOf(i) === -1) { allocatedBindingPoints.push(i); return i; } } console.error("THREE.WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached."); return 0; } function updateBufferData(uniformsGroup) { const buffer2 = buffers[uniformsGroup.id]; const uniforms = uniformsGroup.uniforms; const cache2 = uniformsGroup.__cache; gl.bindBuffer(gl.UNIFORM_BUFFER, buffer2); for (let i = 0, il = uniforms.length; i < il; i++) { const uniformArray2 = Array.isArray(uniforms[i]) ? uniforms[i] : [uniforms[i]]; for (let j = 0, jl = uniformArray2.length; j < jl; j++) { const uniform2 = uniformArray2[j]; if (hasUniformChanged(uniform2, i, j, cache2) === true) { const offset = uniform2.__offset; const values = Array.isArray(uniform2.value) ? uniform2.value : [uniform2.value]; let arrayOffset = 0; for (let k = 0; k < values.length; k++) { const value = values[k]; const info2 = getUniformSize(value); if (typeof value === "number" || typeof value === "boolean") { uniform2.__data[0] = value; gl.bufferSubData(gl.UNIFORM_BUFFER, offset + arrayOffset, uniform2.__data); } else if (value.isMatrix3) { uniform2.__data[0] = value.elements[0]; uniform2.__data[1] = value.elements[1]; uniform2.__data[2] = value.elements[2]; uniform2.__data[3] = 0; uniform2.__data[4] = value.elements[3]; uniform2.__data[5] = value.elements[4]; uniform2.__data[6] = value.elements[5]; uniform2.__data[7] = 0; uniform2.__data[8] = value.elements[6]; uniform2.__data[9] = value.elements[7]; uniform2.__data[10] = value.elements[8]; uniform2.__data[11] = 0; } else { value.toArray(uniform2.__data, arrayOffset); arrayOffset += info2.storage / Float32Array.BYTES_PER_ELEMENT; } } gl.bufferSubData(gl.UNIFORM_BUFFER, offset, uniform2.__data); } } } gl.bindBuffer(gl.UNIFORM_BUFFER, null); } function hasUniformChanged(uniform2, index5, indexArray, cache2) { const value = uniform2.value; const indexString = index5 + "_" + indexArray; if (cache2[indexString] === void 0) { if (typeof value === "number" || typeof value === "boolean") { cache2[indexString] = value; } else { cache2[indexString] = value.clone(); } return true; } else { const cachedObject = cache2[indexString]; if (typeof value === "number" || typeof value === "boolean") { if (cachedObject !== value) { cache2[indexString] = value; return true; } } else { if (cachedObject.equals(value) === false) { cachedObject.copy(value); return true; } } } return false; } function prepareUniformsGroup(uniformsGroup) { const uniforms = uniformsGroup.uniforms; let offset = 0; const chunkSize = 16; for (let i = 0, l = uniforms.length; i < l; i++) { const uniformArray2 = Array.isArray(uniforms[i]) ? uniforms[i] : [uniforms[i]]; for (let j = 0, jl = uniformArray2.length; j < jl; j++) { const uniform2 = uniformArray2[j]; const values = Array.isArray(uniform2.value) ? uniform2.value : [uniform2.value]; for (let k = 0, kl = values.length; k < kl; k++) { const value = values[k]; const info2 = getUniformSize(value); const chunkOffset2 = offset % chunkSize; const chunkPadding = chunkOffset2 % info2.boundary; const chunkStart = chunkOffset2 + chunkPadding; offset += chunkPadding; if (chunkStart !== 0 && chunkSize - chunkStart < info2.storage) { offset += chunkSize - chunkStart; } uniform2.__data = new Float32Array(info2.storage / Float32Array.BYTES_PER_ELEMENT); uniform2.__offset = offset; offset += info2.storage; } } } const chunkOffset = offset % chunkSize; if (chunkOffset > 0) offset += chunkSize - chunkOffset; uniformsGroup.__size = offset; uniformsGroup.__cache = {}; return this; } function getUniformSize(value) { const info2 = { boundary: 0, // bytes storage: 0 // bytes }; if (typeof value === "number" || typeof value === "boolean") { info2.boundary = 4; info2.storage = 4; } else if (value.isVector2) { info2.boundary = 8; info2.storage = 8; } else if (value.isVector3 || value.isColor) { info2.boundary = 16; info2.storage = 12; } else if (value.isVector4) { info2.boundary = 16; info2.storage = 16; } else if (value.isMatrix3) { info2.boundary = 48; info2.storage = 48; } else if (value.isMatrix4) { info2.boundary = 64; info2.storage = 64; } else if (value.isTexture) { console.warn("THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group."); } else { console.warn("THREE.WebGLRenderer: Unsupported uniform value type.", value); } return info2; } function onUniformsGroupsDispose(event) { const uniformsGroup = event.target; uniformsGroup.removeEventListener("dispose", onUniformsGroupsDispose); const index5 = allocatedBindingPoints.indexOf(uniformsGroup.__bindingPointIndex); allocatedBindingPoints.splice(index5, 1); gl.deleteBuffer(buffers[uniformsGroup.id]); delete buffers[uniformsGroup.id]; delete updateList[uniformsGroup.id]; } function dispose() { for (const id2 in buffers) { gl.deleteBuffer(buffers[id2]); } allocatedBindingPoints = []; buffers = {}; updateList = {}; } return { bind, update: update4, dispose }; } var WebGLRenderer = class { constructor(parameters = {}) { const { canvas = createCanvasElement(), context: context2 = null, depth: depth2 = true, stencil = false, alpha = false, antialias = false, premultipliedAlpha = true, preserveDrawingBuffer = false, powerPreference = "default", failIfMajorPerformanceCaveat = false, reverseDepthBuffer = false } = parameters; this.isWebGLRenderer = true; let _alpha; if (context2 !== null) { if (typeof WebGLRenderingContext !== "undefined" && context2 instanceof WebGLRenderingContext) { throw new Error("THREE.WebGLRenderer: WebGL 1 is not supported since r163."); } _alpha = context2.getContextAttributes().alpha; } else { _alpha = alpha; } const uintClearColor = new Uint32Array(4); const intClearColor = new Int32Array(4); let currentRenderList = null; let currentRenderState = null; const renderListStack = []; const renderStateStack = []; this.domElement = canvas; this.debug = { /** * Enables error checking and reporting when shader programs are being compiled * @type {boolean} */ checkShaderErrors: true, /** * Callback for custom error reporting. * @type {?Function} */ onShaderError: null }; this.autoClear = true; this.autoClearColor = true; this.autoClearDepth = true; this.autoClearStencil = true; this.sortObjects = true; this.clippingPlanes = []; this.localClippingEnabled = false; this._outputColorSpace = SRGBColorSpace; 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; const _currentClearColor = new Color(0); let _currentClearAlpha = 0; let _width = canvas.width; let _height = canvas.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 _frustum2 = new Frustum(); let _clippingEnabled = false; let _localClippingEnabled = false; const _currentProjectionMatrix = new Matrix4(); const _projScreenMatrix2 = new Matrix4(); const _vector3 = new Vector3(); const _vector42 = new Vector4(); const _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true }; let _renderBackground = false; function getTargetPixelRatio() { return _currentRenderTarget === null ? _pixelRatio : 1; } let _gl = context2; function getContext(contextName, contextAttributes) { return canvas.getContext(contextName, contextAttributes); } try { const contextAttributes = { alpha: true, depth: depth2, stencil, antialias, premultipliedAlpha, preserveDrawingBuffer, powerPreference, failIfMajorPerformanceCaveat }; if ("setAttribute" in canvas) canvas.setAttribute("data-engine", `three.js r${REVISION}`); canvas.addEventListener("webglcontextlost", onContextLost, false); canvas.addEventListener("webglcontextrestored", onContextRestore, false); canvas.addEventListener("webglcontextcreationerror", onContextCreationError, false); if (_gl === null) { const contextName = "webgl2"; _gl = getContext(contextName, contextAttributes); if (_gl === null) { if (getContext(contextName)) { throw new Error("Error creating WebGL context with your selected attributes."); } else { throw new Error("Error creating WebGL context."); } } } } 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, clipping2, shadowMap; let background, morphtargets, bufferRenderer, indexedBufferRenderer; let utils, bindingStates, uniformsGroups; function initGLContext() { extensions = new WebGLExtensions(_gl); extensions.init(); utils = new WebGLUtils(_gl, extensions); capabilities = new WebGLCapabilities(_gl, extensions, parameters, utils); state = new WebGLState(_gl, extensions); if (capabilities.reverseDepthBuffer && reverseDepthBuffer) { state.buffers.depth.setReversed(true); } 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); bindingStates = new WebGLBindingStates(_gl, attributes); geometries = new WebGLGeometries(_gl, attributes, info, bindingStates); objects = new WebGLObjects(_gl, geometries, attributes, info); morphtargets = new WebGLMorphtargets(_gl, capabilities, textures); clipping2 = new WebGLClipping(properties); programCache = new WebGLPrograms(_this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping2); materials = new WebGLMaterials(_this, properties); renderLists = new WebGLRenderLists(); renderStates = new WebGLRenderStates(extensions); background = new WebGLBackground(_this, cubemaps, cubeuvmaps, state, objects, _alpha, premultipliedAlpha); shadowMap = new WebGLShadowMap(_this, objects, capabilities); uniformsGroups = new WebGLUniformsGroups(_gl, info, capabilities, state); bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info); indexedBufferRenderer = new WebGLIndexedBufferRenderer(_gl, extensions, info); 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 = true) { if (xr.isPresenting) { console.warn("THREE.WebGLRenderer: Can't change size while VR device is presenting."); return; } _width = width; _height = height; canvas.width = Math.floor(width * _pixelRatio); canvas.height = Math.floor(height * _pixelRatio); if (updateStyle === true) { canvas.style.width = width + "px"; canvas.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; canvas.width = Math.floor(width * pixelRatio); canvas.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(x2, y2, width, height) { if (x2.isVector4) { _viewport.set(x2.x, x2.y, x2.z, x2.w); } else { _viewport.set(x2, y2, width, height); } state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).round()); }; this.getScissor = function(target) { return target.copy(_scissor); }; this.setScissor = function(x2, y2, width, height) { if (x2.isVector4) { _scissor.set(x2.x, x2.y, x2.z, x2.w); } else { _scissor.set(x2, y2, width, height); } state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).round()); }; 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(color2 = true, depth3 = true, stencil2 = true) { let bits = 0; if (color2) { let isIntegerFormat = false; if (_currentRenderTarget !== null) { const targetFormat = _currentRenderTarget.texture.format; isIntegerFormat = targetFormat === RGBAIntegerFormat || targetFormat === RGIntegerFormat || targetFormat === RedIntegerFormat; } if (isIntegerFormat) { const targetType = _currentRenderTarget.texture.type; const isUnsignedType = targetType === UnsignedByteType || targetType === UnsignedIntType || targetType === UnsignedShortType || targetType === UnsignedInt248Type || targetType === UnsignedShort4444Type || targetType === UnsignedShort5551Type; const clearColor = background.getClearColor(); const a2 = background.getClearAlpha(); const r = clearColor.r; const g = clearColor.g; const b = clearColor.b; if (isUnsignedType) { uintClearColor[0] = r; uintClearColor[1] = g; uintClearColor[2] = b; uintClearColor[3] = a2; _gl.clearBufferuiv(_gl.COLOR, 0, uintClearColor); } else { intClearColor[0] = r; intClearColor[1] = g; intClearColor[2] = b; intClearColor[3] = a2; _gl.clearBufferiv(_gl.COLOR, 0, intClearColor); } } else { bits |= _gl.COLOR_BUFFER_BIT; } } if (depth3) { bits |= _gl.DEPTH_BUFFER_BIT; } if (stencil2) { bits |= _gl.STENCIL_BUFFER_BIT; this.state.buffers.stencil.setMask(4294967295); } _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() { canvas.removeEventListener("webglcontextlost", onContextLost, false); canvas.removeEventListener("webglcontextrestored", onContextRestore, false); canvas.removeEventListener("webglcontextcreationerror", onContextCreationError, false); renderLists.dispose(); renderStates.dispose(); properties.dispose(); cubemaps.dispose(); cubeuvmaps.dispose(); objects.dispose(); bindingStates.dispose(); uniformsGroups.dispose(); programCache.dispose(); xr.dispose(); xr.removeEventListener("sessionstart", onXRSessionStart); xr.removeEventListener("sessionend", onXRSessionEnd); 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 onContextCreationError(event) { console.error("THREE.WebGLRenderer: A WebGL context could not be created. Reason: ", event.statusMessage); } 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); }); if (material.isShaderMaterial) { programCache.releaseShaderCache(material); } } } this.renderBufferDirect = function(camera3, scene3, geometry, material, object, group) { if (scene3 === null) scene3 = _emptyScene; const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; const program = setProgram(camera3, scene3, geometry, material, object); state.setMaterial(material, frontFaceCW); let index5 = geometry.index; let rangeFactor = 1; if (material.wireframe === true) { index5 = geometries.getWireframeAttribute(geometry); if (index5 === void 0) return; rangeFactor = 2; } const drawRange = geometry.drawRange; const position = geometry.attributes.position; let drawStart = drawRange.start * rangeFactor; let drawEnd = (drawRange.start + drawRange.count) * rangeFactor; if (group !== null) { drawStart = Math.max(drawStart, group.start * rangeFactor); drawEnd = Math.min(drawEnd, (group.start + group.count) * rangeFactor); } if (index5 !== null) { drawStart = Math.max(drawStart, 0); drawEnd = Math.min(drawEnd, index5.count); } else if (position !== void 0 && position !== null) { drawStart = Math.max(drawStart, 0); drawEnd = Math.min(drawEnd, position.count); } const drawCount = drawEnd - drawStart; if (drawCount < 0 || drawCount === Infinity) return; bindingStates.setup(object, material, program, geometry, index5); let attribute2; let renderer3 = bufferRenderer; if (index5 !== null) { attribute2 = attributes.get(index5); renderer3 = indexedBufferRenderer; renderer3.setIndex(attribute2); } if (object.isMesh) { if (material.wireframe === true) { state.setLineWidth(material.wireframeLinewidth * getTargetPixelRatio()); renderer3.setMode(_gl.LINES); } else { renderer3.setMode(_gl.TRIANGLES); } } else if (object.isLine) { let lineWidth = material.linewidth; if (lineWidth === void 0) lineWidth = 1; state.setLineWidth(lineWidth * getTargetPixelRatio()); if (object.isLineSegments) { renderer3.setMode(_gl.LINES); } else if (object.isLineLoop) { renderer3.setMode(_gl.LINE_LOOP); } else { renderer3.setMode(_gl.LINE_STRIP); } } else if (object.isPoints) { renderer3.setMode(_gl.POINTS); } else if (object.isSprite) { renderer3.setMode(_gl.TRIANGLES); } if (object.isBatchedMesh) { if (object._multiDrawInstances !== null) { renderer3.renderMultiDrawInstances(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount, object._multiDrawInstances); } else { if (!extensions.get("WEBGL_multi_draw")) { const starts = object._multiDrawStarts; const counts = object._multiDrawCounts; const drawCount2 = object._multiDrawCount; const bytesPerElement = index5 ? attributes.get(index5).bytesPerElement : 1; const uniforms = properties.get(material).currentProgram.getUniforms(); for (let i = 0; i < drawCount2; i++) { uniforms.setValue(_gl, "_gl_DrawID", i); renderer3.render(starts[i] / bytesPerElement, counts[i]); } } else { renderer3.renderMultiDraw(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount); } } } else if (object.isInstancedMesh) { renderer3.renderInstances(drawStart, drawCount, object.count); } else if (geometry.isInstancedBufferGeometry) { const maxInstanceCount = geometry._maxInstanceCount !== void 0 ? geometry._maxInstanceCount : Infinity; const instanceCount = Math.min(geometry.instanceCount, maxInstanceCount); renderer3.renderInstances(drawStart, drawCount, instanceCount); } else { renderer3.render(drawStart, drawCount); } }; function prepareMaterial(material, scene3, object) { if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) { material.side = BackSide; material.needsUpdate = true; getProgram(material, scene3, object); material.side = FrontSide; material.needsUpdate = true; getProgram(material, scene3, object); material.side = DoubleSide; } else { getProgram(material, scene3, object); } } this.compile = function(scene3, camera3, targetScene = null) { if (targetScene === null) targetScene = scene3; currentRenderState = renderStates.get(targetScene); currentRenderState.init(camera3); renderStateStack.push(currentRenderState); targetScene.traverseVisible(function(object) { if (object.isLight && object.layers.test(camera3.layers)) { currentRenderState.pushLight(object); if (object.castShadow) { currentRenderState.pushShadow(object); } } }); if (scene3 !== targetScene) { scene3.traverseVisible(function(object) { if (object.isLight && object.layers.test(camera3.layers)) { currentRenderState.pushLight(object); if (object.castShadow) { currentRenderState.pushShadow(object); } } }); } currentRenderState.setupLights(); const materials2 = /* @__PURE__ */ new Set(); scene3.traverse(function(object) { if (!(object.isMesh || object.isPoints || object.isLine || object.isSprite)) { return; } const material = object.material; if (material) { if (Array.isArray(material)) { for (let i = 0; i < material.length; i++) { const material2 = material[i]; prepareMaterial(material2, targetScene, object); materials2.add(material2); } } else { prepareMaterial(material, targetScene, object); materials2.add(material); } } }); renderStateStack.pop(); currentRenderState = null; return materials2; }; this.compileAsync = function(scene3, camera3, targetScene = null) { const materials2 = this.compile(scene3, camera3, targetScene); return new Promise((resolve) => { function checkMaterialsReady() { materials2.forEach(function(material) { const materialProperties = properties.get(material); const program = materialProperties.currentProgram; if (program.isReady()) { materials2.delete(material); } }); if (materials2.size === 0) { resolve(scene3); return; } setTimeout(checkMaterialsReady, 10); } if (extensions.get("KHR_parallel_shader_compile") !== null) { checkMaterialsReady(); } else { setTimeout(checkMaterialsReady, 10); } }); }; 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 self !== "undefined") animation.setContext(self); 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(scene3, camera3) { if (camera3 !== void 0 && camera3.isCamera !== true) { console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera."); return; } if (_isContextLost === true) return; if (scene3.matrixWorldAutoUpdate === true) scene3.updateMatrixWorld(); if (camera3.parent === null && camera3.matrixWorldAutoUpdate === true) camera3.updateMatrixWorld(); if (xr.enabled === true && xr.isPresenting === true) { if (xr.cameraAutoUpdate === true) xr.updateCamera(camera3); camera3 = xr.getCamera(); } if (scene3.isScene === true) scene3.onBeforeRender(_this, scene3, camera3, _currentRenderTarget); currentRenderState = renderStates.get(scene3, renderStateStack.length); currentRenderState.init(camera3); renderStateStack.push(currentRenderState); _projScreenMatrix2.multiplyMatrices(camera3.projectionMatrix, camera3.matrixWorldInverse); _frustum2.setFromProjectionMatrix(_projScreenMatrix2); _localClippingEnabled = this.localClippingEnabled; _clippingEnabled = clipping2.init(this.clippingPlanes, _localClippingEnabled); currentRenderList = renderLists.get(scene3, renderListStack.length); currentRenderList.init(); renderListStack.push(currentRenderList); if (xr.enabled === true && xr.isPresenting === true) { const depthSensingMesh = _this.xr.getDepthSensingMesh(); if (depthSensingMesh !== null) { projectObject(depthSensingMesh, camera3, -Infinity, _this.sortObjects); } } projectObject(scene3, camera3, 0, _this.sortObjects); currentRenderList.finish(); if (_this.sortObjects === true) { currentRenderList.sort(_opaqueSort, _transparentSort); } _renderBackground = xr.enabled === false || xr.isPresenting === false || xr.hasDepthSensing() === false; if (_renderBackground) { background.addToRenderList(currentRenderList, scene3); } this.info.render.frame++; if (_clippingEnabled === true) clipping2.beginShadows(); const shadowsArray = currentRenderState.state.shadowsArray; shadowMap.render(shadowsArray, scene3, camera3); if (_clippingEnabled === true) clipping2.endShadows(); if (this.info.autoReset === true) this.info.reset(); const opaqueObjects = currentRenderList.opaque; const transmissiveObjects = currentRenderList.transmissive; currentRenderState.setupLights(); if (camera3.isArrayCamera) { const cameras = camera3.cameras; if (transmissiveObjects.length > 0) { for (let i = 0, l = cameras.length; i < l; i++) { const camera22 = cameras[i]; renderTransmissionPass(opaqueObjects, transmissiveObjects, scene3, camera22); } } if (_renderBackground) background.render(scene3); for (let i = 0, l = cameras.length; i < l; i++) { const camera22 = cameras[i]; renderScene(currentRenderList, scene3, camera22, camera22.viewport); } } else { if (transmissiveObjects.length > 0) renderTransmissionPass(opaqueObjects, transmissiveObjects, scene3, camera3); if (_renderBackground) background.render(scene3); renderScene(currentRenderList, scene3, camera3); } if (_currentRenderTarget !== null) { textures.updateMultisampleRenderTarget(_currentRenderTarget); textures.updateRenderTargetMipmap(_currentRenderTarget); } if (scene3.isScene === true) scene3.onAfterRender(_this, scene3, camera3); bindingStates.resetDefaultState(); _currentMaterialId = -1; _currentCamera = null; renderStateStack.pop(); if (renderStateStack.length > 0) { currentRenderState = renderStateStack[renderStateStack.length - 1]; if (_clippingEnabled === true) clipping2.setGlobalState(_this.clippingPlanes, currentRenderState.state.camera); } else { currentRenderState = null; } renderListStack.pop(); if (renderListStack.length > 0) { currentRenderList = renderListStack[renderListStack.length - 1]; } else { currentRenderList = null; } }; function projectObject(object, camera3, groupOrder, sortObjects) { if (object.visible === false) return; const visible = object.layers.test(camera3.layers); if (visible) { if (object.isGroup) { groupOrder = object.renderOrder; } else if (object.isLOD) { if (object.autoUpdate === true) object.update(camera3); } else if (object.isLight) { currentRenderState.pushLight(object); if (object.castShadow) { currentRenderState.pushShadow(object); } } else if (object.isSprite) { if (!object.frustumCulled || _frustum2.intersectsSprite(object)) { if (sortObjects) { _vector42.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix2); } const geometry = objects.update(object); const material = object.material; if (material.visible) { currentRenderList.push(object, geometry, material, groupOrder, _vector42.z, null); } } } else if (object.isMesh || object.isLine || object.isPoints) { if (!object.frustumCulled || _frustum2.intersectsObject(object)) { const geometry = objects.update(object); const material = object.material; if (sortObjects) { if (object.boundingSphere !== void 0) { if (object.boundingSphere === null) object.computeBoundingSphere(); _vector42.copy(object.boundingSphere.center); } else { if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _vector42.copy(geometry.boundingSphere.center); } _vector42.applyMatrix4(object.matrixWorld).applyMatrix4(_projScreenMatrix2); } 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, _vector42.z, group); } } } else if (material.visible) { currentRenderList.push(object, geometry, material, groupOrder, _vector42.z, null); } } } } const children = object.children; for (let i = 0, l = children.length; i < l; i++) { projectObject(children[i], camera3, groupOrder, sortObjects); } } function renderScene(currentRenderList2, scene3, camera3, viewport2) { const opaqueObjects = currentRenderList2.opaque; const transmissiveObjects = currentRenderList2.transmissive; const transparentObjects = currentRenderList2.transparent; currentRenderState.setupLightsView(camera3); if (_clippingEnabled === true) clipping2.setGlobalState(_this.clippingPlanes, camera3); if (viewport2) state.viewport(_currentViewport.copy(viewport2)); if (opaqueObjects.length > 0) renderObjects(opaqueObjects, scene3, camera3); if (transmissiveObjects.length > 0) renderObjects(transmissiveObjects, scene3, camera3); if (transparentObjects.length > 0) renderObjects(transparentObjects, scene3, camera3); state.buffers.depth.setTest(true); state.buffers.depth.setMask(true); state.buffers.color.setMask(true); state.setPolygonOffset(false); } function renderTransmissionPass(opaqueObjects, transmissiveObjects, scene3, camera3) { const overrideMaterial = scene3.isScene === true ? scene3.overrideMaterial : null; if (overrideMaterial !== null) { return; } if (currentRenderState.state.transmissionRenderTarget[camera3.id] === void 0) { currentRenderState.state.transmissionRenderTarget[camera3.id] = new WebGLRenderTarget(1, 1, { generateMipmaps: true, type: extensions.has("EXT_color_buffer_half_float") || extensions.has("EXT_color_buffer_float") ? HalfFloatType : UnsignedByteType, minFilter: LinearMipmapLinearFilter, samples: 4, stencilBuffer: stencil, resolveDepthBuffer: false, resolveStencilBuffer: false, colorSpace: ColorManagement.workingColorSpace }); } const transmissionRenderTarget = currentRenderState.state.transmissionRenderTarget[camera3.id]; const activeViewport = camera3.viewport || _currentViewport; transmissionRenderTarget.setSize(activeViewport.z, activeViewport.w); const currentRenderTarget = _this.getRenderTarget(); _this.setRenderTarget(transmissionRenderTarget); _this.getClearColor(_currentClearColor); _currentClearAlpha = _this.getClearAlpha(); if (_currentClearAlpha < 1) _this.setClearColor(16777215, 0.5); _this.clear(); if (_renderBackground) background.render(scene3); const currentToneMapping = _this.toneMapping; _this.toneMapping = NoToneMapping; const currentCameraViewport = camera3.viewport; if (camera3.viewport !== void 0) camera3.viewport = void 0; currentRenderState.setupLightsView(camera3); if (_clippingEnabled === true) clipping2.setGlobalState(_this.clippingPlanes, camera3); renderObjects(opaqueObjects, scene3, camera3); textures.updateMultisampleRenderTarget(transmissionRenderTarget); textures.updateRenderTargetMipmap(transmissionRenderTarget); if (extensions.has("WEBGL_multisampled_render_to_texture") === false) { let renderTargetNeedsUpdate = false; for (let i = 0, l = transmissiveObjects.length; i < l; i++) { const renderItem = transmissiveObjects[i]; const object = renderItem.object; const geometry = renderItem.geometry; const material = renderItem.material; const group = renderItem.group; if (material.side === DoubleSide && object.layers.test(camera3.layers)) { const currentSide = material.side; material.side = BackSide; material.needsUpdate = true; renderObject(object, scene3, camera3, geometry, material, group); material.side = currentSide; material.needsUpdate = true; renderTargetNeedsUpdate = true; } } if (renderTargetNeedsUpdate === true) { textures.updateMultisampleRenderTarget(transmissionRenderTarget); textures.updateRenderTargetMipmap(transmissionRenderTarget); } } _this.setRenderTarget(currentRenderTarget); _this.setClearColor(_currentClearColor, _currentClearAlpha); if (currentCameraViewport !== void 0) camera3.viewport = currentCameraViewport; _this.toneMapping = currentToneMapping; } function renderObjects(renderList, scene3, camera3) { const overrideMaterial = scene3.isScene === true ? scene3.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(camera3.layers)) { renderObject(object, scene3, camera3, geometry, material, group); } } } function renderObject(object, scene3, camera3, geometry, material, group) { object.onBeforeRender(_this, scene3, camera3, geometry, material, group); object.modelViewMatrix.multiplyMatrices(camera3.matrixWorldInverse, object.matrixWorld); object.normalMatrix.getNormalMatrix(object.modelViewMatrix); material.onBeforeRender(_this, scene3, camera3, geometry, object, group); if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) { material.side = BackSide; material.needsUpdate = true; _this.renderBufferDirect(camera3, scene3, geometry, material, object, group); material.side = FrontSide; material.needsUpdate = true; _this.renderBufferDirect(camera3, scene3, geometry, material, object, group); material.side = DoubleSide; } else { _this.renderBufferDirect(camera3, scene3, geometry, material, object, group); } object.onAfterRender(_this, scene3, camera3, geometry, material, group); } function getProgram(material, scene3, object) { if (scene3.isScene !== true) scene3 = _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, scene3, object); const programCacheKey = programCache.getProgramCacheKey(parameters2); let programs = materialProperties.programs; materialProperties.environment = material.isMeshStandardMaterial ? scene3.environment : null; materialProperties.fog = scene3.fog; materialProperties.envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || materialProperties.environment); materialProperties.envMapRotation = materialProperties.environment !== null && material.envMap === null ? scene3.environmentRotation : material.envMapRotation; 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.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 = clipping2.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.spotLightMatrix.value = lights.state.spotLightMatrix; uniforms.spotLightMap.value = lights.state.spotLightMap; uniforms.pointShadowMap.value = lights.state.pointShadowMap; uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; } materialProperties.currentProgram = program; materialProperties.uniformsList = null; return program; } function getUniformList(materialProperties) { if (materialProperties.uniformsList === null) { const progUniforms = materialProperties.currentProgram.getUniforms(); materialProperties.uniformsList = WebGLUniforms.seqWithValue(progUniforms.seq, materialProperties.uniforms); } return materialProperties.uniformsList; } function updateCommonMaterialProperties(material, parameters2) { const materialProperties = properties.get(material); materialProperties.outputColorSpace = parameters2.outputColorSpace; materialProperties.batching = parameters2.batching; materialProperties.batchingColor = parameters2.batchingColor; materialProperties.instancing = parameters2.instancing; materialProperties.instancingColor = parameters2.instancingColor; materialProperties.instancingMorph = parameters2.instancingMorph; materialProperties.skinning = parameters2.skinning; materialProperties.morphTargets = parameters2.morphTargets; materialProperties.morphNormals = parameters2.morphNormals; materialProperties.morphColors = parameters2.morphColors; materialProperties.morphTargetsCount = parameters2.morphTargetsCount; materialProperties.numClippingPlanes = parameters2.numClippingPlanes; materialProperties.numIntersection = parameters2.numClipIntersection; materialProperties.vertexAlphas = parameters2.vertexAlphas; materialProperties.vertexTangents = parameters2.vertexTangents; materialProperties.toneMapping = parameters2.toneMapping; } function setProgram(camera3, scene3, geometry, material, object) { if (scene3.isScene !== true) scene3 = _emptyScene; textures.resetTextureUnits(); const fog = scene3.fog; const environment = material.isMeshStandardMaterial ? scene3.environment : null; const colorSpace = _currentRenderTarget === null ? _this.outputColorSpace : _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace; const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment); const vertexAlphas = material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4; const vertexTangents = !!geometry.attributes.tangent && (!!material.normalMap || material.anisotropy > 0); const morphTargets = !!geometry.morphAttributes.position; const morphNormals = !!geometry.morphAttributes.normal; const morphColors = !!geometry.morphAttributes.color; let toneMapping2 = NoToneMapping; if (material.toneMapped) { if (_currentRenderTarget === null || _currentRenderTarget.isXRRenderTarget === true) { toneMapping2 = _this.toneMapping; } } const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; const morphTargetsCount = morphAttribute !== void 0 ? morphAttribute.length : 0; const materialProperties = properties.get(material); const lights = currentRenderState.state.lights; if (_clippingEnabled === true) { if (_localClippingEnabled === true || camera3 !== _currentCamera) { const useCache = camera3 === _currentCamera && material.id === _currentMaterialId; clipping2.setState(material, camera3, useCache); } } let needsProgramChange = false; if (material.version === materialProperties.__version) { if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) { needsProgramChange = true; } else if (materialProperties.outputColorSpace !== colorSpace) { needsProgramChange = true; } else if (object.isBatchedMesh && materialProperties.batching === false) { needsProgramChange = true; } else if (!object.isBatchedMesh && materialProperties.batching === true) { needsProgramChange = true; } else if (object.isBatchedMesh && materialProperties.batchingColor === true && object.colorTexture === null) { needsProgramChange = true; } else if (object.isBatchedMesh && materialProperties.batchingColor === false && object.colorTexture !== null) { 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 (object.isInstancedMesh && materialProperties.instancingColor === true && object.instanceColor === null) { needsProgramChange = true; } else if (object.isInstancedMesh && materialProperties.instancingColor === false && object.instanceColor !== null) { needsProgramChange = true; } else if (object.isInstancedMesh && materialProperties.instancingMorph === true && object.morphTexture === null) { needsProgramChange = true; } else if (object.isInstancedMesh && materialProperties.instancingMorph === false && object.morphTexture !== null) { needsProgramChange = true; } else if (materialProperties.envMap !== envMap) { needsProgramChange = true; } else if (material.fog === true && materialProperties.fog !== fog) { needsProgramChange = true; } else if (materialProperties.numClippingPlanes !== void 0 && (materialProperties.numClippingPlanes !== clipping2.numPlanes || materialProperties.numIntersection !== clipping2.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 if (materialProperties.morphColors !== morphColors) { needsProgramChange = true; } else if (materialProperties.toneMapping !== toneMapping2) { needsProgramChange = true; } else if (materialProperties.morphTargetsCount !== morphTargetsCount) { needsProgramChange = true; } } else { needsProgramChange = true; materialProperties.__version = material.version; } let program = materialProperties.currentProgram; if (needsProgramChange === true) { program = getProgram(material, scene3, 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 !== camera3) { const reverseDepthBuffer2 = state.buffers.depth.getReversed(); if (reverseDepthBuffer2) { _currentProjectionMatrix.copy(camera3.projectionMatrix); toNormalizedProjectionMatrix(_currentProjectionMatrix); toReversedProjectionMatrix(_currentProjectionMatrix); p_uniforms.setValue(_gl, "projectionMatrix", _currentProjectionMatrix); } else { p_uniforms.setValue(_gl, "projectionMatrix", camera3.projectionMatrix); } p_uniforms.setValue(_gl, "viewMatrix", camera3.matrixWorldInverse); const uCamPos = p_uniforms.map.cameraPosition; if (uCamPos !== void 0) { uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera3.matrixWorld)); } if (capabilities.logarithmicDepthBuffer) { p_uniforms.setValue( _gl, "logDepthBufFC", 2 / (Math.log(camera3.far + 1) / Math.LN2) ); } if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) { p_uniforms.setValue(_gl, "isOrthographic", camera3.isOrthographicCamera === true); } if (_currentCamera !== camera3) { _currentCamera = camera3; refreshMaterial = true; refreshLights = true; } } if (object.isSkinnedMesh) { p_uniforms.setOptional(_gl, object, "bindMatrix"); p_uniforms.setOptional(_gl, object, "bindMatrixInverse"); const skeleton = object.skeleton; if (skeleton) { if (skeleton.boneTexture === null) skeleton.computeBoneTexture(); p_uniforms.setValue(_gl, "boneTexture", skeleton.boneTexture, textures); } } if (object.isBatchedMesh) { p_uniforms.setOptional(_gl, object, "batchingTexture"); p_uniforms.setValue(_gl, "batchingTexture", object._matricesTexture, textures); p_uniforms.setOptional(_gl, object, "batchingIdTexture"); p_uniforms.setValue(_gl, "batchingIdTexture", object._indirectTexture, textures); p_uniforms.setOptional(_gl, object, "batchingColorTexture"); if (object._colorsTexture !== null) { p_uniforms.setValue(_gl, "batchingColorTexture", object._colorsTexture, textures); } } const morphAttributes = geometry.morphAttributes; if (morphAttributes.position !== void 0 || morphAttributes.normal !== void 0 || morphAttributes.color !== void 0) { morphtargets.update(object, geometry, program); } if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) { materialProperties.receiveShadow = object.receiveShadow; p_uniforms.setValue(_gl, "receiveShadow", object.receiveShadow); } if (material.isMeshGouraudMaterial && material.envMap !== null) { m_uniforms.envMap.value = envMap; m_uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1; } if (material.isMeshStandardMaterial && material.envMap === null && scene3.environment !== null) { m_uniforms.envMapIntensity.value = scene3.environmentIntensity; } if (refreshMaterial) { p_uniforms.setValue(_gl, "toneMappingExposure", _this.toneMappingExposure); if (materialProperties.needsLights) { markUniformsLightsNeedsUpdate(m_uniforms, refreshLights); } if (fog && material.fog === true) { materials.refreshFogUniforms(m_uniforms, fog); } materials.refreshMaterialUniforms(m_uniforms, material, _pixelRatio, _height, currentRenderState.state.transmissionRenderTarget[camera3.id]); WebGLUniforms.upload(_gl, getUniformList(materialProperties), m_uniforms, textures); } if (material.isShaderMaterial && material.uniformsNeedUpdate === true) { WebGLUniforms.upload(_gl, getUniformList(materialProperties), 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); if (material.isShaderMaterial || material.isRawShaderMaterial) { const groups = material.uniformsGroups; for (let i = 0, l = groups.length; i < l; i++) { const group = groups[i]; uniformsGroups.update(group, program); uniformsGroups.bind(group, program); } } 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.setRenderTargetTextures = function(renderTarget, colorTexture, depthTexture) { properties.get(renderTarget.texture).__webglTexture = colorTexture; properties.get(renderTarget.depthTexture).__webglTexture = depthTexture; const renderTargetProperties = properties.get(renderTarget); renderTargetProperties.__hasExternalTextures = true; renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === void 0; if (!renderTargetProperties.__autoAllocateDepthBuffer) { if (extensions.has("WEBGL_multisampled_render_to_texture") === true) { console.warn("THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided"); renderTargetProperties.__useRenderToTexture = false; } } }; this.setRenderTargetFramebuffer = function(renderTarget, defaultFramebuffer) { const renderTargetProperties = properties.get(renderTarget); renderTargetProperties.__webglFramebuffer = defaultFramebuffer; renderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === void 0; }; this.setRenderTarget = function(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { _currentRenderTarget = renderTarget; _currentActiveCubeFace = activeCubeFace; _currentActiveMipmapLevel = activeMipmapLevel; let useDefaultFramebuffer = true; let framebuffer = null; let isCube = false; let isRenderTarget3D = false; if (renderTarget) { const renderTargetProperties = properties.get(renderTarget); if (renderTargetProperties.__useDefaultFramebuffer !== void 0) { state.bindFramebuffer(_gl.FRAMEBUFFER, null); useDefaultFramebuffer = false; } else if (renderTargetProperties.__webglFramebuffer === void 0) { textures.setupRenderTarget(renderTarget); } else if (renderTargetProperties.__hasExternalTextures) { textures.rebindTextures(renderTarget, properties.get(renderTarget.texture).__webglTexture, properties.get(renderTarget.depthTexture).__webglTexture); } else if (renderTarget.depthBuffer) { const depthTexture = renderTarget.depthTexture; if (renderTargetProperties.__boundDepthTexture !== depthTexture) { if (depthTexture !== null && properties.has(depthTexture) && (renderTarget.width !== depthTexture.image.width || renderTarget.height !== depthTexture.image.height)) { throw new Error("WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size."); } textures.setupDepthRenderbuffer(renderTarget); } } const texture2 = renderTarget.texture; if (texture2.isData3DTexture || texture2.isDataArrayTexture || texture2.isCompressedArrayTexture) { isRenderTarget3D = true; } const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer; if (renderTarget.isWebGLCubeRenderTarget) { if (Array.isArray(__webglFramebuffer[activeCubeFace])) { framebuffer = __webglFramebuffer[activeCubeFace][activeMipmapLevel]; } else { framebuffer = __webglFramebuffer[activeCubeFace]; } isCube = true; } else if (renderTarget.samples > 0 && textures.useMultisampledRTT(renderTarget) === false) { framebuffer = properties.get(renderTarget).__webglMultisampledFramebuffer; } else { if (Array.isArray(__webglFramebuffer)) { framebuffer = __webglFramebuffer[activeMipmapLevel]; } 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(_gl.FRAMEBUFFER, framebuffer); if (framebufferBound && useDefaultFramebuffer) { state.drawBuffers(renderTarget, framebuffer); } state.viewport(_currentViewport); state.scissor(_currentScissor); state.setScissorTest(_currentScissorTest); if (isCube) { const textureProperties = properties.get(renderTarget.texture); _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel); } else if (isRenderTarget3D) { const textureProperties = properties.get(renderTarget.texture); const layer = activeCubeFace || 0; _gl.framebufferTextureLayer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureProperties.__webglTexture, activeMipmapLevel || 0, layer); } _currentMaterialId = -1; }; this.readRenderTargetPixels = function(renderTarget, x2, y2, width, height, buffer2, 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(_gl.FRAMEBUFFER, framebuffer); try { const texture2 = renderTarget.texture; const textureFormat = texture2.format; const textureType = texture2.type; if (!capabilities.textureFormatReadable(textureFormat)) { console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."); return; } if (!capabilities.textureTypeReadable(textureType)) { console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type."); return; } if (x2 >= 0 && x2 <= renderTarget.width - width && (y2 >= 0 && y2 <= renderTarget.height - height)) { _gl.readPixels(x2, y2, width, height, utils.convert(textureFormat), utils.convert(textureType), buffer2); } } finally { const framebuffer2 = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null; state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer2); } } }; this.readRenderTargetPixelsAsync = async function(renderTarget, x2, y2, width, height, buffer2, activeCubeFaceIndex) { if (!(renderTarget && renderTarget.isWebGLRenderTarget)) { throw new Error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); } let framebuffer = properties.get(renderTarget).__webglFramebuffer; if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== void 0) { framebuffer = framebuffer[activeCubeFaceIndex]; } if (framebuffer) { const texture2 = renderTarget.texture; const textureFormat = texture2.format; const textureType = texture2.type; if (!capabilities.textureFormatReadable(textureFormat)) { throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format."); } if (!capabilities.textureTypeReadable(textureType)) { throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type."); } if (x2 >= 0 && x2 <= renderTarget.width - width && (y2 >= 0 && y2 <= renderTarget.height - height)) { state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer); const glBuffer = _gl.createBuffer(); _gl.bindBuffer(_gl.PIXEL_PACK_BUFFER, glBuffer); _gl.bufferData(_gl.PIXEL_PACK_BUFFER, buffer2.byteLength, _gl.STREAM_READ); _gl.readPixels(x2, y2, width, height, utils.convert(textureFormat), utils.convert(textureType), 0); const currFramebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null; state.bindFramebuffer(_gl.FRAMEBUFFER, currFramebuffer); const sync = _gl.fenceSync(_gl.SYNC_GPU_COMMANDS_COMPLETE, 0); _gl.flush(); await probeAsync(_gl, sync, 4); _gl.bindBuffer(_gl.PIXEL_PACK_BUFFER, glBuffer); _gl.getBufferSubData(_gl.PIXEL_PACK_BUFFER, 0, buffer2); _gl.deleteBuffer(glBuffer); _gl.deleteSync(sync); return buffer2; } else { throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range."); } } }; this.copyFramebufferToTexture = function(texture2, position = null, level = 0) { if (texture2.isTexture !== true) { warnOnce("WebGLRenderer: copyFramebufferToTexture function signature has changed."); position = arguments[0] || null; texture2 = arguments[1]; } const levelScale = Math.pow(2, -level); const width = Math.floor(texture2.image.width * levelScale); const height = Math.floor(texture2.image.height * levelScale); const x2 = position !== null ? position.x : 0; const y2 = position !== null ? position.y : 0; textures.setTexture2D(texture2, 0); _gl.copyTexSubImage2D(_gl.TEXTURE_2D, level, 0, 0, x2, y2, width, height); state.unbindTexture(); }; this.copyTextureToTexture = function(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { if (srcTexture.isTexture !== true) { warnOnce("WebGLRenderer: copyTextureToTexture function signature has changed."); dstPosition = arguments[0] || null; srcTexture = arguments[1]; dstTexture = arguments[2]; level = arguments[3] || 0; srcRegion = null; } let width, height, depth3, minX, minY, minZ; let dstX, dstY, dstZ; const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[level] : srcTexture.image; if (srcRegion !== null) { width = srcRegion.max.x - srcRegion.min.x; height = srcRegion.max.y - srcRegion.min.y; depth3 = srcRegion.isBox3 ? srcRegion.max.z - srcRegion.min.z : 1; minX = srcRegion.min.x; minY = srcRegion.min.y; minZ = srcRegion.isBox3 ? srcRegion.min.z : 0; } else { width = image.width; height = image.height; depth3 = image.depth || 1; minX = 0; minY = 0; minZ = 0; } if (dstPosition !== null) { dstX = dstPosition.x; dstY = dstPosition.y; dstZ = dstPosition.z; } else { dstX = 0; dstY = 0; dstZ = 0; } const glFormat = utils.convert(dstTexture.format); const glType = utils.convert(dstTexture.type); let glTarget; if (dstTexture.isData3DTexture) { textures.setTexture3D(dstTexture, 0); glTarget = _gl.TEXTURE_3D; } else if (dstTexture.isDataArrayTexture || dstTexture.isCompressedArrayTexture) { textures.setTexture2DArray(dstTexture, 0); glTarget = _gl.TEXTURE_2D_ARRAY; } else { textures.setTexture2D(dstTexture, 0); glTarget = _gl.TEXTURE_2D; } _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); const currentUnpackRowLen = _gl.getParameter(_gl.UNPACK_ROW_LENGTH); const currentUnpackImageHeight = _gl.getParameter(_gl.UNPACK_IMAGE_HEIGHT); const currentUnpackSkipPixels = _gl.getParameter(_gl.UNPACK_SKIP_PIXELS); const currentUnpackSkipRows = _gl.getParameter(_gl.UNPACK_SKIP_ROWS); const currentUnpackSkipImages = _gl.getParameter(_gl.UNPACK_SKIP_IMAGES); _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width); _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, image.height); _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, minX); _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, minY); _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, minZ); const isSrc3D = srcTexture.isDataArrayTexture || srcTexture.isData3DTexture; const isDst3D = dstTexture.isDataArrayTexture || dstTexture.isData3DTexture; if (srcTexture.isRenderTargetTexture || srcTexture.isDepthTexture) { const srcTextureProperties = properties.get(srcTexture); const dstTextureProperties = properties.get(dstTexture); const srcRenderTargetProperties = properties.get(srcTextureProperties.__renderTarget); const dstRenderTargetProperties = properties.get(dstTextureProperties.__renderTarget); state.bindFramebuffer(_gl.READ_FRAMEBUFFER, srcRenderTargetProperties.__webglFramebuffer); state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, dstRenderTargetProperties.__webglFramebuffer); for (let i = 0; i < depth3; i++) { if (isSrc3D) { _gl.framebufferTextureLayer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get(srcTexture).__webglTexture, level, minZ + i); } if (srcTexture.isDepthTexture) { if (isDst3D) { _gl.framebufferTextureLayer(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get(dstTexture).__webglTexture, level, dstZ + i); } _gl.blitFramebuffer(minX, minY, width, height, dstX, dstY, width, height, _gl.DEPTH_BUFFER_BIT, _gl.NEAREST); } else if (isDst3D) { _gl.copyTexSubImage3D(glTarget, level, dstX, dstY, dstZ + i, minX, minY, width, height); } else { _gl.copyTexSubImage2D(glTarget, level, dstX, dstY, dstZ + i, minX, minY, width, height); } } state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null); state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null); } else { if (isDst3D) { if (srcTexture.isDataTexture || srcTexture.isData3DTexture) { _gl.texSubImage3D(glTarget, level, dstX, dstY, dstZ, width, height, depth3, glFormat, glType, image.data); } else if (dstTexture.isCompressedArrayTexture) { _gl.compressedTexSubImage3D(glTarget, level, dstX, dstY, dstZ, width, height, depth3, glFormat, image.data); } else { _gl.texSubImage3D(glTarget, level, dstX, dstY, dstZ, width, height, depth3, glFormat, glType, image); } } else { if (srcTexture.isDataTexture) { _gl.texSubImage2D(_gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image.data); } else if (srcTexture.isCompressedTexture) { _gl.compressedTexSubImage2D(_gl.TEXTURE_2D, level, dstX, dstY, image.width, image.height, glFormat, image.data); } else { _gl.texSubImage2D(_gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image); } } } _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, currentUnpackRowLen); _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight); _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels); _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows); _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages); if (level === 0 && dstTexture.generateMipmaps) { _gl.generateMipmap(glTarget); } state.unbindTexture(); }; this.copyTextureToTexture3D = function(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { if (srcTexture.isTexture !== true) { warnOnce("WebGLRenderer: copyTextureToTexture3D function signature has changed."); srcRegion = arguments[0] || null; dstPosition = arguments[1] || null; srcTexture = arguments[2]; dstTexture = arguments[3]; level = arguments[4] || 0; } warnOnce('WebGLRenderer: copyTextureToTexture3D function has been deprecated. Use "copyTextureToTexture" instead.'); return this.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); }; this.initRenderTarget = function(target) { if (properties.get(target).__webglFramebuffer === void 0) { textures.setupRenderTarget(target); } }; this.initTexture = function(texture2) { if (texture2.isCubeTexture) { textures.setTextureCube(texture2, 0); } else if (texture2.isData3DTexture) { textures.setTexture3D(texture2, 0); } else if (texture2.isDataArrayTexture || texture2.isCompressedArrayTexture) { textures.setTexture2DArray(texture2, 0); } else { textures.setTexture2D(texture2, 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 })); } } get coordinateSystem() { return WebGLCoordinateSystem; } get outputColorSpace() { return this._outputColorSpace; } set outputColorSpace(colorSpace) { this._outputColorSpace = colorSpace; const gl = this.getContext(); gl.drawingBufferColorspace = ColorManagement._getDrawingBufferColorSpace(colorSpace); gl.unpackColorSpace = ColorManagement._getUnpackColorSpace(); } }; var Scene = class extends Object3D { constructor() { super(); this.isScene = true; this.type = "Scene"; this.background = null; this.environment = null; this.fog = null; this.backgroundBlurriness = 0; this.backgroundIntensity = 1; this.backgroundRotation = new Euler(); this.environmentIntensity = 1; this.environmentRotation = new Euler(); this.overrideMaterial = null; 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(); this.backgroundBlurriness = source.backgroundBlurriness; this.backgroundIntensity = source.backgroundIntensity; this.backgroundRotation.copy(source.backgroundRotation); this.environmentIntensity = source.environmentIntensity; this.environmentRotation.copy(source.environmentRotation); if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone(); this.matrixAutoUpdate = source.matrixAutoUpdate; return this; } toJSON(meta) { const data = super.toJSON(meta); if (this.fog !== null) data.object.fog = this.fog.toJSON(); if (this.backgroundBlurriness > 0) data.object.backgroundBlurriness = this.backgroundBlurriness; if (this.backgroundIntensity !== 1) data.object.backgroundIntensity = this.backgroundIntensity; data.object.backgroundRotation = this.backgroundRotation.toArray(); if (this.environmentIntensity !== 1) data.object.environmentIntensity = this.environmentIntensity; data.object.environmentRotation = this.environmentRotation.toArray(); return data; } }; var LineBasicMaterial = class extends Material { static get type() { return "LineBasicMaterial"; } constructor(parameters) { super(); this.isLineBasicMaterial = true; this.color = new Color(16777215); this.map = null; this.linewidth = 1; this.linecap = "round"; this.linejoin = "round"; this.fog = true; this.setValues(parameters); } copy(source) { super.copy(source); this.color.copy(source.color); this.map = source.map; this.linewidth = source.linewidth; this.linecap = source.linecap; this.linejoin = source.linejoin; this.fog = source.fog; return this; } }; var _vStart = /* @__PURE__ */ new Vector3(); var _vEnd = /* @__PURE__ */ new Vector3(); var _inverseMatrix$1 = /* @__PURE__ */ new Matrix4(); var _ray$1 = /* @__PURE__ */ new Ray(); var _sphere$1 = /* @__PURE__ */ new Sphere(); var _intersectPointOnRay = /* @__PURE__ */ new Vector3(); var _intersectPointOnSegment = /* @__PURE__ */ new Vector3(); var Line = class extends Object3D { constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()) { super(); this.isLine = true; this.type = "Line"; this.geometry = geometry; this.material = material; this.updateMorphTargets(); } copy(source, recursive) { super.copy(source, recursive); this.material = Array.isArray(source.material) ? source.material.slice() : source.material; this.geometry = source.geometry; return this; } computeLineDistances() { const geometry = this.geometry; if (geometry.index === null) { const positionAttribute = geometry.attributes.position; const lineDistances = [0]; for (let i = 1, l = positionAttribute.count; i < l; i++) { _vStart.fromBufferAttribute(positionAttribute, i - 1); _vEnd.fromBufferAttribute(positionAttribute, i); lineDistances[i] = lineDistances[i - 1]; lineDistances[i] += _vStart.distanceTo(_vEnd); } geometry.setAttribute("lineDistance", new Float32BufferAttribute(lineDistances, 1)); } else { console.warn("THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry."); } return this; } raycast(raycaster, intersects) { 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 step2 = this.isLineSegments ? 2 : 1; const index5 = geometry.index; const attributes = geometry.attributes; const positionAttribute = attributes.position; if (index5 !== null) { const start = Math.max(0, drawRange.start); const end = Math.min(index5.count, drawRange.start + drawRange.count); for (let i = start, l = end - 1; i < l; i += step2) { const a2 = index5.getX(i); const b = index5.getX(i + 1); const intersect2 = checkIntersection(this, raycaster, _ray$1, localThresholdSq, a2, b); if (intersect2) { intersects.push(intersect2); } } if (this.isLineLoop) { const a2 = index5.getX(end - 1); const b = index5.getX(start); const intersect2 = checkIntersection(this, raycaster, _ray$1, localThresholdSq, a2, b); if (intersect2) { intersects.push(intersect2); } } } 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 += step2) { const intersect2 = checkIntersection(this, raycaster, _ray$1, localThresholdSq, i, i + 1); if (intersect2) { intersects.push(intersect2); } } if (this.isLineLoop) { const intersect2 = checkIntersection(this, raycaster, _ray$1, localThresholdSq, end - 1, start); if (intersect2) { intersects.push(intersect2); } } } } updateMorphTargets() { const geometry = this.geometry; 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 m2 = 0, ml = morphAttribute.length; m2 < ml; m2++) { const name = morphAttribute[m2].name || String(m2); this.morphTargetInfluences.push(0); this.morphTargetDictionary[name] = m2; } } } } }; function checkIntersection(object, raycaster, ray, thresholdSq, a2, b) { const positionAttribute = object.geometry.attributes.position; _vStart.fromBufferAttribute(positionAttribute, a2); _vEnd.fromBufferAttribute(positionAttribute, b); const distSq = ray.distanceSqToSegment(_vStart, _vEnd, _intersectPointOnRay, _intersectPointOnSegment); if (distSq > thresholdSq) return; _intersectPointOnRay.applyMatrix4(object.matrixWorld); const distance2 = raycaster.ray.origin.distanceTo(_intersectPointOnRay); if (distance2 < raycaster.near || distance2 > raycaster.far) return; return { distance: distance2, // What do we want? intersection point on the ray or on the segment?? // point: raycaster.ray.at( distance ), point: _intersectPointOnSegment.clone().applyMatrix4(object.matrixWorld), index: a2, face: null, faceIndex: null, barycoord: null, object }; } var Curve = class { constructor() { this.type = "Curve"; this.arcLengthDivisions = 200; } // Virtual base class method to overwrite and implement in subclasses // - t [0 .. 1] getPoint() { console.warn("THREE.Curve: .getPoint() not implemented."); return null; } // Get point at relative position in curve according to arc length // - u [0 .. 1] getPointAt(u, optionalTarget) { const t = this.getUtoTmapping(u); return this.getPoint(t, optionalTarget); } // Get sequence of points using getPoint( t ) getPoints(divisions = 5) { const points = []; for (let d = 0; d <= divisions; d++) { points.push(this.getPoint(d / divisions)); } return points; } // Get sequence of points using getPointAt( u ) getSpacedPoints(divisions = 5) { const points = []; for (let d = 0; d <= divisions; d++) { points.push(this.getPointAt(d / divisions)); } return points; } // Get total curve arc length getLength() { const lengths = this.getLengths(); return lengths[lengths.length - 1]; } // Get list of cumulative segment lengths getLengths(divisions = this.arcLengthDivisions) { if (this.cacheArcLengths && this.cacheArcLengths.length === divisions + 1 && !this.needsUpdate) { return this.cacheArcLengths; } this.needsUpdate = false; const cache2 = []; let current, last = this.getPoint(0); let sum = 0; cache2.push(0); for (let p = 1; p <= divisions; p++) { current = this.getPoint(p / divisions); sum += current.distanceTo(last); cache2.push(sum); last = current; } this.cacheArcLengths = cache2; return cache2; } updateArcLengths() { this.needsUpdate = true; this.getLengths(); } // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant getUtoTmapping(u, distance2) { const arcLengths = this.getLengths(); let i = 0; const il = arcLengths.length; let targetArcLength; if (distance2) { targetArcLength = distance2; } 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; } // Returns a unit vector tangent at t // In case any sub curve does not implement its tangent derivation, // 2 points a small delta apart will be used to find its gradient // which seems to give a reasonable approximation 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 normal2 = 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()); } normals[0] = new Vector3(); binormals[0] = new Vector3(); let min2 = 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 <= min2) { min2 = tx; normal2.set(1, 0, 0); } if (ty <= min2) { min2 = ty; normal2.set(0, 1, 0); } if (tz <= min2) { normal2.set(0, 0, 1); } vec.crossVectors(tangents[0], normal2).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.6, 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.isEllipseCurve = true; 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 = new Vector2()) { const point = optionalTarget; 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 x2 = this.aX + this.xRadius * Math.cos(angle); let y2 = this.aY + this.yRadius * Math.sin(angle); if (this.aRotation !== 0) { const cos2 = Math.cos(this.aRotation); const sin2 = Math.sin(this.aRotation); const tx = x2 - this.aX; const ty = y2 - this.aY; x2 = tx * cos2 - ty * sin2 + this.aX; y2 = tx * sin2 + ty * cos2 + this.aY; } return point.set(x2, y2); } 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; } }; var ArcCurve = class extends EllipseCurve { constructor(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { super(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise); this.isArcCurve = true; this.type = "ArcCurve"; } }; function CubicPoly() { let c0 = 0, c1 = 0, c2 = 0, c3 = 0; function init4(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) { init4(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; init4(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 = /* @__PURE__ */ new Vector3(); var px = /* @__PURE__ */ new CubicPoly(); var py = /* @__PURE__ */ new CubicPoly(); var pz = /* @__PURE__ */ new CubicPoly(); var CatmullRomCurve3 = class extends Curve { constructor(points = [], closed = false, curveType = "centripetal", tension = 0.5) { super(); this.isCatmullRomCurve3 = true; 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 p = (l - (this.closed ? 0 : 1)) * t; let intPoint = Math.floor(p); let weight = p - 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 p2 = 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 pow5 = this.curveType === "chordal" ? 0.5 : 0.25; let dt0 = Math.pow(p0.distanceToSquared(p1), pow5); let dt1 = Math.pow(p1.distanceToSquared(p2), pow5); let dt2 = Math.pow(p2.distanceToSquared(p3), pow5); if (dt1 < 1e-4) dt1 = 1; if (dt0 < 1e-4) dt0 = dt1; if (dt2 < 1e-4) dt2 = dt1; px.initNonuniformCatmullRom(p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2); py.initNonuniformCatmullRom(p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2); pz.initNonuniformCatmullRom(p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2); } else if (this.curveType === "catmullrom") { px.initCatmullRom(p0.x, p1.x, p2.x, p3.x, this.tension); py.initCatmullRom(p0.y, p1.y, p2.y, p3.y, this.tension); pz.initCatmullRom(p0.z, p1.z, p2.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; } }; function CatmullRom(t, p0, p1, p2, p3) { const v0 = (p2 - p0) * 0.5; const v1 = (p3 - p1) * 0.5; const t2 = t * t; const t3 = t * t2; return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; } function QuadraticBezierP0(t, p) { const k = 1 - t; return k * k * p; } function QuadraticBezierP1(t, p) { return 2 * (1 - t) * t * p; } function QuadraticBezierP2(t, p) { return t * t * p; } function QuadraticBezier(t, p0, p1, p2) { return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) + QuadraticBezierP2(t, p2); } function CubicBezierP0(t, p) { const k = 1 - t; return k * k * k * p; } function CubicBezierP1(t, p) { const k = 1 - t; return 3 * k * k * t * p; } function CubicBezierP2(t, p) { return 3 * (1 - t) * t * t * p; } function CubicBezierP3(t, p) { return t * t * t * p; } 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(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2()) { super(); this.isCubicBezierCurve = true; this.type = "CubicBezierCurve"; this.v0 = v0; this.v1 = v1; this.v2 = v2; this.v3 = v3; } getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3; point.set( CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.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; } }; var CubicBezierCurve3 = class extends Curve { constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3(), v3 = new Vector3()) { super(); this.isCubicBezierCurve3 = true; this.type = "CubicBezierCurve3"; this.v0 = v0; this.v1 = v1; this.v2 = v2; this.v3 = v3; } getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3; point.set( CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y), CubicBezier(t, v0.z, v1.z, v2.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; } }; var LineCurve = class extends Curve { constructor(v1 = new Vector2(), v2 = new Vector2()) { super(); this.isLineCurve = true; this.type = "LineCurve"; this.v1 = v1; this.v2 = v2; } 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; } // Line curve is linear, so we can overwrite default getPointAt getPointAt(u, optionalTarget) { return this.getPoint(u, optionalTarget); } getTangent(t, optionalTarget = new Vector2()) { return optionalTarget.subVectors(this.v2, this.v1).normalize(); } getTangentAt(u, optionalTarget) { return this.getTangent(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 LineCurve3 = class extends Curve { constructor(v1 = new Vector3(), v2 = new Vector3()) { super(); this.isLineCurve3 = true; this.type = "LineCurve3"; this.v1 = v1; this.v2 = v2; } 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; } // Line curve is linear, so we can overwrite default getPointAt getPointAt(u, optionalTarget) { return this.getPoint(u, optionalTarget); } getTangent(t, optionalTarget = new Vector3()) { return optionalTarget.subVectors(this.v2, this.v1).normalize(); } getTangentAt(u, optionalTarget) { return this.getTangent(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(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2()) { super(); this.isQuadraticBezierCurve = true; this.type = "QuadraticBezierCurve"; this.v0 = v0; this.v1 = v1; this.v2 = v2; } getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const v0 = this.v0, v1 = this.v1, v2 = this.v2; point.set( QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.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; } }; var QuadraticBezierCurve3 = class extends Curve { constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3()) { super(); this.isQuadraticBezierCurve3 = true; this.type = "QuadraticBezierCurve3"; this.v0 = v0; this.v1 = v1; this.v2 = v2; } getPoint(t, optionalTarget = new Vector3()) { const point = optionalTarget; const v0 = this.v0, v1 = this.v1, v2 = this.v2; point.set( QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y), QuadraticBezier(t, v0.z, v1.z, v2.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; } }; var SplineCurve = class extends Curve { constructor(points = []) { super(); this.isSplineCurve = true; this.type = "SplineCurve"; this.points = points; } getPoint(t, optionalTarget = new Vector2()) { const point = optionalTarget; const points = this.points; const p = (points.length - 1) * t; const intPoint = Math.floor(p); const weight = p - intPoint; const p0 = points[intPoint === 0 ? intPoint : intPoint - 1]; const p1 = points[intPoint]; const p2 = 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, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.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; } }; var Curves = /* @__PURE__ */ Object.freeze({ __proto__: null, ArcCurve, CatmullRomCurve3, CubicBezierCurve, CubicBezierCurve3, EllipseCurve, LineCurve, LineCurve3, QuadraticBezierCurve, QuadraticBezierCurve3, SplineCurve }); var CylinderGeometry = class _CylinderGeometry extends BufferGeometry { constructor(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) { super(); this.type = "CylinderGeometry"; this.parameters = { radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }; const scope = this; radialSegments = Math.floor(radialSegments); heightSegments = Math.floor(heightSegments); const indices = []; const vertices = []; const normals = []; const uvs = []; let index5 = 0; const indexArray = []; const halfHeight = height / 2; let groupStart = 0; generateTorso(); if (openEnded === false) { if (radiusTop > 0) generateCap(true); if (radiusBottom > 0) generateCap(false); } 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 generateTorso() { const normal2 = new Vector3(); const vertex2 = new Vector3(); let groupCount = 0; const slope = (radiusBottom - radiusTop) / height; for (let y2 = 0; y2 <= heightSegments; y2++) { const indexRow = []; const v = y2 / heightSegments; const radius = v * (radiusBottom - radiusTop) + radiusTop; for (let x2 = 0; x2 <= radialSegments; x2++) { const u = x2 / radialSegments; const theta = u * thetaLength + thetaStart; const sinTheta = Math.sin(theta); const cosTheta = Math.cos(theta); vertex2.x = radius * sinTheta; vertex2.y = -v * height + halfHeight; vertex2.z = radius * cosTheta; vertices.push(vertex2.x, vertex2.y, vertex2.z); normal2.set(sinTheta, slope, cosTheta).normalize(); normals.push(normal2.x, normal2.y, normal2.z); uvs.push(u, 1 - v); indexRow.push(index5++); } indexArray.push(indexRow); } for (let x2 = 0; x2 < radialSegments; x2++) { for (let y2 = 0; y2 < heightSegments; y2++) { const a2 = indexArray[y2][x2]; const b = indexArray[y2 + 1][x2]; const c2 = indexArray[y2 + 1][x2 + 1]; const d = indexArray[y2][x2 + 1]; if (radiusTop > 0 || y2 !== 0) { indices.push(a2, b, d); groupCount += 3; } if (radiusBottom > 0 || y2 !== heightSegments - 1) { indices.push(b, c2, d); groupCount += 3; } } } scope.addGroup(groupStart, groupCount, 0); groupStart += groupCount; } function generateCap(top) { const centerIndexStart = index5; const uv2 = new Vector2(); const vertex2 = new Vector3(); let groupCount = 0; const radius = top === true ? radiusTop : radiusBottom; const sign2 = top === true ? 1 : -1; for (let x2 = 1; x2 <= radialSegments; x2++) { vertices.push(0, halfHeight * sign2, 0); normals.push(0, sign2, 0); uvs.push(0.5, 0.5); index5++; } const centerIndexEnd = index5; for (let x2 = 0; x2 <= radialSegments; x2++) { const u = x2 / radialSegments; const theta = u * thetaLength + thetaStart; const cosTheta = Math.cos(theta); const sinTheta = Math.sin(theta); vertex2.x = radius * sinTheta; vertex2.y = halfHeight * sign2; vertex2.z = radius * cosTheta; vertices.push(vertex2.x, vertex2.y, vertex2.z); normals.push(0, sign2, 0); uv2.x = cosTheta * 0.5 + 0.5; uv2.y = sinTheta * 0.5 * sign2 + 0.5; uvs.push(uv2.x, uv2.y); index5++; } for (let x2 = 0; x2 < radialSegments; x2++) { const c2 = centerIndexStart + x2; const i = centerIndexEnd + x2; if (top === true) { indices.push(i, i + 1, c2); } else { indices.push(i + 1, i, c2); } groupCount += 3; } scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); groupStart += groupCount; } } copy(source) { super.copy(source); this.parameters = Object.assign({}, source.parameters); return this; } static fromJSON(data) { return new _CylinderGeometry(data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); } }; var ConeGeometry = class _ConeGeometry extends CylinderGeometry { constructor(radius = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) { super(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength); this.type = "ConeGeometry"; this.parameters = { radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength }; } static fromJSON(data) { return new _ConeGeometry(data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength); } }; var SphereGeometry = class _SphereGeometry extends BufferGeometry { constructor(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI) { super(); this.type = "SphereGeometry"; this.parameters = { radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength }; widthSegments = Math.max(3, Math.floor(widthSegments)); heightSegments = Math.max(2, Math.floor(heightSegments)); const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI); let index5 = 0; const grid = []; const vertex2 = new Vector3(); const normal2 = new Vector3(); const indices = []; const vertices = []; const normals = []; const uvs = []; for (let iy = 0; iy <= heightSegments; iy++) { const verticesRow = []; const v = iy / heightSegments; let uOffset = 0; if (iy === 0 && thetaStart === 0) { uOffset = 0.5 / widthSegments; } else if (iy === heightSegments && thetaEnd === Math.PI) { uOffset = -0.5 / widthSegments; } for (let ix = 0; ix <= widthSegments; ix++) { const u = ix / widthSegments; vertex2.x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); vertex2.y = radius * Math.cos(thetaStart + v * thetaLength); vertex2.z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); vertices.push(vertex2.x, vertex2.y, vertex2.z); normal2.copy(vertex2).normalize(); normals.push(normal2.x, normal2.y, normal2.z); uvs.push(u + uOffset, 1 - v); verticesRow.push(index5++); } grid.push(verticesRow); } for (let iy = 0; iy < heightSegments; iy++) { for (let ix = 0; ix < widthSegments; ix++) { const a2 = grid[iy][ix + 1]; const b = grid[iy][ix]; const c2 = grid[iy + 1][ix]; const d = grid[iy + 1][ix + 1]; if (iy !== 0 || thetaStart > 0) indices.push(a2, b, d); if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, 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)); } copy(source) { super.copy(source); this.parameters = Object.assign({}, source.parameters); return this; } static fromJSON(data) { return new _SphereGeometry(data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength); } }; var TubeGeometry = class _TubeGeometry extends BufferGeometry { constructor(path = new QuadraticBezierCurve3(new Vector3(-1, -1, 0), new Vector3(-1, 1, 0), new Vector3(1, 1, 0)), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false) { super(); this.type = "TubeGeometry"; this.parameters = { path, tubularSegments, radius, radialSegments, closed }; const frames = path.computeFrenetFrames(tubularSegments, closed); this.tangents = frames.tangents; this.normals = frames.normals; this.binormals = frames.binormals; const vertex2 = new Vector3(); const normal2 = new Vector3(); const uv2 = new Vector2(); let P = new Vector3(); const vertices = []; const normals = []; const uvs = []; const indices = []; generateBufferData(); 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 generateBufferData() { for (let i = 0; i < tubularSegments; i++) { generateSegment(i); } generateSegment(closed === false ? tubularSegments : 0); generateUVs(); generateIndices(); } function generateSegment(i) { P = path.getPointAt(i / tubularSegments, P); const N = frames.normals[i]; const B = frames.binormals[i]; for (let j = 0; j <= radialSegments; j++) { const v = j / radialSegments * Math.PI * 2; const sin2 = Math.sin(v); const cos2 = -Math.cos(v); normal2.x = cos2 * N.x + sin2 * B.x; normal2.y = cos2 * N.y + sin2 * B.y; normal2.z = cos2 * N.z + sin2 * B.z; normal2.normalize(); normals.push(normal2.x, normal2.y, normal2.z); vertex2.x = P.x + radius * normal2.x; vertex2.y = P.y + radius * normal2.y; vertex2.z = P.z + radius * normal2.z; vertices.push(vertex2.x, vertex2.y, vertex2.z); } } function generateIndices() { for (let j = 1; j <= tubularSegments; j++) { for (let i = 1; i <= radialSegments; i++) { const a2 = (radialSegments + 1) * (j - 1) + (i - 1); const b = (radialSegments + 1) * j + (i - 1); const c2 = (radialSegments + 1) * j + i; const d = (radialSegments + 1) * (j - 1) + i; indices.push(a2, b, d); indices.push(b, c2, d); } } } function generateUVs() { for (let i = 0; i <= tubularSegments; i++) { for (let j = 0; j <= radialSegments; j++) { uv2.x = i / tubularSegments; uv2.y = j / radialSegments; uvs.push(uv2.x, uv2.y); } } } } copy(source) { super.copy(source); this.parameters = Object.assign({}, source.parameters); return this; } toJSON() { const data = super.toJSON(); data.path = this.parameters.path.toJSON(); return data; } static fromJSON(data) { return new _TubeGeometry( new Curves[data.path.type]().fromJSON(data.path), data.tubularSegments, data.radius, data.radialSegments, data.closed ); } }; var MeshLambertMaterial = class extends Material { static get type() { return "MeshLambertMaterial"; } constructor(parameters) { super(); this.isMeshLambertMaterial = true; 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.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.envMapRotation = new Euler(); 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.fog = true; 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.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.envMapRotation.copy(source.envMapRotation); 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; this.fog = source.fog; return this; } }; function convertArray(array, type, forceClone) { if (!array || // let 'undefined' and 'null' pass !forceClone && array.constructor === type) return array; if (typeof type.BYTES_PER_ELEMENT === "number") { return new type(array); } return Array.prototype.slice.call(array); } function isTypedArray(object) { return ArrayBuffer.isView(object) && !(object instanceof DataView); } 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.copySampleValue_(i1 - 1); } 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.copySampleValue_(0); } 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.copySampleValue_(0); } if (t1 === void 0) { i1 = pp.length; this._cachedIndex = i1; return this.copySampleValue_(i1 - 1); } } this._cachedIndex = i1; this.intervalChanged_(i1, t0, t1); } return this.interpolate_(i1, t0, t, t1); } getSettings_() { return this.settings || this.DefaultSettings_; } copySampleValue_(index5) { const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, offset = index5 * stride; for (let i = 0; i !== stride; ++i) { result[i] = values[offset + i]; } return result; } // Template methods for derived classes: interpolate_() { throw new Error("call to abstract method"); } intervalChanged_() { } }; 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, p = (t - t0) / (t1 - t0), pp = p * p, ppp = pp * p; const sP = -wP * ppp + 2 * wP * pp - wP * p; const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1; const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p; 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 = convertArray(times, this.TimeBufferType); this.values = convertArray(values, this.ValueBufferType); this.setInterpolation(interpolation || this.DefaultInterpolation); } // Serialization (in static context, because of constructor invocation // and automatic invocation of .toJSON): static toJSON(track) { const trackType = track.constructor; let json; if (trackType.toJSON !== this.toJSON) { json = trackType.toJSON(track); } else { json = { "name": track.name, "times": convertArray(track.times, Array), "values": 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; } // move all keyframes either forwards or backwards in time 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 all keyframe times by a factor (useful for frame <-> seconds conversions) scale(timeScale) { if (timeScale !== 1) { const times = this.times; for (let i = 0, n = times.length; i !== n; ++i) { times[i] *= timeScale; } } return this; } // removes keyframes before and after animation without changing any values within the range [startTime, endTime]. // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values 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 = times.slice(from, to); this.values = this.values.slice(from * stride, to * stride); } return this; } // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable 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 (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; } // removes equivalent sequential keys as common in morph target sequences // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) optimize() { const times = this.times.slice(), values = this.values.slice(), 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 = times.slice(0, writeIndex); this.values = values.slice(0, writeIndex * stride); } else { this.times = times; this.values = values; } return this; } clone() { const times = this.times.slice(); const values = this.values.slice(); 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 { // No interpolation parameter because only InterpolateDiscrete is valid. constructor(name, times, values) { super(name, times, values); } }; 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.InterpolantFactoryMethodSmooth = void 0; var StringKeyframeTrack = class extends KeyframeTrack { // No interpolation parameter because only InterpolateDiscrete is valid. constructor(name, times, values) { super(name, times, values); } }; 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 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 index5 = handlers.indexOf(regex); if (index5 !== -1) { handlers.splice(index5, 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 = /* @__PURE__ */ 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(resolve, reject) { scope.load(url, resolve, onProgress, reject); }); } 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; } }; Loader.DEFAULT_MATERIAL_NAME = "__DEFAULT"; 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 = createElementNS("img"); function onImageLoad() { removeEventListeners(); Cache.add(url, this); if (onLoad) onLoad(this); scope.manager.itemEnd(url); } function onImageError(event) { removeEventListeners(); if (onError) onError(event); scope.manager.itemError(url); scope.manager.itemEnd(url); } function removeEventListeners() { image.removeEventListener("load", onImageLoad, false); image.removeEventListener("error", onImageError, false); } image.addEventListener("load", onImageLoad, false); image.addEventListener("error", onImageError, false); if (url.slice(0, 5) !== "data:") { if (this.crossOrigin !== void 0) image.crossOrigin = this.crossOrigin; } scope.manager.itemStart(url); image.src = url; return image; } }; var TextureLoader = class extends Loader { constructor(manager) { super(manager); } load(url, onLoad, onProgress, onError) { const texture2 = new Texture(); const loader = new ImageLoader(this.manager); loader.setCrossOrigin(this.crossOrigin); loader.setPath(this.path); loader.load(url, function(image) { texture2.image = image; texture2.needsUpdate = true; if (onLoad !== void 0) { onLoad(texture2); } }, onProgress, onError); return texture2; } }; var Light = class extends Object3D { constructor(color2, intensity = 1) { super(); this.isLight = true; this.type = "Light"; this.color = new Color(color2); this.intensity = intensity; } dispose() { } copy(source, recursive) { super.copy(source, recursive); 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(); if (this.target !== void 0) data.object.target = this.target.uuid; return data; } }; var _projScreenMatrix$1 = /* @__PURE__ */ new Matrix4(); var _lightPositionWorld$1 = /* @__PURE__ */ new Vector3(); var _lookTarget$1 = /* @__PURE__ */ new Vector3(); var LightShadow = class { constructor(camera3) { this.camera = camera3; this.intensity = 1; 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(_projScreenMatrix$1); } 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.intensity = source.intensity; 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.intensity !== 1) object.intensity = this.intensity; 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 DirectionalLightShadow = class extends LightShadow { constructor() { super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500)); this.isDirectionalLightShadow = true; } }; var DirectionalLight = class extends Light { constructor(color2, intensity) { super(color2, intensity); this.isDirectionalLight = true; this.type = "DirectionalLight"; this.position.copy(Object3D.DEFAULT_UP); 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; } }; var AmbientLight = class extends Light { constructor(color2, intensity) { super(color2, intensity); this.isAmbientLight = true; this.type = "AmbientLight"; } }; var Clock = class { constructor(autoStart = true) { this.autoStart = autoStart; this.startTime = 0; this.oldTime = 0; this.elapsedTime = 0; this.running = false; } start() { this.startTime = now(); this.oldTime = this.startTime; this.elapsedTime = 0; this.running = true; } stop() { this.getElapsedTime(); this.running = false; this.autoStart = false; } getElapsedTime() { this.getDelta(); return this.elapsedTime; } getDelta() { let diff = 0; if (this.autoStart && !this.running) { this.start(); return 0; } if (this.running) { const newTime = now(); diff = (newTime - this.oldTime) / 1e3; this.oldTime = newTime; this.elapsedTime += diff; } return diff; } }; function now() { return performance.now(); } 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 = /* @__PURE__ */ /((?:WC+[\/:])*)/.source.replace("WC", _wordChar); var _nodeRe = /* @__PURE__ */ /(WCOD+)?/.source.replace("WCOD", _wordCharOrDot); var _objectRe = /* @__PURE__ */ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC", _wordChar); var _propertyRe = /* @__PURE__ */ /\.(WC+)(?:\[(.+)\])?/.source.replace("WC", _wordChar); var _trackRe = new RegExp( "^" + _directoryRe + _nodeRe + _objectRe + _propertyRe + "$" ); var _supportedObjectNames = ["material", "materials", "bones", "map"]; 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 _PropertyBinding { constructor(rootNode, path, parsedPath) { this.path = path; this.parsedPath = parsedPath || _PropertyBinding.parseTrackName(path); this.node = _PropertyBinding.findNode(rootNode, this.parsedPath.nodeName); this.rootNode = rootNode; this.getValue = this._getValue_unbound; this.setValue = this._setValue_unbound; } static create(root2, path, parsedPath) { if (!(root2 && root2.isAnimationObjectGroup)) { return new _PropertyBinding(root2, path, parsedPath); } else { return new _PropertyBinding.Composite(root2, path, parsedPath); } } /** * Replaces spaces with underscores and removes unsupported characters from * node names, to ensure compatibility with parseTrackName(). * * @param {string} name Node name to be sanitized. * @return {string} */ static sanitizeNodeName(name) { return name.replace(/\s/g, "_").replace(_reservedRe, ""); } static parseTrackName(trackName) { const matches = _trackRe.exec(trackName); if (matches === null) { throw new Error("PropertyBinding: Cannot parse trackName: " + trackName); } const results = { // directoryName: matches[ 1 ], // (tschw) currently unused nodeName: matches[2], objectName: matches[3], objectIndex: matches[4], propertyName: matches[5], // required 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(root2, nodeName) { if (nodeName === void 0 || nodeName === "" || nodeName === "." || nodeName === -1 || nodeName === root2.name || nodeName === root2.uuid) { return root2; } if (root2.skeleton) { const bone = root2.skeleton.getBoneByName(nodeName); if (bone !== void 0) { return bone; } } if (root2.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(root2.children); if (subTreeNode) { return subTreeNode; } } return null; } // these are used to "bind" a nonexistent property _getValue_unavailable() { } _setValue_unavailable() { } // Getters _getValue_direct(buffer2, offset) { buffer2[offset] = this.targetObject[this.propertyName]; } _getValue_array(buffer2, offset) { const source = this.resolvedProperty; for (let i = 0, n = source.length; i !== n; ++i) { buffer2[offset++] = source[i]; } } _getValue_arrayElement(buffer2, offset) { buffer2[offset] = this.resolvedProperty[this.propertyIndex]; } _getValue_toArray(buffer2, offset) { this.resolvedProperty.toArray(buffer2, offset); } // Direct _setValue_direct(buffer2, offset) { this.targetObject[this.propertyName] = buffer2[offset]; } _setValue_direct_setNeedsUpdate(buffer2, offset) { this.targetObject[this.propertyName] = buffer2[offset]; this.targetObject.needsUpdate = true; } _setValue_direct_setMatrixWorldNeedsUpdate(buffer2, offset) { this.targetObject[this.propertyName] = buffer2[offset]; this.targetObject.matrixWorldNeedsUpdate = true; } // EntireArray _setValue_array(buffer2, offset) { const dest = this.resolvedProperty; for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer2[offset++]; } } _setValue_array_setNeedsUpdate(buffer2, offset) { const dest = this.resolvedProperty; for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer2[offset++]; } this.targetObject.needsUpdate = true; } _setValue_array_setMatrixWorldNeedsUpdate(buffer2, offset) { const dest = this.resolvedProperty; for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer2[offset++]; } this.targetObject.matrixWorldNeedsUpdate = true; } // ArrayElement _setValue_arrayElement(buffer2, offset) { this.resolvedProperty[this.propertyIndex] = buffer2[offset]; } _setValue_arrayElement_setNeedsUpdate(buffer2, offset) { this.resolvedProperty[this.propertyIndex] = buffer2[offset]; this.targetObject.needsUpdate = true; } _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer2, offset) { this.resolvedProperty[this.propertyIndex] = buffer2[offset]; this.targetObject.matrixWorldNeedsUpdate = true; } // HasToFromArray _setValue_fromArray(buffer2, offset) { this.resolvedProperty.fromArray(buffer2, offset); } _setValue_fromArray_setNeedsUpdate(buffer2, offset) { this.resolvedProperty.fromArray(buffer2, offset); this.targetObject.needsUpdate = true; } _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer2, offset) { this.resolvedProperty.fromArray(buffer2, 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); } // create getter / setter pair for a property in the scene graph 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.node = targetObject; } this.getValue = this._getValue_unavailable; this.setValue = this._setValue_unavailable; if (!targetObject) { console.warn("THREE.PropertyBinding: No target node found for track: " + this.path + "."); 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; case "map": if ("map" in targetObject) { targetObject = targetObject.map; break; } if (!targetObject.material) { console.error("THREE.PropertyBinding: Can not bind to material as node does not have a material.", this); return; } if (!targetObject.material.map) { console.error("THREE.PropertyBinding: Can not bind to material.map as node.material does not have a map.", this); return; } targetObject = targetObject.material.map; 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.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]; } } 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 = [ [ // Direct PropertyBinding.prototype._setValue_direct, PropertyBinding.prototype._setValue_direct_setNeedsUpdate, PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate ], [ // EntireArray PropertyBinding.prototype._setValue_array, PropertyBinding.prototype._setValue_array_setNeedsUpdate, PropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate ], [ // ArrayElement PropertyBinding.prototype._setValue_arrayElement, PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate, PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate ], [ // HasToFromArray PropertyBinding.prototype._setValue_fromArray, PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate ] ]; var _controlInterpolantsResultBuffer = new Float32Array(1); var _matrix = /* @__PURE__ */ new Matrix4(); var Raycaster = class { constructor(origin, direction2, near = 0, far = Infinity) { this.ray = new Ray(origin, direction2); this.near = near; this.far = far; this.camera = null; this.layers = new Layers(); this.params = { Mesh: {}, Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} }; } set(origin, direction2) { this.ray.set(origin, direction2); } setFromCamera(coords, camera3) { if (camera3.isPerspectiveCamera) { this.ray.origin.setFromMatrixPosition(camera3.matrixWorld); this.ray.direction.set(coords.x, coords.y, 0.5).unproject(camera3).sub(this.ray.origin).normalize(); this.camera = camera3; } else if (camera3.isOrthographicCamera) { this.ray.origin.set(coords.x, coords.y, (camera3.near + camera3.far) / (camera3.near - camera3.far)).unproject(camera3); this.ray.direction.set(0, 0, -1).transformDirection(camera3.matrixWorld); this.camera = camera3; } else { console.error("THREE.Raycaster: Unsupported camera type: " + camera3.type); } } setFromXRController(controller) { _matrix.identity().extractRotation(controller.matrixWorld); this.ray.origin.setFromMatrixPosition(controller.matrixWorld); this.ray.direction.set(0, 0, -1).applyMatrix4(_matrix); return this; } intersectObject(object, recursive = true, intersects = []) { intersect(object, this, intersects, recursive); intersects.sort(ascSort); return intersects; } intersectObjects(objects, recursive = true, intersects = []) { for (let i = 0, l = objects.length; i < l; i++) { intersect(objects[i], this, intersects, recursive); } intersects.sort(ascSort); return intersects; } }; function ascSort(a2, b) { return a2.distance - b.distance; } function intersect(object, raycaster, intersects, recursive) { let propagate = true; if (object.layers.test(raycaster.layers)) { const result = object.raycast(raycaster, intersects); if (result === false) propagate = false; } if (propagate === true && recursive === true) { const children = object.children; for (let i = 0, l = children.length; i < l; i++) { intersect(children[i], raycaster, intersects, true); } } } var Spherical = class { constructor(radius = 1, phi = 0, theta = 0) { this.radius = radius; this.phi = phi; this.theta = theta; return this; } set(radius, phi, theta) { this.radius = radius; this.phi = phi; this.theta = theta; return this; } copy(other) { this.radius = other.radius; this.phi = other.phi; this.theta = other.theta; return this; } // restrict phi to be between EPS and PI-EPS makeSafe() { const EPS = 1e-6; this.phi = Math.max(EPS, Math.min(Math.PI - EPS, this.phi)); return this; } setFromVector3(v) { return this.setFromCartesianCoords(v.x, v.y, v.z); } setFromCartesianCoords(x2, y2, z2) { this.radius = Math.sqrt(x2 * x2 + y2 * y2 + z2 * z2); if (this.radius === 0) { this.theta = 0; this.phi = 0; } else { this.theta = Math.atan2(x2, z2); this.phi = Math.acos(clamp(y2 / this.radius, -1, 1)); } return this; } clone() { return new this.constructor().copy(this); } }; var Controls = class extends EventDispatcher { constructor(object, domElement = null) { super(); this.object = object; this.domElement = domElement; this.enabled = true; this.state = -1; this.keys = {}; this.mouseButtons = { LEFT: null, MIDDLE: null, RIGHT: null }; this.touches = { ONE: null, TWO: null }; } connect() { } disconnect() { } dispose() { } update() { } }; 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/three/examples/jsm/controls/DragControls.js var _plane = new Plane(); var _pointer = new Vector2(); var _offset2 = new Vector3(); var _diff2 = new Vector2(); var _previousPointer = new Vector2(); var _intersection = new Vector3(); var _worldPosition = new Vector3(); var _inverseMatrix = new Matrix4(); var _up = new Vector3(); var _right = new Vector3(); var _selected = null; var _hovered = null; var _intersections = []; var STATE = { NONE: -1, PAN: 0, ROTATE: 1 }; var DragControls = class extends Controls { constructor(objects, camera3, domElement = null) { super(camera3, domElement); this.objects = objects; this.recursive = true; this.transformGroup = false; this.rotateSpeed = 1; this.raycaster = new Raycaster(); this.mouseButtons = { LEFT: MOUSE.PAN, MIDDLE: MOUSE.PAN, RIGHT: MOUSE.ROTATE }; this.touches = { ONE: TOUCH.PAN }; this._onPointerMove = onPointerMove.bind(this); this._onPointerDown = onPointerDown.bind(this); this._onPointerCancel = onPointerCancel.bind(this); this._onContextMenu = onContextMenu.bind(this); if (domElement !== null) { this.connect(); } } connect() { this.domElement.addEventListener("pointermove", this._onPointerMove); this.domElement.addEventListener("pointerdown", this._onPointerDown); this.domElement.addEventListener("pointerup", this._onPointerCancel); this.domElement.addEventListener("pointerleave", this._onPointerCancel); this.domElement.addEventListener("contextmenu", this._onContextMenu); this.domElement.style.touchAction = "none"; } disconnect() { this.domElement.removeEventListener("pointermove", this._onPointerMove); this.domElement.removeEventListener("pointerdown", this._onPointerDown); this.domElement.removeEventListener("pointerup", this._onPointerCancel); this.domElement.removeEventListener("pointerleave", this._onPointerCancel); this.domElement.removeEventListener("contextmenu", this._onContextMenu); this.domElement.style.touchAction = "auto"; this.domElement.style.cursor = ""; } dispose() { this.disconnect(); } _updatePointer(event) { const rect = this.domElement.getBoundingClientRect(); _pointer.x = (event.clientX - rect.left) / rect.width * 2 - 1; _pointer.y = -(event.clientY - rect.top) / rect.height * 2 + 1; } _updateState(event) { let action; if (event.pointerType === "touch") { action = this.touches.ONE; } else { switch (event.button) { case 0: action = this.mouseButtons.LEFT; break; case 1: action = this.mouseButtons.MIDDLE; break; case 2: action = this.mouseButtons.RIGHT; break; default: action = null; } } switch (action) { case MOUSE.PAN: case TOUCH.PAN: this.state = STATE.PAN; break; case MOUSE.ROTATE: case TOUCH.ROTATE: this.state = STATE.ROTATE; break; default: this.state = STATE.NONE; } } getRaycaster() { console.warn("THREE.DragControls: getRaycaster() has been deprecated. Use controls.raycaster instead."); return this.raycaster; } setObjects(objects) { console.warn("THREE.DragControls: setObjects() has been deprecated. Use controls.objects instead."); this.objects = objects; } getObjects() { console.warn("THREE.DragControls: getObjects() has been deprecated. Use controls.objects instead."); return this.objects; } activate() { console.warn("THREE.DragControls: activate() has been renamed to connect()."); this.connect(); } deactivate() { console.warn("THREE.DragControls: deactivate() has been renamed to disconnect()."); this.disconnect(); } set mode(value) { console.warn("THREE.DragControls: The .mode property has been removed. Define the type of transformation via the .mouseButtons or .touches properties."); } get mode() { console.warn("THREE.DragControls: The .mode property has been removed. Define the type of transformation via the .mouseButtons or .touches properties."); } }; function onPointerMove(event) { const camera3 = this.object; const domElement = this.domElement; const raycaster = this.raycaster; if (this.enabled === false) return; this._updatePointer(event); raycaster.setFromCamera(_pointer, camera3); if (_selected) { if (this.state === STATE.PAN) { if (raycaster.ray.intersectPlane(_plane, _intersection)) { _selected.position.copy(_intersection.sub(_offset2).applyMatrix4(_inverseMatrix)); } } else if (this.state === STATE.ROTATE) { _diff2.subVectors(_pointer, _previousPointer).multiplyScalar(this.rotateSpeed); _selected.rotateOnWorldAxis(_up, _diff2.x); _selected.rotateOnWorldAxis(_right.normalize(), -_diff2.y); } this.dispatchEvent({ type: "drag", object: _selected }); _previousPointer.copy(_pointer); } else { if (event.pointerType === "mouse" || event.pointerType === "pen") { _intersections.length = 0; raycaster.setFromCamera(_pointer, camera3); raycaster.intersectObjects(this.objects, this.recursive, _intersections); if (_intersections.length > 0) { const object = _intersections[0].object; _plane.setFromNormalAndCoplanarPoint(camera3.getWorldDirection(_plane.normal), _worldPosition.setFromMatrixPosition(object.matrixWorld)); if (_hovered !== object && _hovered !== null) { this.dispatchEvent({ type: "hoveroff", object: _hovered }); domElement.style.cursor = "auto"; _hovered = null; } if (_hovered !== object) { this.dispatchEvent({ type: "hoveron", object }); domElement.style.cursor = "pointer"; _hovered = object; } } else { if (_hovered !== null) { this.dispatchEvent({ type: "hoveroff", object: _hovered }); domElement.style.cursor = "auto"; _hovered = null; } } } } _previousPointer.copy(_pointer); } function onPointerDown(event) { const camera3 = this.object; const domElement = this.domElement; const raycaster = this.raycaster; if (this.enabled === false) return; this._updatePointer(event); this._updateState(event); _intersections.length = 0; raycaster.setFromCamera(_pointer, camera3); raycaster.intersectObjects(this.objects, this.recursive, _intersections); if (_intersections.length > 0) { if (this.transformGroup === true) { _selected = findGroup(_intersections[0].object); } else { _selected = _intersections[0].object; } _plane.setFromNormalAndCoplanarPoint(camera3.getWorldDirection(_plane.normal), _worldPosition.setFromMatrixPosition(_selected.matrixWorld)); if (raycaster.ray.intersectPlane(_plane, _intersection)) { if (this.state === STATE.PAN) { _inverseMatrix.copy(_selected.parent.matrixWorld).invert(); _offset2.copy(_intersection).sub(_worldPosition.setFromMatrixPosition(_selected.matrixWorld)); } else if (this.state === STATE.ROTATE) { _up.set(0, 1, 0).applyQuaternion(camera3.quaternion).normalize(); _right.set(1, 0, 0).applyQuaternion(camera3.quaternion).normalize(); } } domElement.style.cursor = "move"; this.dispatchEvent({ type: "dragstart", object: _selected }); } _previousPointer.copy(_pointer); } function onPointerCancel() { if (this.enabled === false) return; if (_selected) { this.dispatchEvent({ type: "dragend", object: _selected }); _selected = null; } this.domElement.style.cursor = _hovered ? "pointer" : "auto"; this.state = STATE.NONE; } function onContextMenu(event) { if (this.enabled === false) return; event.preventDefault(); } function findGroup(obj, group = null) { if (obj.isGroup) group = obj; if (obj.parent === null) return group; return findGroup(obj.parent, group); } // ../../node_modules/d3-force-3d/src/center.js function center_default(x2, y2, z2) { var nodes, strength = 1; if (x2 == null) x2 = 0; if (y2 == null) y2 = 0; if (z2 == null) z2 = 0; function force() { var i, n = nodes.length, node, sx = 0, sy = 0, sz = 0; for (i = 0; i < n; ++i) { node = nodes[i], sx += node.x || 0, sy += node.y || 0, sz += node.z || 0; } for (sx = (sx / n - x2) * strength, sy = (sy / n - y2) * strength, sz = (sz / n - z2) * strength, i = 0; i < n; ++i) { node = nodes[i]; if (sx) { node.x -= sx; } if (sy) { node.y -= sy; } if (sz) { node.z -= sz; } } } force.initialize = function(_) { nodes = _; }; force.x = function(_) { return arguments.length ? (x2 = +_, force) : x2; }; force.y = function(_) { return arguments.length ? (y2 = +_, force) : y2; }; force.z = function(_) { return arguments.length ? (z2 = +_, force) : z2; }; force.strength = function(_) { return arguments.length ? (strength = +_, force) : strength; }; return force; } // ../../node_modules/d3-binarytree/src/add.js function add_default(d) { const x2 = +this._x.call(null, d); return add(this.cover(x2), x2, d); } function add(tree, x2, d) { if (isNaN(x2)) return tree; var parent, node = tree._root, leaf = { data: d }, x0 = tree._x0, x1 = tree._x1, xm, xp, right, i, j; if (!node) return tree._root = leaf, tree; while (node.length) { if (right = x2 >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (parent = node, !(node = node[i = +right])) return parent[i] = leaf, tree; } xp = +tree._x.call(null, node.data); if (x2 === xp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; do { parent = parent ? parent[i] = new Array(2) : tree._root = new Array(2); if (right = x2 >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; } while ((i = +right) === (j = +(xp >= xm))); return parent[j] = node, parent[i] = leaf, tree; } function addAll(data) { if (!Array.isArray(data)) data = Array.from(data); const n = data.length; const xz = new Float64Array(n); let x0 = Infinity, x1 = -Infinity; for (let i = 0, x2; i < n; ++i) { if (isNaN(x2 = +this._x.call(null, data[i]))) continue; xz[i] = x2; if (x2 < x0) x0 = x2; if (x2 > x1) x1 = x2; } if (x0 > x1) return this; this.cover(x0).cover(x1); for (let i = 0; i < n; ++i) { add(this, xz[i], data[i]); } return this; } // ../../node_modules/d3-binarytree/src/cover.js function cover_default(x2) { if (isNaN(x2 = +x2)) return this; var x0 = this._x0, x1 = this._x1; if (isNaN(x0)) { x1 = (x0 = Math.floor(x2)) + 1; } else { var z2 = x1 - x0 || 1, node = this._root, parent, i; while (x0 > x2 || x2 >= x1) { i = +(x2 < x0); parent = new Array(2), parent[i] = node, node = parent, z2 *= 2; switch (i) { case 0: x1 = x0 + z2; break; case 1: x0 = x1 - z2; break; } } if (this._root && this._root.length) this._root = node; } this._x0 = x0; this._x1 = x1; return this; } // ../../node_modules/d3-binarytree/src/data.js function data_default() { var data = []; this.visit(function(node) { if (!node.length) do data.push(node.data); while (node = node.next); }); return data; } // ../../node_modules/d3-binarytree/src/extent.js function extent_default(_) { return arguments.length ? this.cover(+_[0][0]).cover(+_[1][0]) : isNaN(this._x0) ? void 0 : [[this._x0], [this._x1]]; } // ../../node_modules/d3-binarytree/src/half.js function half_default(node, x0, x1) { this.node = node; this.x0 = x0; this.x1 = x1; } // ../../node_modules/d3-binarytree/src/find.js function find_default(x2, radius) { var data, x0 = this._x0, x1, x22, x3 = this._x1, halves = [], node = this._root, q, i; if (node) halves.push(new half_default(node, x0, x3)); if (radius == null) radius = Infinity; else { x0 = x2 - radius; x3 = x2 + radius; } while (q = halves.pop()) { if (!(node = q.node) || (x1 = q.x0) > x3 || (x22 = q.x1) < x0) continue; if (node.length) { var xm = (x1 + x22) / 2; halves.push( new half_default(node[1], xm, x22), new half_default(node[0], x1, xm) ); if (i = +(x2 >= xm)) { q = halves[halves.length - 1]; halves[halves.length - 1] = halves[halves.length - 1 - i]; halves[halves.length - 1 - i] = q; } } else { var d = Math.abs(x2 - +this._x.call(null, node.data)); if (d < radius) { radius = d; x0 = x2 - d; x3 = x2 + d; data = node.data; } } } return data; } // ../../node_modules/d3-binarytree/src/remove.js function remove_default(d) { if (isNaN(x2 = +this._x.call(null, d))) return this; var parent, node = this._root, retainer, previous, next, x0 = this._x0, x1 = this._x1, x2, xm, right, i, j; if (!node) return this; if (node.length) while (true) { if (right = x2 >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (!(parent = node, node = node[i = +right])) return this; if (!node.length) break; if (parent[i + 1 & 1]) retainer = parent, j = i; } while (node.data !== d) if (!(previous = node, node = node.next)) return this; if (next = node.next) delete node.next; if (previous) return next ? previous.next = next : delete previous.next, this; if (!parent) return this._root = next, this; next ? parent[i] = next : delete parent[i]; if ((node = parent[0] || parent[1]) && node === (parent[1] || parent[0]) && !node.length) { if (retainer) retainer[j] = node; else this._root = node; } return this; } function removeAll(data) { for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); return this; } // ../../node_modules/d3-binarytree/src/root.js function root_default() { return this._root; } // ../../node_modules/d3-binarytree/src/size.js function size_default() { var size = 0; this.visit(function(node) { if (!node.length) do ++size; while (node = node.next); }); return size; } // ../../node_modules/d3-binarytree/src/visit.js function visit_default(callback) { var halves = [], q, node = this._root, child, x0, x1; if (node) halves.push(new half_default(node, this._x0, this._x1)); while (q = halves.pop()) { if (!callback(node = q.node, x0 = q.x0, x1 = q.x1) && node.length) { var xm = (x0 + x1) / 2; if (child = node[1]) halves.push(new half_default(child, xm, x1)); if (child = node[0]) halves.push(new half_default(child, x0, xm)); } } return this; } // ../../node_modules/d3-binarytree/src/visitAfter.js function visitAfter_default(callback) { var halves = [], next = [], q; if (this._root) halves.push(new half_default(this._root, this._x0, this._x1)); while (q = halves.pop()) { var node = q.node; if (node.length) { var child, x0 = q.x0, x1 = q.x1, xm = (x0 + x1) / 2; if (child = node[0]) halves.push(new half_default(child, x0, xm)); if (child = node[1]) halves.push(new half_default(child, xm, x1)); } next.push(q); } while (q = next.pop()) { callback(q.node, q.x0, q.x1); } return this; } // ../../node_modules/d3-binarytree/src/x.js function defaultX(d) { return d[0]; } function x_default(_) { return arguments.length ? (this._x = _, this) : this._x; } // ../../node_modules/d3-binarytree/src/binarytree.js function binarytree(nodes, x2) { var tree = new Binarytree(x2 == null ? defaultX : x2, NaN, NaN); return nodes == null ? tree : tree.addAll(nodes); } function Binarytree(x2, x0, x1) { this._x = x2; this._x0 = x0; this._x1 = x1; this._root = void 0; } function leaf_copy(leaf) { var copy = { data: leaf.data }, next = copy; while (leaf = leaf.next) next = next.next = { data: leaf.data }; return copy; } var treeProto = binarytree.prototype = Binarytree.prototype; treeProto.copy = function() { var copy = new Binarytree(this._x, this._x0, this._x1), node = this._root, nodes, child; if (!node) return copy; if (!node.length) return copy._root = leaf_copy(node), copy; nodes = [{ source: node, target: copy._root = new Array(2) }]; while (node = nodes.pop()) { for (var i = 0; i < 2; ++i) { if (child = node.source[i]) { if (child.length) nodes.push({ source: child, target: node.target[i] = new Array(2) }); else node.target[i] = leaf_copy(child); } } } return copy; }; treeProto.add = add_default; treeProto.addAll = addAll; treeProto.cover = cover_default; treeProto.data = data_default; treeProto.extent = extent_default; treeProto.find = find_default; treeProto.remove = remove_default; treeProto.removeAll = removeAll; treeProto.root = root_default; treeProto.size = size_default; treeProto.visit = visit_default; treeProto.visitAfter = visitAfter_default; treeProto.x = x_default; // ../../node_modules/d3-quadtree/src/add.js function add_default2(d) { const x2 = +this._x.call(null, d), y2 = +this._y.call(null, d); return add2(this.cover(x2, y2), x2, y2, d); } function add2(tree, x2, y2, d) { if (isNaN(x2) || isNaN(y2)) return tree; var parent, node = tree._root, leaf = { data: d }, x0 = tree._x0, y0 = tree._y0, x1 = tree._x1, y1 = tree._y1, xm, ym, xp, yp, right, bottom, i, j; if (!node) return tree._root = leaf, tree; while (node.length) { if (right = x2 >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (bottom = y2 >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree; } xp = +tree._x.call(null, node.data); yp = +tree._y.call(null, node.data); if (x2 === xp && y2 === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; do { parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4); if (right = x2 >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (bottom = y2 >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | xp >= xm)); return parent[j] = node, parent[i] = leaf, tree; } function addAll2(data) { var d, i, n = data.length, x2, y2, xz = new Array(n), yz = new Array(n), x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity; for (i = 0; i < n; ++i) { if (isNaN(x2 = +this._x.call(null, d = data[i])) || isNaN(y2 = +this._y.call(null, d))) continue; xz[i] = x2; yz[i] = y2; if (x2 < x0) x0 = x2; if (x2 > x1) x1 = x2; if (y2 < y0) y0 = y2; if (y2 > y1) y1 = y2; } if (x0 > x1 || y0 > y1) return this; this.cover(x0, y0).cover(x1, y1); for (i = 0; i < n; ++i) { add2(this, xz[i], yz[i], data[i]); } return this; } // ../../node_modules/d3-quadtree/src/cover.js function cover_default2(x2, y2) { if (isNaN(x2 = +x2) || isNaN(y2 = +y2)) return this; var x0 = this._x0, y0 = this._y0, x1 = this._x1, y1 = this._y1; if (isNaN(x0)) { x1 = (x0 = Math.floor(x2)) + 1; y1 = (y0 = Math.floor(y2)) + 1; } else { var z2 = x1 - x0 || 1, node = this._root, parent, i; while (x0 > x2 || x2 >= x1 || y0 > y2 || y2 >= y1) { i = (y2 < y0) << 1 | x2 < x0; parent = new Array(4), parent[i] = node, node = parent, z2 *= 2; switch (i) { case 0: x1 = x0 + z2, y1 = y0 + z2; break; case 1: x0 = x1 - z2, y1 = y0 + z2; break; case 2: x1 = x0 + z2, y0 = y1 - z2; break; case 3: x0 = x1 - z2, y0 = y1 - z2; break; } } if (this._root && this._root.length) this._root = node; } this._x0 = x0; this._y0 = y0; this._x1 = x1; this._y1 = y1; return this; } // ../../node_modules/d3-quadtree/src/data.js function data_default2() { var data = []; this.visit(function(node) { if (!node.length) do data.push(node.data); while (node = node.next); }); return data; } // ../../node_modules/d3-quadtree/src/extent.js function extent_default2(_) { return arguments.length ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1]) : isNaN(this._x0) ? void 0 : [[this._x0, this._y0], [this._x1, this._y1]]; } // ../../node_modules/d3-quadtree/src/quad.js function quad_default(node, x0, y0, x1, y1) { this.node = node; this.x0 = x0; this.y0 = y0; this.x1 = x1; this.y1 = y1; } // ../../node_modules/d3-quadtree/src/find.js function find_default2(x2, y2, radius) { var data, x0 = this._x0, y0 = this._y0, x1, y1, x22, y22, x3 = this._x1, y3 = this._y1, quads = [], node = this._root, q, i; if (node) quads.push(new quad_default(node, x0, y0, x3, y3)); if (radius == null) radius = Infinity; else { x0 = x2 - radius, y0 = y2 - radius; x3 = x2 + radius, y3 = y2 + radius; radius *= radius; } while (q = quads.pop()) { if (!(node = q.node) || (x1 = q.x0) > x3 || (y1 = q.y0) > y3 || (x22 = q.x1) < x0 || (y22 = q.y1) < y0) continue; if (node.length) { var xm = (x1 + x22) / 2, ym = (y1 + y22) / 2; quads.push( new quad_default(node[3], xm, ym, x22, y22), new quad_default(node[2], x1, ym, xm, y22), new quad_default(node[1], xm, y1, x22, ym), new quad_default(node[0], x1, y1, xm, ym) ); if (i = (y2 >= ym) << 1 | x2 >= xm) { q = quads[quads.length - 1]; quads[quads.length - 1] = quads[quads.length - 1 - i]; quads[quads.length - 1 - i] = q; } } else { var dx = x2 - +this._x.call(null, node.data), dy = y2 - +this._y.call(null, node.data), d2 = dx * dx + dy * dy; if (d2 < radius) { var d = Math.sqrt(radius = d2); x0 = x2 - d, y0 = y2 - d; x3 = x2 + d, y3 = y2 + d; data = node.data; } } } return data; } // ../../node_modules/d3-quadtree/src/remove.js function remove_default2(d) { if (isNaN(x2 = +this._x.call(null, d)) || isNaN(y2 = +this._y.call(null, d))) return this; var parent, node = this._root, retainer, previous, next, x0 = this._x0, y0 = this._y0, x1 = this._x1, y1 = this._y1, x2, y2, xm, ym, right, bottom, i, j; if (!node) return this; if (node.length) while (true) { if (right = x2 >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (bottom = y2 >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; if (!(parent = node, node = node[i = bottom << 1 | right])) return this; if (!node.length) break; if (parent[i + 1 & 3] || parent[i + 2 & 3] || parent[i + 3 & 3]) retainer = parent, j = i; } while (node.data !== d) if (!(previous = node, node = node.next)) return this; if (next = node.next) delete node.next; if (previous) return next ? previous.next = next : delete previous.next, this; if (!parent) return this._root = next, this; next ? parent[i] = next : delete parent[i]; if ((node = parent[0] || parent[1] || parent[2] || parent[3]) && node === (parent[3] || parent[2] || parent[1] || parent[0]) && !node.length) { if (retainer) retainer[j] = node; else this._root = node; } return this; } function removeAll2(data) { for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); return this; } // ../../node_modules/d3-quadtree/src/root.js function root_default2() { return this._root; } // ../../node_modules/d3-quadtree/src/size.js function size_default2() { var size = 0; this.visit(function(node) { if (!node.length) do ++size; while (node = node.next); }); return size; } // ../../node_modules/d3-quadtree/src/visit.js function visit_default2(callback) { var quads = [], q, node = this._root, child, x0, y0, x1, y1; if (node) quads.push(new quad_default(node, this._x0, this._y0, this._x1, this._y1)); while (q = quads.pop()) { if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) { var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; if (child = node[3]) quads.push(new quad_default(child, xm, ym, x1, y1)); if (child = node[2]) quads.push(new quad_default(child, x0, ym, xm, y1)); if (child = node[1]) quads.push(new quad_default(child, xm, y0, x1, ym)); if (child = node[0]) quads.push(new quad_default(child, x0, y0, xm, ym)); } } return this; } // ../../node_modules/d3-quadtree/src/visitAfter.js function visitAfter_default2(callback) { var quads = [], next = [], q; if (this._root) quads.push(new quad_default(this._root, this._x0, this._y0, this._x1, this._y1)); while (q = quads.pop()) { var node = q.node; if (node.length) { var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; if (child = node[0]) quads.push(new quad_default(child, x0, y0, xm, ym)); if (child = node[1]) quads.push(new quad_default(child, xm, y0, x1, ym)); if (child = node[2]) quads.push(new quad_default(child, x0, ym, xm, y1)); if (child = node[3]) quads.push(new quad_default(child, xm, ym, x1, y1)); } next.push(q); } while (q = next.pop()) { callback(q.node, q.x0, q.y0, q.x1, q.y1); } return this; } // ../../node_modules/d3-quadtree/src/x.js function defaultX2(d) { return d[0]; } function x_default2(_) { return arguments.length ? (this._x = _, this) : this._x; } // ../../node_modules/d3-quadtree/src/y.js function defaultY(d) { return d[1]; } function y_default(_) { return arguments.length ? (this._y = _, this) : this._y; } // ../../node_modules/d3-quadtree/src/quadtree.js function quadtree(nodes, x2, y2) { var tree = new Quadtree(x2 == null ? defaultX2 : x2, y2 == null ? defaultY : y2, NaN, NaN, NaN, NaN); return nodes == null ? tree : tree.addAll(nodes); } function Quadtree(x2, y2, x0, y0, x1, y1) { this._x = x2; this._y = y2; this._x0 = x0; this._y0 = y0; this._x1 = x1; this._y1 = y1; this._root = void 0; } function leaf_copy2(leaf) { var copy = { data: leaf.data }, next = copy; while (leaf = leaf.next) next = next.next = { data: leaf.data }; return copy; } var treeProto2 = quadtree.prototype = Quadtree.prototype; treeProto2.copy = function() { var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1), node = this._root, nodes, child; if (!node) return copy; if (!node.length) return copy._root = leaf_copy2(node), copy; nodes = [{ source: node, target: copy._root = new Array(4) }]; while (node = nodes.pop()) { for (var i = 0; i < 4; ++i) { if (child = node.source[i]) { if (child.length) nodes.push({ source: child, target: node.target[i] = new Array(4) }); else node.target[i] = leaf_copy2(child); } } } return copy; }; treeProto2.add = add_default2; treeProto2.addAll = addAll2; treeProto2.cover = cover_default2; treeProto2.data = data_default2; treeProto2.extent = extent_default2; treeProto2.find = find_default2; treeProto2.remove = remove_default2; treeProto2.removeAll = removeAll2; treeProto2.root = root_default2; treeProto2.size = size_default2; treeProto2.visit = visit_default2; treeProto2.visitAfter = visitAfter_default2; treeProto2.x = x_default2; treeProto2.y = y_default; // ../../node_modules/d3-octree/src/add.js function add_default3(d) { const x2 = +this._x.call(null, d), y2 = +this._y.call(null, d), z2 = +this._z.call(null, d); return add3(this.cover(x2, y2, z2), x2, y2, z2, d); } function add3(tree, x2, y2, z2, d) { if (isNaN(x2) || isNaN(y2) || isNaN(z2)) return tree; var parent, node = tree._root, leaf = { data: d }, x0 = tree._x0, y0 = tree._y0, z0 = tree._z0, x1 = tree._x1, y1 = tree._y1, z1 = tree._z1, xm, ym, zm, xp, yp, zp, right, bottom, deep, i, j; if (!node) return tree._root = leaf, tree; while (node.length) { if (right = x2 >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (bottom = y2 >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; if (deep = z2 >= (zm = (z0 + z1) / 2)) z0 = zm; else z1 = zm; if (parent = node, !(node = node[i = deep << 2 | bottom << 1 | right])) return parent[i] = leaf, tree; } xp = +tree._x.call(null, node.data); yp = +tree._y.call(null, node.data); zp = +tree._z.call(null, node.data); if (x2 === xp && y2 === yp && z2 === zp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; do { parent = parent ? parent[i] = new Array(8) : tree._root = new Array(8); if (right = x2 >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (bottom = y2 >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; if (deep = z2 >= (zm = (z0 + z1) / 2)) z0 = zm; else z1 = zm; } while ((i = deep << 2 | bottom << 1 | right) === (j = (zp >= zm) << 2 | (yp >= ym) << 1 | xp >= xm)); return parent[j] = node, parent[i] = leaf, tree; } function addAll3(data) { if (!Array.isArray(data)) data = Array.from(data); const n = data.length; const xz = new Float64Array(n); const yz = new Float64Array(n); const zz = new Float64Array(n); let x0 = Infinity, y0 = Infinity, z0 = Infinity, x1 = -Infinity, y1 = -Infinity, z1 = -Infinity; for (let i = 0, d, x2, y2, z2; i < n; ++i) { if (isNaN(x2 = +this._x.call(null, d = data[i])) || isNaN(y2 = +this._y.call(null, d)) || isNaN(z2 = +this._z.call(null, d))) continue; xz[i] = x2; yz[i] = y2; zz[i] = z2; if (x2 < x0) x0 = x2; if (x2 > x1) x1 = x2; if (y2 < y0) y0 = y2; if (y2 > y1) y1 = y2; if (z2 < z0) z0 = z2; if (z2 > z1) z1 = z2; } if (x0 > x1 || y0 > y1 || z0 > z1) return this; this.cover(x0, y0, z0).cover(x1, y1, z1); for (let i = 0; i < n; ++i) { add3(this, xz[i], yz[i], zz[i], data[i]); } return this; } // ../../node_modules/d3-octree/src/cover.js function cover_default3(x2, y2, z2) { if (isNaN(x2 = +x2) || isNaN(y2 = +y2) || isNaN(z2 = +z2)) return this; var x0 = this._x0, y0 = this._y0, z0 = this._z0, x1 = this._x1, y1 = this._y1, z1 = this._z1; if (isNaN(x0)) { x1 = (x0 = Math.floor(x2)) + 1; y1 = (y0 = Math.floor(y2)) + 1; z1 = (z0 = Math.floor(z2)) + 1; } else { var t = x1 - x0 || 1, node = this._root, parent, i; while (x0 > x2 || x2 >= x1 || y0 > y2 || y2 >= y1 || z0 > z2 || z2 >= z1) { i = (z2 < z0) << 2 | (y2 < y0) << 1 | x2 < x0; parent = new Array(8), parent[i] = node, node = parent, t *= 2; switch (i) { case 0: x1 = x0 + t, y1 = y0 + t, z1 = z0 + t; break; case 1: x0 = x1 - t, y1 = y0 + t, z1 = z0 + t; break; case 2: x1 = x0 + t, y0 = y1 - t, z1 = z0 + t; break; case 3: x0 = x1 - t, y0 = y1 - t, z1 = z0 + t; break; case 4: x1 = x0 + t, y1 = y0 + t, z0 = z1 - t; break; case 5: x0 = x1 - t, y1 = y0 + t, z0 = z1 - t; break; case 6: x1 = x0 + t, y0 = y1 - t, z0 = z1 - t; break; case 7: x0 = x1 - t, y0 = y1 - t, z0 = z1 - t; break; } } if (this._root && this._root.length) this._root = node; } this._x0 = x0; this._y0 = y0; this._z0 = z0; this._x1 = x1; this._y1 = y1; this._z1 = z1; return this; } // ../../node_modules/d3-octree/src/data.js function data_default3() { var data = []; this.visit(function(node) { if (!node.length) do data.push(node.data); while (node = node.next); }); return data; } // ../../node_modules/d3-octree/src/extent.js function extent_default3(_) { return arguments.length ? this.cover(+_[0][0], +_[0][1], +_[0][2]).cover(+_[1][0], +_[1][1], +_[1][2]) : isNaN(this._x0) ? void 0 : [[this._x0, this._y0, this._z0], [this._x1, this._y1, this._z1]]; } // ../../node_modules/d3-octree/src/octant.js function octant_default(node, x0, y0, z0, x1, y1, z1) { this.node = node; this.x0 = x0; this.y0 = y0; this.z0 = z0; this.x1 = x1; this.y1 = y1; this.z1 = z1; } // ../../node_modules/d3-octree/src/find.js function find_default3(x2, y2, z2, radius) { var data, x0 = this._x0, y0 = this._y0, z0 = this._z0, x1, y1, z1, x22, y22, z22, x3 = this._x1, y3 = this._y1, z3 = this._z1, octs = [], node = this._root, q, i; if (node) octs.push(new octant_default(node, x0, y0, z0, x3, y3, z3)); if (radius == null) radius = Infinity; else { x0 = x2 - radius, y0 = y2 - radius, z0 = z2 - radius; x3 = x2 + radius, y3 = y2 + radius, z3 = z2 + radius; radius *= radius; } while (q = octs.pop()) { if (!(node = q.node) || (x1 = q.x0) > x3 || (y1 = q.y0) > y3 || (z1 = q.z0) > z3 || (x22 = q.x1) < x0 || (y22 = q.y1) < y0 || (z22 = q.z1) < z0) continue; if (node.length) { var xm = (x1 + x22) / 2, ym = (y1 + y22) / 2, zm = (z1 + z22) / 2; octs.push( new octant_default(node[7], xm, ym, zm, x22, y22, z22), new octant_default(node[6], x1, ym, zm, xm, y22, z22), new octant_default(node[5], xm, y1, zm, x22, ym, z22), new octant_default(node[4], x1, y1, zm, xm, ym, z22), new octant_default(node[3], xm, ym, z1, x22, y22, zm), new octant_default(node[2], x1, ym, z1, xm, y22, zm), new octant_default(node[1], xm, y1, z1, x22, ym, zm), new octant_default(node[0], x1, y1, z1, xm, ym, zm) ); if (i = (z2 >= zm) << 2 | (y2 >= ym) << 1 | x2 >= xm) { q = octs[octs.length - 1]; octs[octs.length - 1] = octs[octs.length - 1 - i]; octs[octs.length - 1 - i] = q; } } else { var dx = x2 - +this._x.call(null, node.data), dy = y2 - +this._y.call(null, node.data), dz = z2 - +this._z.call(null, node.data), d2 = dx * dx + dy * dy + dz * dz; if (d2 < radius) { var d = Math.sqrt(radius = d2); x0 = x2 - d, y0 = y2 - d, z0 = z2 - d; x3 = x2 + d, y3 = y2 + d, z3 = z2 + d; data = node.data; } } } return data; } // ../../node_modules/d3-octree/src/remove.js function remove_default3(d) { if (isNaN(x2 = +this._x.call(null, d)) || isNaN(y2 = +this._y.call(null, d)) || isNaN(z2 = +this._z.call(null, d))) return this; var parent, node = this._root, retainer, previous, next, x0 = this._x0, y0 = this._y0, z0 = this._z0, x1 = this._x1, y1 = this._y1, z1 = this._z1, x2, y2, z2, xm, ym, zm, right, bottom, deep, i, j; if (!node) return this; if (node.length) while (true) { if (right = x2 >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; if (bottom = y2 >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; if (deep = z2 >= (zm = (z0 + z1) / 2)) z0 = zm; else z1 = zm; if (!(parent = node, node = node[i = deep << 2 | bottom << 1 | right])) return this; if (!node.length) break; if (parent[i + 1 & 7] || parent[i + 2 & 7] || parent[i + 3 & 7] || parent[i + 4 & 7] || parent[i + 5 & 7] || parent[i + 6 & 7] || parent[i + 7 & 7]) retainer = parent, j = i; } while (node.data !== d) if (!(previous = node, node = node.next)) return this; if (next = node.next) delete node.next; if (previous) return next ? previous.next = next : delete previous.next, this; if (!parent) return this._root = next, this; next ? parent[i] = next : delete parent[i]; if ((node = parent[0] || parent[1] || parent[2] || parent[3] || parent[4] || parent[5] || parent[6] || parent[7]) && node === (parent[7] || parent[6] || parent[5] || parent[4] || parent[3] || parent[2] || parent[1] || parent[0]) && !node.length) { if (retainer) retainer[j] = node; else this._root = node; } return this; } function removeAll3(data) { for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); return this; } // ../../node_modules/d3-octree/src/root.js function root_default3() { return this._root; } // ../../node_modules/d3-octree/src/size.js function size_default3() { var size = 0; this.visit(function(node) { if (!node.length) do ++size; while (node = node.next); }); return size; } // ../../node_modules/d3-octree/src/visit.js function visit_default3(callback) { var octs = [], q, node = this._root, child, x0, y0, z0, x1, y1, z1; if (node) octs.push(new octant_default(node, this._x0, this._y0, this._z0, this._x1, this._y1, this._z1)); while (q = octs.pop()) { if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, z0 = q.z0, x1 = q.x1, y1 = q.y1, z1 = q.z1) && node.length) { var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2, zm = (z0 + z1) / 2; if (child = node[7]) octs.push(new octant_default(child, xm, ym, zm, x1, y1, z1)); if (child = node[6]) octs.push(new octant_default(child, x0, ym, zm, xm, y1, z1)); if (child = node[5]) octs.push(new octant_default(child, xm, y0, zm, x1, ym, z1)); if (child = node[4]) octs.push(new octant_default(child, x0, y0, zm, xm, ym, z1)); if (child = node[3]) octs.push(new octant_default(child, xm, ym, z0, x1, y1, zm)); if (child = node[2]) octs.push(new octant_default(child, x0, ym, z0, xm, y1, zm)); if (child = node[1]) octs.push(new octant_default(child, xm, y0, z0, x1, ym, zm)); if (child = node[0]) octs.push(new octant_default(child, x0, y0, z0, xm, ym, zm)); } } return this; } // ../../node_modules/d3-octree/src/visitAfter.js function visitAfter_default3(callback) { var octs = [], next = [], q; if (this._root) octs.push(new octant_default(this._root, this._x0, this._y0, this._z0, this._x1, this._y1, this._z1)); while (q = octs.pop()) { var node = q.node; if (node.length) { var child, x0 = q.x0, y0 = q.y0, z0 = q.z0, x1 = q.x1, y1 = q.y1, z1 = q.z1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2, zm = (z0 + z1) / 2; if (child = node[0]) octs.push(new octant_default(child, x0, y0, z0, xm, ym, zm)); if (child = node[1]) octs.push(new octant_default(child, xm, y0, z0, x1, ym, zm)); if (child = node[2]) octs.push(new octant_default(child, x0, ym, z0, xm, y1, zm)); if (child = node[3]) octs.push(new octant_default(child, xm, ym, z0, x1, y1, zm)); if (child = node[4]) octs.push(new octant_default(child, x0, y0, zm, xm, ym, z1)); if (child = node[5]) octs.push(new octant_default(child, xm, y0, zm, x1, ym, z1)); if (child = node[6]) octs.push(new octant_default(child, x0, ym, zm, xm, y1, z1)); if (child = node[7]) octs.push(new octant_default(child, xm, ym, zm, x1, y1, z1)); } next.push(q); } while (q = next.pop()) { callback(q.node, q.x0, q.y0, q.z0, q.x1, q.y1, q.z1); } return this; } // ../../node_modules/d3-octree/src/x.js function defaultX3(d) { return d[0]; } function x_default3(_) { return arguments.length ? (this._x = _, this) : this._x; } // ../../node_modules/d3-octree/src/y.js function defaultY2(d) { return d[1]; } function y_default2(_) { return arguments.length ? (this._y = _, this) : this._y; } // ../../node_modules/d3-octree/src/z.js function defaultZ(d) { return d[2]; } function z_default(_) { return arguments.length ? (this._z = _, this) : this._z; } // ../../node_modules/d3-octree/src/octree.js function octree(nodes, x2, y2, z2) { var tree = new Octree(x2 == null ? defaultX3 : x2, y2 == null ? defaultY2 : y2, z2 == null ? defaultZ : z2, NaN, NaN, NaN, NaN, NaN, NaN); return nodes == null ? tree : tree.addAll(nodes); } function Octree(x2, y2, z2, x0, y0, z0, x1, y1, z1) { this._x = x2; this._y = y2; this._z = z2; this._x0 = x0; this._y0 = y0; this._z0 = z0; this._x1 = x1; this._y1 = y1; this._z1 = z1; this._root = void 0; } function leaf_copy3(leaf) { var copy = { data: leaf.data }, next = copy; while (leaf = leaf.next) next = next.next = { data: leaf.data }; return copy; } var treeProto3 = octree.prototype = Octree.prototype; treeProto3.copy = function() { var copy = new Octree(this._x, this._y, this._z, this._x0, this._y0, this._z0, this._x1, this._y1, this._z1), node = this._root, nodes, child; if (!node) return copy; if (!node.length) return copy._root = leaf_copy3(node), copy; nodes = [{ source: node, target: copy._root = new Array(8) }]; while (node = nodes.pop()) { for (var i = 0; i < 8; ++i) { if (child = node.source[i]) { if (child.length) nodes.push({ source: child, target: node.target[i] = new Array(8) }); else node.target[i] = leaf_copy3(child); } } } return copy; }; treeProto3.add = add_default3; treeProto3.addAll = addAll3; treeProto3.cover = cover_default3; treeProto3.data = data_default3; treeProto3.extent = extent_default3; treeProto3.find = find_default3; treeProto3.remove = remove_default3; treeProto3.removeAll = removeAll3; treeProto3.root = root_default3; treeProto3.size = size_default3; treeProto3.visit = visit_default3; treeProto3.visitAfter = visitAfter_default3; treeProto3.x = x_default3; treeProto3.y = y_default2; treeProto3.z = z_default; // ../../node_modules/d3-force-3d/src/constant.js function constant_default(x2) { return function() { return x2; }; } // ../../node_modules/d3-force-3d/src/jiggle.js function jiggle_default(random) { return (random() - 0.5) * 1e-6; } // ../../node_modules/d3-force-3d/src/link.js function index(d) { return d.index; } function find(nodeById, nodeId) { var node = nodeById.get(nodeId); if (!node) throw new Error("node not found: " + nodeId); return node; } function link_default(links) { var id2 = index, strength = defaultStrength, strengths, distance2 = constant_default(30), distances, nodes, nDim, count, bias, random, iterations = 1; if (links == null) links = []; function defaultStrength(link) { return 1 / Math.min(count[link.source.index], count[link.target.index]); } function force(alpha) { for (var k = 0, n = links.length; k < iterations; ++k) { for (var i = 0, link, source, target, x2 = 0, y2 = 0, z2 = 0, l, b; i < n; ++i) { link = links[i], source = link.source, target = link.target; x2 = target.x + target.vx - source.x - source.vx || jiggle_default(random); if (nDim > 1) { y2 = target.y + target.vy - source.y - source.vy || jiggle_default(random); } if (nDim > 2) { z2 = target.z + target.vz - source.z - source.vz || jiggle_default(random); } l = Math.sqrt(x2 * x2 + y2 * y2 + z2 * z2); l = (l - distances[i]) / l * alpha * strengths[i]; x2 *= l, y2 *= l, z2 *= l; target.vx -= x2 * (b = bias[i]); if (nDim > 1) { target.vy -= y2 * b; } if (nDim > 2) { target.vz -= z2 * b; } source.vx += x2 * (b = 1 - b); if (nDim > 1) { source.vy += y2 * b; } if (nDim > 2) { source.vz += z2 * b; } } } } function initialize() { if (!nodes) return; var i, n = nodes.length, m2 = links.length, nodeById = new Map(nodes.map((d, i2) => [id2(d, i2, nodes), d])), link; for (i = 0, count = new Array(n); i < m2; ++i) { link = links[i], link.index = i; if (typeof link.source !== "object") link.source = find(nodeById, link.source); if (typeof link.target !== "object") link.target = find(nodeById, link.target); count[link.source.index] = (count[link.source.index] || 0) + 1; count[link.target.index] = (count[link.target.index] || 0) + 1; } for (i = 0, bias = new Array(m2); i < m2; ++i) { link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]); } strengths = new Array(m2), initializeStrength(); distances = new Array(m2), initializeDistance(); } function initializeStrength() { if (!nodes) return; for (var i = 0, n = links.length; i < n; ++i) { strengths[i] = +strength(links[i], i, links); } } function initializeDistance() { if (!nodes) return; for (var i = 0, n = links.length; i < n; ++i) { distances[i] = +distance2(links[i], i, links); } } force.initialize = function(_nodes, ...args) { nodes = _nodes; random = args.find((arg) => typeof arg === "function") || Math.random; nDim = args.find((arg) => [1, 2, 3].includes(arg)) || 2; initialize(); }; force.links = function(_) { return arguments.length ? (links = _, initialize(), force) : links; }; force.id = function(_) { return arguments.length ? (id2 = _, force) : id2; }; force.iterations = function(_) { return arguments.length ? (iterations = +_, force) : iterations; }; force.strength = function(_) { return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initializeStrength(), force) : strength; }; force.distance = function(_) { return arguments.length ? (distance2 = typeof _ === "function" ? _ : constant_default(+_), initializeDistance(), force) : distance2; }; return force; } // ../../node_modules/d3-dispatch/src/dispatch.js var noop = { value: () => { } }; function dispatch() { for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { if (!(t = arguments[i] + "") || t in _ || /[\s.]/.test(t)) throw new Error("illegal type: " + t); _[t] = []; } return new Dispatch(_); } function Dispatch(_) { this._ = _; } function parseTypenames(typenames, types) { return typenames.trim().split(/^|\s+/).map(function(t) { var name = "", i = t.indexOf("."); if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); return { type: t, name }; }); } Dispatch.prototype = dispatch.prototype = { constructor: Dispatch, on: function(typename, callback) { var _ = this._, T = parseTypenames(typename + "", _), t, i = -1, n = T.length; if (arguments.length < 2) { while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t; return; } if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); while (++i < n) { if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback); else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null); } return this; }, copy: function() { var copy = {}, _ = this._; for (var t in _) copy[t] = _[t].slice(); return new Dispatch(copy); }, call: function(type, that) { if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); }, apply: function(type, that, args) { if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); } }; function get(type, name) { for (var i = 0, n = type.length, c2; i < n; ++i) { if ((c2 = type[i]).name === name) { return c2.value; } } } function set(type, name, callback) { for (var i = 0, n = type.length; i < n; ++i) { if (type[i].name === name) { type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); break; } } if (callback != null) type.push({ name, value: callback }); return type; } var dispatch_default = dispatch; // ../../node_modules/d3-timer/src/timer.js var frame = 0; var timeout = 0; var interval = 0; var pokeDelay = 1e3; var taskHead; var taskTail; var clockLast = 0; var clockNow = 0; var clockSkew = 0; var clock = typeof performance === "object" && performance.now ? performance : Date; var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; function now2() { return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); } function clearNow() { clockNow = 0; } function Timer() { this._call = this._time = this._next = null; } Timer.prototype = timer.prototype = { constructor: Timer, restart: function(callback, delay, time) { if (typeof callback !== "function") throw new TypeError("callback is not a function"); time = (time == null ? now2() : +time) + (delay == null ? 0 : +delay); if (!this._next && taskTail !== this) { if (taskTail) taskTail._next = this; else taskHead = this; taskTail = this; } this._call = callback; this._time = time; sleep(); }, stop: function() { if (this._call) { this._call = null; this._time = Infinity; sleep(); } } }; function timer(callback, delay, time) { var t = new Timer(); t.restart(callback, delay, time); return t; } function timerFlush() { now2(); ++frame; var t = taskHead, e; while (t) { if ((e = clockNow - t._time) >= 0) t._call.call(void 0, e); t = t._next; } --frame; } function wake() { clockNow = (clockLast = clock.now()) + clockSkew; frame = timeout = 0; try { timerFlush(); } finally { frame = 0; nap(); clockNow = 0; } } function poke() { var now5 = clock.now(), delay = now5 - clockLast; if (delay > pokeDelay) clockSkew -= delay, clockLast = now5; } function nap() { var t0, t1 = taskHead, t2, time = Infinity; while (t1) { if (t1._call) { if (time > t1._time) time = t1._time; t0 = t1, t1 = t1._next; } else { t2 = t1._next, t1._next = null; t1 = t0 ? t0._next = t2 : taskHead = t2; } } taskTail = t0; sleep(time); } function sleep(time) { if (frame) return; if (timeout) timeout = clearTimeout(timeout); var delay = time - clockNow; if (delay > 24) { if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew); if (interval) interval = clearInterval(interval); } else { if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); frame = 1, setFrame(wake); } } // ../../node_modules/d3-force-3d/src/lcg.js var a = 1664525; var c = 1013904223; var m = 4294967296; function lcg_default() { let s = 1; return () => (s = (a * s + c) % m) / m; } // ../../node_modules/d3-force-3d/src/simulation.js var MAX_DIMENSIONS = 3; function x(d) { return d.x; } function y(d) { return d.y; } function z(d) { return d.z; } var initialRadius = 10; var initialAngleRoll = Math.PI * (3 - Math.sqrt(5)); var initialAngleYaw = Math.PI * 20 / (9 + Math.sqrt(221)); function simulation_default(nodes, numDimensions) { numDimensions = numDimensions || 2; var nDim = Math.min(MAX_DIMENSIONS, Math.max(1, Math.round(numDimensions))), simulation, alpha = 1, alphaMin = 1e-3, alphaDecay = 1 - Math.pow(alphaMin, 1 / 300), alphaTarget = 0, velocityDecay = 0.6, forces = /* @__PURE__ */ new Map(), stepper = timer(step2), event = dispatch_default("tick", "end"), random = lcg_default(); if (nodes == null) nodes = []; function step2() { tick2(); event.call("tick", simulation); if (alpha < alphaMin) { stepper.stop(); event.call("end", simulation); } } function tick2(iterations) { var i, n = nodes.length, node; if (iterations === void 0) iterations = 1; for (var k = 0; k < iterations; ++k) { alpha += (alphaTarget - alpha) * alphaDecay; forces.forEach(function(force) { force(alpha); }); for (i = 0; i < n; ++i) { node = nodes[i]; if (node.fx == null) node.x += node.vx *= velocityDecay; else node.x = node.fx, node.vx = 0; if (nDim > 1) { if (node.fy == null) node.y += node.vy *= velocityDecay; else node.y = node.fy, node.vy = 0; } if (nDim > 2) { if (node.fz == null) node.z += node.vz *= velocityDecay; else node.z = node.fz, node.vz = 0; } } } return simulation; } function initializeNodes() { for (var i = 0, n = nodes.length, node; i < n; ++i) { node = nodes[i], node.index = i; if (node.fx != null) node.x = node.fx; if (node.fy != null) node.y = node.fy; if (node.fz != null) node.z = node.fz; if (isNaN(node.x) || nDim > 1 && isNaN(node.y) || nDim > 2 && isNaN(node.z)) { var radius = initialRadius * (nDim > 2 ? Math.cbrt(0.5 + i) : nDim > 1 ? Math.sqrt(0.5 + i) : i), rollAngle = i * initialAngleRoll, yawAngle = i * initialAngleYaw; if (nDim === 1) { node.x = radius; } else if (nDim === 2) { node.x = radius * Math.cos(rollAngle); node.y = radius * Math.sin(rollAngle); } else { node.x = radius * Math.sin(rollAngle) * Math.cos(yawAngle); node.y = radius * Math.cos(rollAngle); node.z = radius * Math.sin(rollAngle) * Math.sin(yawAngle); } } if (isNaN(node.vx) || nDim > 1 && isNaN(node.vy) || nDim > 2 && isNaN(node.vz)) { node.vx = 0; if (nDim > 1) { node.vy = 0; } if (nDim > 2) { node.vz = 0; } } } } function initializeForce(force) { if (force.initialize) force.initialize(nodes, random, nDim); return force; } initializeNodes(); return simulation = { tick: tick2, restart: function() { return stepper.restart(step2), simulation; }, stop: function() { return stepper.stop(), simulation; }, numDimensions: function(_) { return arguments.length ? (nDim = Math.min(MAX_DIMENSIONS, Math.max(1, Math.round(_))), forces.forEach(initializeForce), simulation) : nDim; }, nodes: function(_) { return arguments.length ? (nodes = _, initializeNodes(), forces.forEach(initializeForce), simulation) : nodes; }, alpha: function(_) { return arguments.length ? (alpha = +_, simulation) : alpha; }, alphaMin: function(_) { return arguments.length ? (alphaMin = +_, simulation) : alphaMin; }, alphaDecay: function(_) { return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay; }, alphaTarget: function(_) { return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget; }, velocityDecay: function(_) { return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay; }, randomSource: function(_) { return arguments.length ? (random = _, forces.forEach(initializeForce), simulation) : random; }, force: function(name, _) { return arguments.length > 1 ? (_ == null ? forces.delete(name) : forces.set(name, initializeForce(_)), simulation) : forces.get(name); }, find: function() { var args = Array.prototype.slice.call(arguments); var x2 = args.shift() || 0, y2 = (nDim > 1 ? args.shift() : null) || 0, z2 = (nDim > 2 ? args.shift() : null) || 0, radius = args.shift() || Infinity; var i = 0, n = nodes.length, dx, dy, dz, d2, node, closest; radius *= radius; for (i = 0; i < n; ++i) { node = nodes[i]; dx = x2 - node.x; dy = y2 - (node.y || 0); dz = z2 - (node.z || 0); d2 = dx * dx + dy * dy + dz * dz; if (d2 < radius) closest = node, radius = d2; } return closest; }, on: function(name, _) { return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name); } }; } // ../../node_modules/d3-force-3d/src/manyBody.js function manyBody_default() { var nodes, nDim, node, random, alpha, strength = constant_default(-30), strengths, distanceMin2 = 1, distanceMax2 = Infinity, theta2 = 0.81; function force(_) { var i, n = nodes.length, tree = (nDim === 1 ? binarytree(nodes, x) : nDim === 2 ? quadtree(nodes, x, y) : nDim === 3 ? octree(nodes, x, y, z) : null).visitAfter(accumulate); for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply); } function initialize() { if (!nodes) return; var i, n = nodes.length, node2; strengths = new Array(n); for (i = 0; i < n; ++i) node2 = nodes[i], strengths[node2.index] = +strength(node2, i, nodes); } function accumulate(treeNode) { var strength2 = 0, q, c2, weight = 0, x2, y2, z2, i; var numChildren = treeNode.length; if (numChildren) { for (x2 = y2 = z2 = i = 0; i < numChildren; ++i) { if ((q = treeNode[i]) && (c2 = Math.abs(q.value))) { strength2 += q.value, weight += c2, x2 += c2 * (q.x || 0), y2 += c2 * (q.y || 0), z2 += c2 * (q.z || 0); } } strength2 *= Math.sqrt(4 / numChildren); treeNode.x = x2 / weight; if (nDim > 1) { treeNode.y = y2 / weight; } if (nDim > 2) { treeNode.z = z2 / weight; } } else { q = treeNode; q.x = q.data.x; if (nDim > 1) { q.y = q.data.y; } if (nDim > 2) { q.z = q.data.z; } do strength2 += strengths[q.data.index]; while (q = q.next); } treeNode.value = strength2; } function apply(treeNode, x1, arg1, arg2, arg3) { if (!treeNode.value) return true; var x2 = [arg1, arg2, arg3][nDim - 1]; var x3 = treeNode.x - node.x, y2 = nDim > 1 ? treeNode.y - node.y : 0, z2 = nDim > 2 ? treeNode.z - node.z : 0, w = x2 - x1, l = x3 * x3 + y2 * y2 + z2 * z2; if (w * w / theta2 < l) { if (l < distanceMax2) { if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3; if (nDim > 1 && y2 === 0) y2 = jiggle_default(random), l += y2 * y2; if (nDim > 2 && z2 === 0) z2 = jiggle_default(random), l += z2 * z2; if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); node.vx += x3 * treeNode.value * alpha / l; if (nDim > 1) { node.vy += y2 * treeNode.value * alpha / l; } if (nDim > 2) { node.vz += z2 * treeNode.value * alpha / l; } } return true; } else if (treeNode.length || l >= distanceMax2) return; if (treeNode.data !== node || treeNode.next) { if (x3 === 0) x3 = jiggle_default(random), l += x3 * x3; if (nDim > 1 && y2 === 0) y2 = jiggle_default(random), l += y2 * y2; if (nDim > 2 && z2 === 0) z2 = jiggle_default(random), l += z2 * z2; if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); } do if (treeNode.data !== node) { w = strengths[treeNode.data.index] * alpha / l; node.vx += x3 * w; if (nDim > 1) { node.vy += y2 * w; } if (nDim > 2) { node.vz += z2 * w; } } while (treeNode = treeNode.next); } force.initialize = function(_nodes, ...args) { nodes = _nodes; random = args.find((arg) => typeof arg === "function") || Math.random; nDim = args.find((arg) => [1, 2, 3].includes(arg)) || 2; initialize(); }; force.strength = function(_) { return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength; }; force.distanceMin = function(_) { return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2); }; force.distanceMax = function(_) { return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2); }; force.theta = function(_) { return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2); }; return force; } // ../../node_modules/d3-force-3d/src/radial.js function radial_default(radius, x2, y2, z2) { var nodes, nDim, strength = constant_default(0.1), strengths, radiuses; if (typeof radius !== "function") radius = constant_default(+radius); if (x2 == null) x2 = 0; if (y2 == null) y2 = 0; if (z2 == null) z2 = 0; function force(alpha) { for (var i = 0, n = nodes.length; i < n; ++i) { var node = nodes[i], dx = node.x - x2 || 1e-6, dy = (node.y || 0) - y2 || 1e-6, dz = (node.z || 0) - z2 || 1e-6, r = Math.sqrt(dx * dx + dy * dy + dz * dz), k = (radiuses[i] - r) * strengths[i] * alpha / r; node.vx += dx * k; if (nDim > 1) { node.vy += dy * k; } if (nDim > 2) { node.vz += dz * k; } } } function initialize() { if (!nodes) return; var i, n = nodes.length; strengths = new Array(n); radiuses = new Array(n); for (i = 0; i < n; ++i) { radiuses[i] = +radius(nodes[i], i, nodes); strengths[i] = isNaN(radiuses[i]) ? 0 : +strength(nodes[i], i, nodes); } } force.initialize = function(initNodes, ...args) { nodes = initNodes; nDim = args.find((arg) => [1, 2, 3].includes(arg)) || 2; initialize(); }; force.strength = function(_) { return arguments.length ? (strength = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : strength; }; force.radius = function(_) { return arguments.length ? (radius = typeof _ === "function" ? _ : constant_default(+_), initialize(), force) : radius; }; force.x = function(_) { return arguments.length ? (x2 = +_, force) : x2; }; force.y = function(_) { return arguments.length ? (y2 = +_, force) : y2; }; force.z = function(_) { return arguments.length ? (z2 = +_, force) : z2; }; return force; } // ../../node_modules/three-forcegraph/dist/three-forcegraph.mjs var import_ngraph = __toESM(require_ngraph2(), 1); var import_ngraph2 = __toESM(require_ngraph5(), 1); // ../../node_modules/lodash-es/isObject.js function isObject(value) { var type = typeof value; return value != null && (type == "object" || type == "function"); } var isObject_default = isObject; // ../../node_modules/lodash-es/_freeGlobal.js var freeGlobal = typeof global == "object" && global && global.Object === Object && global; var freeGlobal_default = freeGlobal; // ../../node_modules/lodash-es/_root.js var freeSelf = typeof self == "object" && self && self.Object === Object && self; var root = freeGlobal_default || freeSelf || Function("return this")(); var root_default4 = root; // ../../node_modules/lodash-es/now.js var now3 = function() { return root_default4.Date.now(); }; var now_default = now3; // ../../node_modules/lodash-es/_trimmedEndIndex.js var reWhitespace = /\s/; function trimmedEndIndex(string) { var index5 = string.length; while (index5-- && reWhitespace.test(string.charAt(index5))) { } return index5; } var trimmedEndIndex_default = trimmedEndIndex; // ../../node_modules/lodash-es/_baseTrim.js var reTrimStart = /^\s+/; function baseTrim(string) { return string ? string.slice(0, trimmedEndIndex_default(string) + 1).replace(reTrimStart, "") : string; } var baseTrim_default = baseTrim; // ../../node_modules/lodash-es/_Symbol.js var Symbol2 = root_default4.Symbol; var Symbol_default = Symbol2; // ../../node_modules/lodash-es/_getRawTag.js var objectProto = Object.prototype; var hasOwnProperty = objectProto.hasOwnProperty; var nativeObjectToString = objectProto.toString; var symToStringTag = Symbol_default ? Symbol_default.toStringTag : void 0; function getRawTag(value) { var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag]; try { value[symToStringTag] = void 0; var unmasked = true; } catch (e) { } var result = nativeObjectToString.call(value); if (unmasked) { if (isOwn) { value[symToStringTag] = tag; } else { delete value[symToStringTag]; } } return result; } var getRawTag_default = getRawTag; // ../../node_modules/lodash-es/_objectToString.js var objectProto2 = Object.prototype; var nativeObjectToString2 = objectProto2.toString; function objectToString(value) { return nativeObjectToString2.call(value); } var objectToString_default = objectToString; // ../../node_modules/lodash-es/_baseGetTag.js var nullTag = "[object Null]"; var undefinedTag = "[object Undefined]"; var symToStringTag2 = Symbol_default ? Symbol_default.toStringTag : void 0; function baseGetTag(value) { if (value == null) { return value === void 0 ? undefinedTag : nullTag; } return symToStringTag2 && symToStringTag2 in Object(value) ? getRawTag_default(value) : objectToString_default(value); } var baseGetTag_default = baseGetTag; // ../../node_modules/lodash-es/isObjectLike.js function isObjectLike(value) { return value != null && typeof value == "object"; } var isObjectLike_default = isObjectLike; // ../../node_modules/lodash-es/isSymbol.js var symbolTag = "[object Symbol]"; function isSymbol(value) { return typeof value == "symbol" || isObjectLike_default(value) && baseGetTag_default(value) == symbolTag; } var isSymbol_default = isSymbol; // ../../node_modules/lodash-es/toNumber.js var NAN = 0 / 0; var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; var reIsBinary = /^0b[01]+$/i; var reIsOctal = /^0o[0-7]+$/i; var freeParseInt = parseInt; function toNumber(value) { if (typeof value == "number") { return value; } if (isSymbol_default(value)) { return NAN; } if (isObject_default(value)) { var other = typeof value.valueOf == "function" ? value.valueOf() : value; value = isObject_default(other) ? other + "" : other; } if (typeof value != "string") { return value === 0 ? value : +value; } value = baseTrim_default(value); var isBinary = reIsBinary.test(value); return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; } var toNumber_default = toNumber; // ../../node_modules/lodash-es/debounce.js var FUNC_ERROR_TEXT = "Expected a function"; var nativeMax = Math.max; var nativeMin = Math.min; function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber_default(wait) || 0; if (isObject_default(options)) { leading = !!options.leading; maxing = "maxWait" in options; maxWait = maxing ? nativeMax(toNumber_default(options.maxWait) || 0, wait) : maxWait; trailing = "trailing" in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = void 0; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { lastInvokeTime = time; timerId = setTimeout(timerExpired, wait); return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall; return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; } function timerExpired() { var time = now_default(); if (shouldInvoke(time)) { return trailingEdge(time); } timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = void 0; if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = void 0; return result; } function cancel() { if (timerId !== void 0) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = void 0; } function flush() { return timerId === void 0 ? result : trailingEdge(now_default()); } function debounced() { var time = now_default(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === void 0) { return leadingEdge(lastCallTime); } if (maxing) { clearTimeout(timerId); timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === void 0) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } var debounce_default = debounce; // ../../node_modules/kapsule/dist/kapsule.mjs function _arrayLikeToArray(r, a2) { (null == a2 || a2 > r.length) && (a2 = r.length); for (var e = 0, n = Array(a2); e < a2; e++) n[e] = r[e]; return n; } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } function _classCallCheck(a2, n) { if (!(a2 instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _createClass(e, r, t) { return Object.defineProperty(e, "prototype", { writable: false }), e; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a2 = [], f = true, o = false; try { if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a2.push(e.value), a2.length !== l); f = true) ; } catch (r2) { o = true, n = r2; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a2; } } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _unsupportedIterableToArray(r, a2) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a2); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a2) : void 0; } } var Prop = /* @__PURE__ */ _createClass(function Prop2(name, _ref) { var _ref$default = _ref["default"], defaultVal = _ref$default === void 0 ? null : _ref$default, _ref$triggerUpdate = _ref.triggerUpdate, triggerUpdate = _ref$triggerUpdate === void 0 ? true : _ref$triggerUpdate, _ref$onChange = _ref.onChange, onChange13 = _ref$onChange === void 0 ? function(newVal, state) { } : _ref$onChange; _classCallCheck(this, Prop2); this.name = name; this.defaultVal = defaultVal; this.triggerUpdate = triggerUpdate; this.onChange = onChange13; }); function index2(_ref2) { var _ref2$stateInit = _ref2.stateInit, stateInit4 = _ref2$stateInit === void 0 ? function() { return {}; } : _ref2$stateInit, _ref2$props = _ref2.props, rawProps = _ref2$props === void 0 ? {} : _ref2$props, _ref2$methods = _ref2.methods, methods = _ref2$methods === void 0 ? {} : _ref2$methods, _ref2$aliases = _ref2.aliases, aliases = _ref2$aliases === void 0 ? {} : _ref2$aliases, _ref2$init = _ref2.init, initFn = _ref2$init === void 0 ? function() { } : _ref2$init, _ref2$update = _ref2.update, updateFn = _ref2$update === void 0 ? function() { } : _ref2$update; var props = Object.keys(rawProps).map(function(propName) { return new Prop(propName, rawProps[propName]); }); return function() { var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; var state = Object.assign( {}, stateInit4 instanceof Function ? stateInit4(options) : stateInit4, // Support plain objects for backwards compatibility { initialised: false } ); var changedProps = {}; function comp(nodeElement) { initStatic(nodeElement, options); digest(); return comp; } var initStatic = function initStatic2(nodeElement, options2) { initFn.call(comp, nodeElement, state, options2); state.initialised = true; }; var digest = debounce_default(function() { if (!state.initialised) { return; } updateFn.call(comp, state, changedProps); changedProps = {}; }, 1); props.forEach(function(prop) { comp[prop.name] = getSetProp(prop); function getSetProp(_ref3) { var prop2 = _ref3.name, _ref3$triggerUpdate = _ref3.triggerUpdate, redigest = _ref3$triggerUpdate === void 0 ? false : _ref3$triggerUpdate, _ref3$onChange = _ref3.onChange, onChange13 = _ref3$onChange === void 0 ? function(newVal, state2) { } : _ref3$onChange, _ref3$defaultVal = _ref3.defaultVal, defaultVal = _ref3$defaultVal === void 0 ? null : _ref3$defaultVal; return function(_) { var curVal = state[prop2]; if (!arguments.length) { return curVal; } var val = _ === void 0 ? defaultVal : _; state[prop2] = val; onChange13.call(comp, val, state, curVal); !changedProps.hasOwnProperty(prop2) && (changedProps[prop2] = curVal); if (redigest) { digest(); } return comp; }; } }); Object.keys(methods).forEach(function(methodName) { comp[methodName] = function() { var _methods$methodName; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return (_methods$methodName = methods[methodName]).call.apply(_methods$methodName, [comp, state].concat(args)); }; }); Object.entries(aliases).forEach(function(_ref4) { var _ref5 = _slicedToArray(_ref4, 2), alias = _ref5[0], target = _ref5[1]; return comp[alias] = comp[target]; }); comp.resetProps = function() { props.forEach(function(prop) { comp[prop.name](prop.defaultVal); }); return comp; }; comp.resetProps(); state._rerender = digest; return comp; }; } // ../../node_modules/accessor-fn/dist/accessor-fn.mjs var index3 = function(p) { return typeof p === "function" ? p : typeof p === "string" ? function(obj) { return obj[p]; } : function(obj) { return p; }; }; // ../../node_modules/internmap/src/index.js var InternMap = class extends Map { constructor(entries, key = keyof) { super(); Object.defineProperties(this, { _intern: { value: /* @__PURE__ */ new Map() }, _key: { value: key } }); if (entries != null) for (const [key2, value] of entries) this.set(key2, value); } get(key) { return super.get(intern_get(this, key)); } has(key) { return super.has(intern_get(this, key)); } set(key, value) { return super.set(intern_set(this, key), value); } delete(key) { return super.delete(intern_delete(this, key)); } }; function intern_get({ _intern, _key }, value) { const key = _key(value); return _intern.has(key) ? _intern.get(key) : value; } function intern_set({ _intern, _key }, value) { const key = _key(value); if (_intern.has(key)) return _intern.get(key); _intern.set(key, value); return value; } function intern_delete({ _intern, _key }, value) { const key = _key(value); if (_intern.has(key)) { value = _intern.get(key); _intern.delete(key); } return value; } function keyof(value) { return value !== null && typeof value === "object" ? value.valueOf() : value; } // ../../node_modules/d3-array/src/max.js function max(values, valueof) { let max2; if (valueof === void 0) { for (const value of values) { if (value != null && (max2 < value || max2 === void 0 && value >= value)) { max2 = value; } } } else { let index5 = -1; for (let value of values) { if ((value = valueof(value, ++index5, values)) != null && (max2 < value || max2 === void 0 && value >= value)) { max2 = value; } } } return max2; } // ../../node_modules/d3-array/src/min.js function min(values, valueof) { let min2; if (valueof === void 0) { for (const value of values) { if (value != null && (min2 > value || min2 === void 0 && value >= value)) { min2 = value; } } } else { let index5 = -1; for (let value of values) { if ((value = valueof(value, ++index5, values)) != null && (min2 > value || min2 === void 0 && value >= value)) { min2 = value; } } } return min2; } // ../../node_modules/index-array-by/dist/index-array-by.mjs function _arrayLikeToArray2(r, a2) { (null == a2 || a2 > r.length) && (a2 = r.length); for (var e = 0, n = Array(a2); e < a2; e++) n[e] = r[e]; return n; } function _arrayWithHoles2(r) { if (Array.isArray(r)) return r; } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray2(r); } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _iterableToArrayLimit2(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a2 = [], f = true, o = false; try { if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a2.push(e.value), a2.length !== l); f = true) ; } catch (r2) { o = true, n = r2; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a2; } } function _nonIterableRest2() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var s = Object.getOwnPropertySymbols(e); for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; } function _slicedToArray2(r, e) { return _arrayWithHoles2(r) || _iterableToArrayLimit2(r, e) || _unsupportedIterableToArray2(r, e) || _nonIterableRest2(); } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray2(r) || _nonIterableSpread(); } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return String(t); } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _unsupportedIterableToArray2(r, a2) { if (r) { if ("string" == typeof r) return _arrayLikeToArray2(r, a2); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray2(r, a2) : void 0; } } var index4 = function() { var list = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : []; var keyAccessors = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : []; var multiItem = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : true; var flattenKeys = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : false; var keys = (keyAccessors instanceof Array ? keyAccessors.length ? keyAccessors : [void 0] : [keyAccessors]).map(function(key) { return { keyAccessor: key, isProp: !(key instanceof Function) }; }); var indexedResult = list.reduce(function(res, item) { var iterObj = res; var itemVal = item; keys.forEach(function(_ref, idx) { var keyAccessor = _ref.keyAccessor, isProp = _ref.isProp; var key; if (isProp) { var _itemVal = itemVal, propVal = _itemVal[keyAccessor], rest = _objectWithoutProperties(_itemVal, [keyAccessor].map(_toPropertyKey)); key = propVal; itemVal = rest; } else { key = keyAccessor(itemVal, idx); } if (idx + 1 < keys.length) { if (!iterObj.hasOwnProperty(key)) { iterObj[key] = {}; } iterObj = iterObj[key]; } else { if (multiItem) { if (!iterObj.hasOwnProperty(key)) { iterObj[key] = []; } iterObj[key].push(itemVal); } else { iterObj[key] = itemVal; } } }); return res; }, {}); if (multiItem instanceof Function) { (function reduce(node) { var level = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 1; if (level === keys.length) { Object.keys(node).forEach(function(k) { return node[k] = multiItem(node[k]); }); } else { Object.values(node).forEach(function(child) { return reduce(child, level + 1); }); } })(indexedResult); } var result = indexedResult; if (flattenKeys) { result = []; (function flatten2(node) { var accKeys = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : []; if (accKeys.length === keys.length) { result.push({ keys: accKeys, vals: node }); } else { Object.entries(node).forEach(function(_ref2) { var _ref3 = _slicedToArray2(_ref2, 2), key = _ref3[0], val = _ref3[1]; return flatten2(val, [].concat(_toConsumableArray(accKeys), [key])); }); } })(indexedResult); if (keyAccessors instanceof Array && keyAccessors.length === 0 && result.length === 1) { result[0].keys = []; } } return result; }; // ../../node_modules/data-joint/dist/data-joint.mjs function _iterableToArrayLimit3(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x3, _r, _arr = [], _n = true, _d = false; try { if (_x3 = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = false; } else for (; !(_n = (_s = _x3.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = true) ; } catch (err) { _d = true, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function(sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), true).forEach(function(key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function(key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _defineProperty(obj, key, value) { key = _toPropertyKey2(key); if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectWithoutPropertiesLoose2(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _objectWithoutProperties2(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose2(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _slicedToArray3(arr, i) { return _arrayWithHoles3(arr) || _iterableToArrayLimit3(arr, i) || _unsupportedIterableToArray3(arr, i) || _nonIterableRest3(); } function _toConsumableArray2(arr) { return _arrayWithoutHoles2(arr) || _iterableToArray2(arr) || _unsupportedIterableToArray3(arr) || _nonIterableSpread2(); } function _arrayWithoutHoles2(arr) { if (Array.isArray(arr)) return _arrayLikeToArray3(arr); } function _arrayWithHoles3(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray2(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _unsupportedIterableToArray3(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray3(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray3(o, minLen); } function _arrayLikeToArray3(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _nonIterableSpread2() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableRest3() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _toPrimitive2(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== void 0) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } function _toPropertyKey2(arg) { var key = _toPrimitive2(arg, "string"); return typeof key === "symbol" ? key : String(key); } var _excluded = ["createObj", "updateObj", "exitObj", "objBindAttr", "dataBindAttr"]; function diffArrays(prev, next, idAccessor) { var result = { enter: [], update: [], exit: [] }; if (!idAccessor) { var prevSet = new Set(prev); var nextSet = new Set(next); new Set([].concat(_toConsumableArray2(prevSet), _toConsumableArray2(nextSet))).forEach(function(item) { var type = !prevSet.has(item) ? "enter" : !nextSet.has(item) ? "exit" : "update"; result[type].push(type === "update" ? [item, item] : item); }); } else { var prevById = index4(prev, idAccessor, false); var nextById = index4(next, idAccessor, false); var byId = Object.assign({}, prevById, nextById); Object.entries(byId).forEach(function(_ref) { var _ref2 = _slicedToArray3(_ref, 2), id2 = _ref2[0], item = _ref2[1]; var type = !prevById.hasOwnProperty(id2) ? "enter" : !nextById.hasOwnProperty(id2) ? "exit" : "update"; result[type].push(type === "update" ? [prevById[id2], nextById[id2]] : item); }); } return result; } function dataBindDiff(data, existingObjs, _ref3) { var _ref3$objBindAttr = _ref3.objBindAttr, objBindAttr = _ref3$objBindAttr === void 0 ? "__obj" : _ref3$objBindAttr, _ref3$dataBindAttr = _ref3.dataBindAttr, dataBindAttr = _ref3$dataBindAttr === void 0 ? "__data" : _ref3$dataBindAttr, idAccessor = _ref3.idAccessor, _ref3$purge = _ref3.purge, purge = _ref3$purge === void 0 ? false : _ref3$purge; var isObjValid = function isObjValid2(obj) { return obj.hasOwnProperty(dataBindAttr); }; var removeObjs = existingObjs.filter(function(obj) { return !isObjValid(obj); }); var prevD = existingObjs.filter(isObjValid).map(function(obj) { return obj[dataBindAttr]; }); var nextD = data; var diff = purge ? { enter: nextD, exit: prevD, update: [] } : diffArrays(prevD, nextD, idAccessor); diff.update = diff.update.map(function(_ref4) { var _ref5 = _slicedToArray3(_ref4, 2), prevD2 = _ref5[0], nextD2 = _ref5[1]; if (prevD2 !== nextD2) { nextD2[objBindAttr] = prevD2[objBindAttr]; nextD2[objBindAttr][dataBindAttr] = nextD2; } return nextD2; }); diff.exit = diff.exit.concat(removeObjs.map(function(obj) { return _defineProperty({}, objBindAttr, obj); })); return diff; } function viewDigest(data, existingObjs, appendObj, removeObj, _ref7) { var _ref7$createObj = _ref7.createObj, createObj = _ref7$createObj === void 0 ? function(d) { return {}; } : _ref7$createObj, _ref7$updateObj = _ref7.updateObj, updateObj = _ref7$updateObj === void 0 ? function(obj, d) { } : _ref7$updateObj, _ref7$exitObj = _ref7.exitObj, exitObj = _ref7$exitObj === void 0 ? function(obj) { } : _ref7$exitObj, _ref7$objBindAttr = _ref7.objBindAttr, objBindAttr = _ref7$objBindAttr === void 0 ? "__obj" : _ref7$objBindAttr, _ref7$dataBindAttr = _ref7.dataBindAttr, dataBindAttr = _ref7$dataBindAttr === void 0 ? "__data" : _ref7$dataBindAttr, dataDiffOptions = _objectWithoutProperties2(_ref7, _excluded); var _dataBindDiff = dataBindDiff(data, existingObjs, _objectSpread2({ objBindAttr, dataBindAttr }, dataDiffOptions)), enter = _dataBindDiff.enter, update4 = _dataBindDiff.update, exit = _dataBindDiff.exit; exit.forEach(function(d) { var obj = d[objBindAttr]; delete d[objBindAttr]; exitObj(obj); removeObj(obj); }); var newObjs = createObjs(enter); var pointsData = [].concat(_toConsumableArray2(enter), _toConsumableArray2(update4)); updateObjs(pointsData); newObjs.forEach(appendObj); function createObjs(data2) { var newObjs2 = []; data2.forEach(function(d) { var obj = createObj(d); if (obj) { obj[dataBindAttr] = d; d[objBindAttr] = obj; newObjs2.push(obj); } }); return newObjs2; } function updateObjs(data2) { data2.forEach(function(d) { var obj = d[objBindAttr]; if (obj) { obj[dataBindAttr] = d; updateObj(obj, d); } }); } } // ../../node_modules/d3-scale/src/init.js function initRange(domain, range) { switch (arguments.length) { case 0: break; case 1: this.range(domain); break; default: this.range(range).domain(domain); break; } return this; } // ../../node_modules/d3-scale/src/ordinal.js var implicit = Symbol("implicit"); function ordinal() { var index5 = new InternMap(), domain = [], range = [], unknown = implicit; function scale(d) { let i = index5.get(d); if (i === void 0) { if (unknown !== implicit) return unknown; index5.set(d, i = domain.push(d) - 1); } return range[i % range.length]; } scale.domain = function(_) { if (!arguments.length) return domain.slice(); domain = [], index5 = new InternMap(); for (const value of _) { if (index5.has(value)) continue; index5.set(value, domain.push(value) - 1); } return scale; }; scale.range = function(_) { return arguments.length ? (range = Array.from(_), scale) : range.slice(); }; scale.unknown = function(_) { return arguments.length ? (unknown = _, scale) : unknown; }; scale.copy = function() { return ordinal(domain, range).unknown(unknown); }; initRange.apply(scale, arguments); return scale; } // ../../node_modules/d3-scale-chromatic/src/colors.js function colors_default(specifier) { var n = specifier.length / 6 | 0, colors = new Array(n), i = 0; while (i < n) colors[i] = "#" + specifier.slice(i * 6, ++i * 6); return colors; } // ../../node_modules/d3-scale-chromatic/src/categorical/Paired.js var Paired_default = colors_default("a6cee31f78b4b2df8a33a02cfb9a99e31a1cfdbf6fff7f00cab2d66a3d9affff99b15928"); // ../../node_modules/tinycolor2/esm/tinycolor.js function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(obj2) { return typeof obj2; } : function(obj2) { return obj2 && "function" == typeof Symbol && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2; }, _typeof(obj); } var trimLeft = /^\s+/; var trimRight = /\s+$/; function tinycolor(color2, opts) { color2 = color2 ? color2 : ""; opts = opts || {}; if (color2 instanceof tinycolor) { return color2; } if (!(this instanceof tinycolor)) { return new tinycolor(color2, opts); } var rgb2 = inputToRGB(color2); this._originalInput = color2, this._r = rgb2.r, this._g = rgb2.g, this._b = rgb2.b, this._a = rgb2.a, this._roundA = Math.round(100 * this._a) / 100, this._format = opts.format || rgb2.format; this._gradientType = opts.gradientType; if (this._r < 1) this._r = Math.round(this._r); if (this._g < 1) this._g = Math.round(this._g); if (this._b < 1) this._b = Math.round(this._b); this._ok = rgb2.ok; } tinycolor.prototype = { isDark: function isDark() { return this.getBrightness() < 128; }, isLight: function isLight() { return !this.isDark(); }, isValid: function isValid() { return this._ok; }, getOriginalInput: function getOriginalInput() { return this._originalInput; }, getFormat: function getFormat() { return this._format; }, getAlpha: function getAlpha() { return this._a; }, getBrightness: function getBrightness() { var rgb2 = this.toRgb(); return (rgb2.r * 299 + rgb2.g * 587 + rgb2.b * 114) / 1e3; }, getLuminance: function getLuminance() { var rgb2 = this.toRgb(); var RsRGB, GsRGB, BsRGB, R, G, B; RsRGB = rgb2.r / 255; GsRGB = rgb2.g / 255; BsRGB = rgb2.b / 255; if (RsRGB <= 0.03928) R = RsRGB / 12.92; else R = Math.pow((RsRGB + 0.055) / 1.055, 2.4); if (GsRGB <= 0.03928) G = GsRGB / 12.92; else G = Math.pow((GsRGB + 0.055) / 1.055, 2.4); if (BsRGB <= 0.03928) B = BsRGB / 12.92; else B = Math.pow((BsRGB + 0.055) / 1.055, 2.4); return 0.2126 * R + 0.7152 * G + 0.0722 * B; }, setAlpha: function setAlpha(value) { this._a = boundAlpha(value); this._roundA = Math.round(100 * this._a) / 100; return this; }, toHsv: function toHsv() { var hsv = rgbToHsv(this._r, this._g, this._b); return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a }; }, toHsvString: function toHsvString() { var hsv = rgbToHsv(this._r, this._g, this._b); var h = Math.round(hsv.h * 360), s = Math.round(hsv.s * 100), v = Math.round(hsv.v * 100); return this._a == 1 ? "hsv(" + h + ", " + s + "%, " + v + "%)" : "hsva(" + h + ", " + s + "%, " + v + "%, " + this._roundA + ")"; }, toHsl: function toHsl() { var hsl2 = rgbToHsl(this._r, this._g, this._b); return { h: hsl2.h * 360, s: hsl2.s, l: hsl2.l, a: this._a }; }, toHslString: function toHslString() { var hsl2 = rgbToHsl(this._r, this._g, this._b); var h = Math.round(hsl2.h * 360), s = Math.round(hsl2.s * 100), l = Math.round(hsl2.l * 100); return this._a == 1 ? "hsl(" + h + ", " + s + "%, " + l + "%)" : "hsla(" + h + ", " + s + "%, " + l + "%, " + this._roundA + ")"; }, toHex: function toHex(allow3Char) { return rgbToHex(this._r, this._g, this._b, allow3Char); }, toHexString: function toHexString(allow3Char) { return "#" + this.toHex(allow3Char); }, toHex8: function toHex8(allow4Char) { return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char); }, toHex8String: function toHex8String(allow4Char) { return "#" + this.toHex8(allow4Char); }, toRgb: function toRgb() { return { r: Math.round(this._r), g: Math.round(this._g), b: Math.round(this._b), a: this._a }; }, toRgbString: function toRgbString() { return this._a == 1 ? "rgb(" + Math.round(this._r) + ", " + Math.round(this._g) + ", " + Math.round(this._b) + ")" : "rgba(" + Math.round(this._r) + ", " + Math.round(this._g) + ", " + Math.round(this._b) + ", " + this._roundA + ")"; }, toPercentageRgb: function toPercentageRgb() { return { r: Math.round(bound01(this._r, 255) * 100) + "%", g: Math.round(bound01(this._g, 255) * 100) + "%", b: Math.round(bound01(this._b, 255) * 100) + "%", a: this._a }; }, toPercentageRgbString: function toPercentageRgbString() { return this._a == 1 ? "rgb(" + Math.round(bound01(this._r, 255) * 100) + "%, " + Math.round(bound01(this._g, 255) * 100) + "%, " + Math.round(bound01(this._b, 255) * 100) + "%)" : "rgba(" + Math.round(bound01(this._r, 255) * 100) + "%, " + Math.round(bound01(this._g, 255) * 100) + "%, " + Math.round(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")"; }, toName: function toName() { if (this._a === 0) { return "transparent"; } if (this._a < 1) { return false; } return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false; }, toFilter: function toFilter(secondColor) { var hex8String = "#" + rgbaToArgbHex(this._r, this._g, this._b, this._a); var secondHex8String = hex8String; var gradientType = this._gradientType ? "GradientType = 1, " : ""; if (secondColor) { var s = tinycolor(secondColor); secondHex8String = "#" + rgbaToArgbHex(s._r, s._g, s._b, s._a); } return "progid:DXImageTransform.Microsoft.gradient(" + gradientType + "startColorstr=" + hex8String + ",endColorstr=" + secondHex8String + ")"; }, toString: function toString(format2) { var formatSet = !!format2; format2 = format2 || this._format; var formattedString = false; var hasAlpha = this._a < 1 && this._a >= 0; var needsAlphaFormat = !formatSet && hasAlpha && (format2 === "hex" || format2 === "hex6" || format2 === "hex3" || format2 === "hex4" || format2 === "hex8" || format2 === "name"); if (needsAlphaFormat) { if (format2 === "name" && this._a === 0) { return this.toName(); } return this.toRgbString(); } if (format2 === "rgb") { formattedString = this.toRgbString(); } if (format2 === "prgb") { formattedString = this.toPercentageRgbString(); } if (format2 === "hex" || format2 === "hex6") { formattedString = this.toHexString(); } if (format2 === "hex3") { formattedString = this.toHexString(true); } if (format2 === "hex4") { formattedString = this.toHex8String(true); } if (format2 === "hex8") { formattedString = this.toHex8String(); } if (format2 === "name") { formattedString = this.toName(); } if (format2 === "hsl") { formattedString = this.toHslString(); } if (format2 === "hsv") { formattedString = this.toHsvString(); } return formattedString || this.toHexString(); }, clone: function clone() { return tinycolor(this.toString()); }, _applyModification: function _applyModification(fn, args) { var color2 = fn.apply(null, [this].concat([].slice.call(args))); this._r = color2._r; this._g = color2._g; this._b = color2._b; this.setAlpha(color2._a); return this; }, lighten: function lighten() { return this._applyModification(_lighten, arguments); }, brighten: function brighten() { return this._applyModification(_brighten, arguments); }, darken: function darken() { return this._applyModification(_darken, arguments); }, desaturate: function desaturate() { return this._applyModification(_desaturate, arguments); }, saturate: function saturate() { return this._applyModification(_saturate, arguments); }, greyscale: function greyscale() { return this._applyModification(_greyscale, arguments); }, spin: function spin() { return this._applyModification(_spin, arguments); }, _applyCombination: function _applyCombination(fn, args) { return fn.apply(null, [this].concat([].slice.call(args))); }, analogous: function analogous() { return this._applyCombination(_analogous, arguments); }, complement: function complement() { return this._applyCombination(_complement, arguments); }, monochromatic: function monochromatic() { return this._applyCombination(_monochromatic, arguments); }, splitcomplement: function splitcomplement() { return this._applyCombination(_splitcomplement, arguments); }, // Disabled until https://github.com/bgrins/TinyColor/issues/254 // polyad: function (number) { // return this._applyCombination(polyad, [number]); // }, triad: function triad() { return this._applyCombination(polyad, [3]); }, tetrad: function tetrad() { return this._applyCombination(polyad, [4]); } }; tinycolor.fromRatio = function(color2, opts) { if (_typeof(color2) == "object") { var newColor = {}; for (var i in color2) { if (color2.hasOwnProperty(i)) { if (i === "a") { newColor[i] = color2[i]; } else { newColor[i] = convertToPercentage(color2[i]); } } } color2 = newColor; } return tinycolor(color2, opts); }; function inputToRGB(color2) { var rgb2 = { r: 0, g: 0, b: 0 }; var a2 = 1; var s = null; var v = null; var l = null; var ok = false; var format2 = false; if (typeof color2 == "string") { color2 = stringInputToObject(color2); } if (_typeof(color2) == "object") { if (isValidCSSUnit(color2.r) && isValidCSSUnit(color2.g) && isValidCSSUnit(color2.b)) { rgb2 = rgbToRgb(color2.r, color2.g, color2.b); ok = true; format2 = String(color2.r).substr(-1) === "%" ? "prgb" : "rgb"; } else if (isValidCSSUnit(color2.h) && isValidCSSUnit(color2.s) && isValidCSSUnit(color2.v)) { s = convertToPercentage(color2.s); v = convertToPercentage(color2.v); rgb2 = hsvToRgb(color2.h, s, v); ok = true; format2 = "hsv"; } else if (isValidCSSUnit(color2.h) && isValidCSSUnit(color2.s) && isValidCSSUnit(color2.l)) { s = convertToPercentage(color2.s); l = convertToPercentage(color2.l); rgb2 = hslToRgb(color2.h, s, l); ok = true; format2 = "hsl"; } if (color2.hasOwnProperty("a")) { a2 = color2.a; } } a2 = boundAlpha(a2); return { ok, format: color2.format || format2, r: Math.min(255, Math.max(rgb2.r, 0)), g: Math.min(255, Math.max(rgb2.g, 0)), b: Math.min(255, Math.max(rgb2.b, 0)), a: a2 }; } function rgbToRgb(r, g, b) { return { r: bound01(r, 255) * 255, g: bound01(g, 255) * 255, b: bound01(b, 255) * 255 }; } function rgbToHsl(r, g, b) { r = bound01(r, 255); g = bound01(g, 255); b = bound01(b, 255); var max2 = Math.max(r, g, b), min2 = Math.min(r, g, b); var h, s, l = (max2 + min2) / 2; if (max2 == min2) { h = s = 0; } else { var d = max2 - min2; s = l > 0.5 ? d / (2 - max2 - min2) : d / (max2 + min2); switch (max2) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return { h, s, l }; } function hslToRgb(h, s, l) { var r, g, b; h = bound01(h, 360); s = bound01(s, 100); l = bound01(l, 100); function hue2rgb3(p2, q2, t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t; if (t < 1 / 2) return q2; if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6; return p2; } if (s === 0) { r = g = b = l; } else { var q = l < 0.5 ? l * (1 + s) : l + s - l * s; var p = 2 * l - q; r = hue2rgb3(p, q, h + 1 / 3); g = hue2rgb3(p, q, h); b = hue2rgb3(p, q, h - 1 / 3); } return { r: r * 255, g: g * 255, b: b * 255 }; } function rgbToHsv(r, g, b) { r = bound01(r, 255); g = bound01(g, 255); b = bound01(b, 255); var max2 = Math.max(r, g, b), min2 = Math.min(r, g, b); var h, s, v = max2; var d = max2 - min2; s = max2 === 0 ? 0 : d / max2; if (max2 == min2) { h = 0; } else { switch (max2) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return { h, s, v }; } function hsvToRgb(h, s, v) { h = bound01(h, 360) * 6; s = bound01(s, 100); v = bound01(v, 100); var i = Math.floor(h), f = h - i, p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s), mod2 = i % 6, r = [v, q, p, p, t, v][mod2], g = [t, v, v, q, p, p][mod2], b = [p, p, t, v, v, q][mod2]; return { r: r * 255, g: g * 255, b: b * 255 }; } function rgbToHex(r, g, b, allow3Char) { var hex = [pad2(Math.round(r).toString(16)), pad2(Math.round(g).toString(16)), pad2(Math.round(b).toString(16))]; if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) { return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0); } return hex.join(""); } function rgbaToHex(r, g, b, a2, allow4Char) { var hex = [pad2(Math.round(r).toString(16)), pad2(Math.round(g).toString(16)), pad2(Math.round(b).toString(16)), pad2(convertDecimalToHex(a2))]; if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) { return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0); } return hex.join(""); } function rgbaToArgbHex(r, g, b, a2) { var hex = [pad2(convertDecimalToHex(a2)), pad2(Math.round(r).toString(16)), pad2(Math.round(g).toString(16)), pad2(Math.round(b).toString(16))]; return hex.join(""); } tinycolor.equals = function(color1, color2) { if (!color1 || !color2) return false; return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString(); }; tinycolor.random = function() { return tinycolor.fromRatio({ r: Math.random(), g: Math.random(), b: Math.random() }); }; function _desaturate(color2, amount) { amount = amount === 0 ? 0 : amount || 10; var hsl2 = tinycolor(color2).toHsl(); hsl2.s -= amount / 100; hsl2.s = clamp01(hsl2.s); return tinycolor(hsl2); } function _saturate(color2, amount) { amount = amount === 0 ? 0 : amount || 10; var hsl2 = tinycolor(color2).toHsl(); hsl2.s += amount / 100; hsl2.s = clamp01(hsl2.s); return tinycolor(hsl2); } function _greyscale(color2) { return tinycolor(color2).desaturate(100); } function _lighten(color2, amount) { amount = amount === 0 ? 0 : amount || 10; var hsl2 = tinycolor(color2).toHsl(); hsl2.l += amount / 100; hsl2.l = clamp01(hsl2.l); return tinycolor(hsl2); } function _brighten(color2, amount) { amount = amount === 0 ? 0 : amount || 10; var rgb2 = tinycolor(color2).toRgb(); rgb2.r = Math.max(0, Math.min(255, rgb2.r - Math.round(255 * -(amount / 100)))); rgb2.g = Math.max(0, Math.min(255, rgb2.g - Math.round(255 * -(amount / 100)))); rgb2.b = Math.max(0, Math.min(255, rgb2.b - Math.round(255 * -(amount / 100)))); return tinycolor(rgb2); } function _darken(color2, amount) { amount = amount === 0 ? 0 : amount || 10; var hsl2 = tinycolor(color2).toHsl(); hsl2.l -= amount / 100; hsl2.l = clamp01(hsl2.l); return tinycolor(hsl2); } function _spin(color2, amount) { var hsl2 = tinycolor(color2).toHsl(); var hue = (hsl2.h + amount) % 360; hsl2.h = hue < 0 ? 360 + hue : hue; return tinycolor(hsl2); } function _complement(color2) { var hsl2 = tinycolor(color2).toHsl(); hsl2.h = (hsl2.h + 180) % 360; return tinycolor(hsl2); } function polyad(color2, number) { if (isNaN(number) || number <= 0) { throw new Error("Argument to polyad must be a positive number"); } var hsl2 = tinycolor(color2).toHsl(); var result = [tinycolor(color2)]; var step2 = 360 / number; for (var i = 1; i < number; i++) { result.push(tinycolor({ h: (hsl2.h + i * step2) % 360, s: hsl2.s, l: hsl2.l })); } return result; } function _splitcomplement(color2) { var hsl2 = tinycolor(color2).toHsl(); var h = hsl2.h; return [tinycolor(color2), tinycolor({ h: (h + 72) % 360, s: hsl2.s, l: hsl2.l }), tinycolor({ h: (h + 216) % 360, s: hsl2.s, l: hsl2.l })]; } function _analogous(color2, results, slices) { results = results || 6; slices = slices || 30; var hsl2 = tinycolor(color2).toHsl(); var part = 360 / slices; var ret = [tinycolor(color2)]; for (hsl2.h = (hsl2.h - (part * results >> 1) + 720) % 360; --results; ) { hsl2.h = (hsl2.h + part) % 360; ret.push(tinycolor(hsl2)); } return ret; } function _monochromatic(color2, results) { results = results || 6; var hsv = tinycolor(color2).toHsv(); var h = hsv.h, s = hsv.s, v = hsv.v; var ret = []; var modification = 1 / results; while (results--) { ret.push(tinycolor({ h, s, v })); v = (v + modification) % 1; } return ret; } tinycolor.mix = function(color1, color2, amount) { amount = amount === 0 ? 0 : amount || 50; var rgb1 = tinycolor(color1).toRgb(); var rgb2 = tinycolor(color2).toRgb(); var p = amount / 100; var rgba2 = { r: (rgb2.r - rgb1.r) * p + rgb1.r, g: (rgb2.g - rgb1.g) * p + rgb1.g, b: (rgb2.b - rgb1.b) * p + rgb1.b, a: (rgb2.a - rgb1.a) * p + rgb1.a }; return tinycolor(rgba2); }; tinycolor.readability = function(color1, color2) { var c1 = tinycolor(color1); var c2 = tinycolor(color2); return (Math.max(c1.getLuminance(), c2.getLuminance()) + 0.05) / (Math.min(c1.getLuminance(), c2.getLuminance()) + 0.05); }; tinycolor.isReadable = function(color1, color2, wcag2) { var readability = tinycolor.readability(color1, color2); var wcag2Parms, out; out = false; wcag2Parms = validateWCAG2Parms(wcag2); switch (wcag2Parms.level + wcag2Parms.size) { case "AAsmall": case "AAAlarge": out = readability >= 4.5; break; case "AAlarge": out = readability >= 3; break; case "AAAsmall": out = readability >= 7; break; } return out; }; tinycolor.mostReadable = function(baseColor, colorList, args) { var bestColor = null; var bestScore = 0; var readability; var includeFallbackColors, level, size; args = args || {}; includeFallbackColors = args.includeFallbackColors; level = args.level; size = args.size; for (var i = 0; i < colorList.length; i++) { readability = tinycolor.readability(baseColor, colorList[i]); if (readability > bestScore) { bestScore = readability; bestColor = tinycolor(colorList[i]); } } if (tinycolor.isReadable(baseColor, bestColor, { level, size }) || !includeFallbackColors) { return bestColor; } else { args.includeFallbackColors = false; return tinycolor.mostReadable(baseColor, ["#fff", "#000"], args); } }; var names = tinycolor.names = { aliceblue: "f0f8ff", antiquewhite: "faebd7", aqua: "0ff", aquamarine: "7fffd4", azure: "f0ffff", beige: "f5f5dc", bisque: "ffe4c4", black: "000", blanchedalmond: "ffebcd", blue: "00f", blueviolet: "8a2be2", brown: "a52a2a", burlywood: "deb887", burntsienna: "ea7e5d", cadetblue: "5f9ea0", chartreuse: "7fff00", chocolate: "d2691e", coral: "ff7f50", cornflowerblue: "6495ed", cornsilk: "fff8dc", crimson: "dc143c", cyan: "0ff", darkblue: "00008b", darkcyan: "008b8b", darkgoldenrod: "b8860b", darkgray: "a9a9a9", darkgreen: "006400", darkgrey: "a9a9a9", darkkhaki: "bdb76b", darkmagenta: "8b008b", darkolivegreen: "556b2f", darkorange: "ff8c00", darkorchid: "9932cc", darkred: "8b0000", darksalmon: "e9967a", darkseagreen: "8fbc8f", darkslateblue: "483d8b", darkslategray: "2f4f4f", darkslategrey: "2f4f4f", darkturquoise: "00ced1", darkviolet: "9400d3", deeppink: "ff1493", deepskyblue: "00bfff", dimgray: "696969", dimgrey: "696969", dodgerblue: "1e90ff", firebrick: "b22222", floralwhite: "fffaf0", forestgreen: "228b22", fuchsia: "f0f", gainsboro: "dcdcdc", ghostwhite: "f8f8ff", gold: "ffd700", goldenrod: "daa520", gray: "808080", green: "008000", greenyellow: "adff2f", grey: "808080", honeydew: "f0fff0", hotpink: "ff69b4", indianred: "cd5c5c", indigo: "4b0082", ivory: "fffff0", khaki: "f0e68c", lavender: "e6e6fa", lavenderblush: "fff0f5", lawngreen: "7cfc00", lemonchiffon: "fffacd", lightblue: "add8e6", lightcoral: "f08080", lightcyan: "e0ffff", lightgoldenrodyellow: "fafad2", lightgray: "d3d3d3", lightgreen: "90ee90", lightgrey: "d3d3d3", lightpink: "ffb6c1", lightsalmon: "ffa07a", lightseagreen: "20b2aa", lightskyblue: "87cefa", lightslategray: "789", lightslategrey: "789", lightsteelblue: "b0c4de", lightyellow: "ffffe0", lime: "0f0", limegreen: "32cd32", linen: "faf0e6", magenta: "f0f", maroon: "800000", mediumaquamarine: "66cdaa", mediumblue: "0000cd", mediumorchid: "ba55d3", mediumpurple: "9370db", mediumseagreen: "3cb371", mediumslateblue: "7b68ee", mediumspringgreen: "00fa9a", mediumturquoise: "48d1cc", mediumvioletred: "c71585", midnightblue: "191970", mintcream: "f5fffa", mistyrose: "ffe4e1", moccasin: "ffe4b5", navajowhite: "ffdead", navy: "000080", oldlace: "fdf5e6", olive: "808000", olivedrab: "6b8e23", orange: "ffa500", orangered: "ff4500", orchid: "da70d6", palegoldenrod: "eee8aa", palegreen: "98fb98", paleturquoise: "afeeee", palevioletred: "db7093", papayawhip: "ffefd5", peachpuff: "ffdab9", peru: "cd853f", pink: "ffc0cb", plum: "dda0dd", powderblue: "b0e0e6", purple: "800080", rebeccapurple: "663399", red: "f00", rosybrown: "bc8f8f", royalblue: "4169e1", saddlebrown: "8b4513", salmon: "fa8072", sandybrown: "f4a460", seagreen: "2e8b57", seashell: "fff5ee", sienna: "a0522d", silver: "c0c0c0", skyblue: "87ceeb", slateblue: "6a5acd", slategray: "708090", slategrey: "708090", snow: "fffafa", springgreen: "00ff7f", steelblue: "4682b4", tan: "d2b48c", teal: "008080", thistle: "d8bfd8", tomato: "ff6347", turquoise: "40e0d0", violet: "ee82ee", wheat: "f5deb3", white: "fff", whitesmoke: "f5f5f5", yellow: "ff0", yellowgreen: "9acd32" }; var hexNames = tinycolor.hexNames = flip(names); function flip(o) { var flipped = {}; for (var i in o) { if (o.hasOwnProperty(i)) { flipped[o[i]] = i; } } return flipped; } function boundAlpha(a2) { a2 = parseFloat(a2); if (isNaN(a2) || a2 < 0 || a2 > 1) { a2 = 1; } return a2; } function bound01(n, max2) { if (isOnePointZero(n)) n = "100%"; var processPercent = isPercentage(n); n = Math.min(max2, Math.max(0, parseFloat(n))); if (processPercent) { n = parseInt(n * max2, 10) / 100; } if (Math.abs(n - max2) < 1e-6) { return 1; } return n % max2 / parseFloat(max2); } function clamp01(val) { return Math.min(1, Math.max(0, val)); } function parseIntFromHex(val) { return parseInt(val, 16); } function isOnePointZero(n) { return typeof n == "string" && n.indexOf(".") != -1 && parseFloat(n) === 1; } function isPercentage(n) { return typeof n === "string" && n.indexOf("%") != -1; } function pad2(c2) { return c2.length == 1 ? "0" + c2 : "" + c2; } function convertToPercentage(n) { if (n <= 1) { n = n * 100 + "%"; } return n; } function convertDecimalToHex(d) { return Math.round(parseFloat(d) * 255).toString(16); } function convertHexToDecimal(h) { return parseIntFromHex(h) / 255; } var matchers = function() { var CSS_INTEGER = "[-\\+]?\\d+%?"; var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")"; var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; return { CSS_UNIT: new RegExp(CSS_UNIT), rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), hsva: new RegExp("hsva" + PERMISSIVE_MATCH4), hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ }; }(); function isValidCSSUnit(color2) { return !!matchers.CSS_UNIT.exec(color2); } function stringInputToObject(color2) { color2 = color2.replace(trimLeft, "").replace(trimRight, "").toLowerCase(); var named = false; if (names[color2]) { color2 = names[color2]; named = true; } else if (color2 == "transparent") { return { r: 0, g: 0, b: 0, a: 0, format: "name" }; } var match; if (match = matchers.rgb.exec(color2)) { return { r: match[1], g: match[2], b: match[3] }; } if (match = matchers.rgba.exec(color2)) { return { r: match[1], g: match[2], b: match[3], a: match[4] }; } if (match = matchers.hsl.exec(color2)) { return { h: match[1], s: match[2], l: match[3] }; } if (match = matchers.hsla.exec(color2)) { return { h: match[1], s: match[2], l: match[3], a: match[4] }; } if (match = matchers.hsv.exec(color2)) { return { h: match[1], s: match[2], v: match[3] }; } if (match = matchers.hsva.exec(color2)) { return { h: match[1], s: match[2], v: match[3], a: match[4] }; } if (match = matchers.hex8.exec(color2)) { return { r: parseIntFromHex(match[1]), g: parseIntFromHex(match[2]), b: parseIntFromHex(match[3]), a: convertHexToDecimal(match[4]), format: named ? "name" : "hex8" }; } if (match = matchers.hex6.exec(color2)) { return { r: parseIntFromHex(match[1]), g: parseIntFromHex(match[2]), b: parseIntFromHex(match[3]), format: named ? "name" : "hex" }; } if (match = matchers.hex4.exec(color2)) { return { r: parseIntFromHex(match[1] + "" + match[1]), g: parseIntFromHex(match[2] + "" + match[2]), b: parseIntFromHex(match[3] + "" + match[3]), a: convertHexToDecimal(match[4] + "" + match[4]), format: named ? "name" : "hex8" }; } if (match = matchers.hex3.exec(color2)) { return { r: parseIntFromHex(match[1] + "" + match[1]), g: parseIntFromHex(match[2] + "" + match[2]), b: parseIntFromHex(match[3] + "" + match[3]), format: named ? "name" : "hex" }; } return false; } function validateWCAG2Parms(parms) { var level, size; parms = parms || { level: "AA", size: "small" }; level = (parms.level || "AA").toUpperCase(); size = (parms.size || "small").toLowerCase(); if (level !== "AA" && level !== "AAA") { level = "AA"; } if (size !== "small" && size !== "large") { size = "small"; } return { level, size }; } // ../../node_modules/three-forcegraph/dist/three-forcegraph.mjs function _arrayLikeToArray4(r, a2) { (null == a2 || a2 > r.length) && (a2 = r.length); for (var e = 0, n = Array(a2); e < a2; e++) n[e] = r[e]; return n; } function _arrayWithHoles4(r) { if (Array.isArray(r)) return r; } function _arrayWithoutHoles3(r) { if (Array.isArray(r)) return _arrayLikeToArray4(r); } function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _classCallCheck2(a2, n) { if (!(a2 instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _construct(t, e, r) { if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); var o = [null]; o.push.apply(o, e); var p = new (t.bind.apply(t, o))(); return p; } function _createClass2(e, r, t) { return Object.defineProperty(e, "prototype", { writable: false }), e; } function _defineProperty2(e, r, t) { return (r = _toPropertyKey3(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e; } function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(t2) { return t2.__proto__ || Object.getPrototypeOf(t2); }, _getPrototypeOf(t); } function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: true, configurable: true } }), Object.defineProperty(t, "prototype", { writable: false }), e && _setPrototypeOf(t, e); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() { })); } catch (t2) { } return (_isNativeReflectConstruct = function() { return !!t; })(); } function _iterableToArray3(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _iterableToArrayLimit4(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a2 = [], f = true, o = false; try { if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a2.push(e.value), a2.length !== l); f = true) ; } catch (r2) { o = true, n = r2; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a2; } } function _nonIterableRest4() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableSpread3() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function ownKeys2(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function(r2) { return Object.getOwnPropertyDescriptor(e, r2).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread22(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys2(Object(t), true).forEach(function(r2) { _defineProperty2(e, r2, t[r2]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys2(Object(t)).forEach(function(r2) { Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2)); }); } return e; } function _objectWithoutProperties3(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose3(e, t); if (Object.getOwnPropertySymbols) { var s = Object.getOwnPropertySymbols(e); for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } function _objectWithoutPropertiesLoose3(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; } function _possibleConstructorReturn(t, e) { if (e && ("object" == typeof e || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); } function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(t2, e2) { return t2.__proto__ = e2, t2; }, _setPrototypeOf(t, e); } function _slicedToArray4(r, e) { return _arrayWithHoles4(r) || _iterableToArrayLimit4(r, e) || _unsupportedIterableToArray4(r, e) || _nonIterableRest4(); } function _toConsumableArray3(r) { return _arrayWithoutHoles3(r) || _iterableToArray3(r) || _unsupportedIterableToArray4(r) || _nonIterableSpread3(); } function _toPrimitive3(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _toPropertyKey3(t) { var i = _toPrimitive3(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _typeof2(o) { "@babel/helpers - typeof"; return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o2) { return typeof o2; } : function(o2) { return o2 && "function" == typeof Symbol && o2.constructor === Symbol && o2 !== Symbol.prototype ? "symbol" : typeof o2; }, _typeof2(o); } function _unsupportedIterableToArray4(r, a2) { if (r) { if ("string" == typeof r) return _arrayLikeToArray4(r, a2); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray4(r, a2) : void 0; } } var _materialDispose = function materialDispose(material) { if (material instanceof Array) { material.forEach(_materialDispose); } else { if (material.map) { material.map.dispose(); } material.dispose(); } }; var _deallocate = function deallocate(obj) { if (obj.geometry) { obj.geometry.dispose(); } if (obj.material) { _materialDispose(obj.material); } if (obj.texture) { obj.texture.dispose(); } if (obj.children) { obj.children.forEach(_deallocate); } }; var emptyObject = function emptyObject2(obj) { while (obj.children.length) { var childObj = obj.children[0]; obj.remove(childObj); _deallocate(childObj); } }; var _excluded2 = ["objFilter"]; function threeDigest(data, scene3) { var _ref = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}, _ref$objFilter = _ref.objFilter, objFilter = _ref$objFilter === void 0 ? function() { return true; } : _ref$objFilter, options = _objectWithoutProperties3(_ref, _excluded2); return viewDigest(data, scene3.children.filter(objFilter), function(obj) { return scene3.add(obj); }, function(obj) { scene3.remove(obj); emptyObject(obj); }, _objectSpread22({ objBindAttr: "__threeObj" }, options)); } var colorStr2Hex = function colorStr2Hex2(str) { return isNaN(str) ? parseInt(tinycolor(str).toHex(), 16) : str; }; var colorAlpha = function colorAlpha2(str) { return isNaN(str) ? tinycolor(str).getAlpha() : 1; }; var autoColorScale = ordinal(Paired_default); function autoColorObjects(objects, colorByAccessor, colorField) { if (!colorByAccessor || typeof colorField !== "string") return; objects.filter(function(obj) { return !obj[colorField]; }).forEach(function(obj) { obj[colorField] = autoColorScale(colorByAccessor(obj)); }); } function getDagDepths(_ref, idAccessor) { var nodes = _ref.nodes, links = _ref.links; var _ref2 = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}, _ref2$nodeFilter = _ref2.nodeFilter, nodeFilter = _ref2$nodeFilter === void 0 ? function() { return true; } : _ref2$nodeFilter, _ref2$onLoopError = _ref2.onLoopError, onLoopError = _ref2$onLoopError === void 0 ? function(loopIds) { throw "Invalid DAG structure! Found cycle in node path: ".concat(loopIds.join(" -> "), "."); } : _ref2$onLoopError; var graph2 = {}; nodes.forEach(function(node) { return graph2[idAccessor(node)] = { data: node, out: [], depth: -1, skip: !nodeFilter(node) }; }); links.forEach(function(_ref3) { var source = _ref3.source, target = _ref3.target; var sourceId = getNodeId(source); var targetId = getNodeId(target); if (!graph2.hasOwnProperty(sourceId)) throw "Missing source node with id: ".concat(sourceId); if (!graph2.hasOwnProperty(targetId)) throw "Missing target node with id: ".concat(targetId); var sourceNode = graph2[sourceId]; var targetNode = graph2[targetId]; sourceNode.out.push(targetNode); function getNodeId(node) { return _typeof2(node) === "object" ? idAccessor(node) : node; } }); var foundLoops = []; traverse(Object.values(graph2)); var nodeDepths = Object.assign.apply(Object, [{}].concat(_toConsumableArray3(Object.entries(graph2).filter(function(_ref4) { var _ref5 = _slicedToArray4(_ref4, 2), node = _ref5[1]; return !node.skip; }).map(function(_ref6) { var _ref7 = _slicedToArray4(_ref6, 2), id2 = _ref7[0], node = _ref7[1]; return _defineProperty2({}, id2, node.depth); })))); return nodeDepths; function traverse(nodes2) { var nodeStack = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : []; var currentDepth = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 0; var _loop = function _loop2() { var node = nodes2[i]; if (nodeStack.indexOf(node) !== -1) { var loop = [].concat(_toConsumableArray3(nodeStack.slice(nodeStack.indexOf(node))), [node]).map(function(d) { return idAccessor(d.data); }); if (!foundLoops.some(function(foundLoop) { return foundLoop.length === loop.length && foundLoop.every(function(id2, idx) { return id2 === loop[idx]; }); })) { foundLoops.push(loop); onLoopError(loop); } return 1; } if (currentDepth > node.depth) { node.depth = currentDepth; traverse(node.out, [].concat(_toConsumableArray3(nodeStack), [node]), currentDepth + (node.skip ? 0 : 1)); } }; for (var i = 0, l = nodes2.length; i < l; i++) { if (_loop()) continue; } } } var three$1 = window.THREE ? window.THREE : { Group, Mesh, MeshLambertMaterial, Color, BufferGeometry, BufferAttribute, Matrix4, Vector3, SphereGeometry, CylinderGeometry, TubeGeometry, ConeGeometry, Line, LineBasicMaterial, QuadraticBezierCurve3, CubicBezierCurve3, Box3 }; var ngraph = { graph: import_ngraph.default, forcelayout: import_ngraph2.default }; var DAG_LEVEL_NODE_RATIO = 2; var setAttributeFn = new three$1.BufferGeometry().setAttribute ? "setAttribute" : "addAttribute"; var applyMatrix4Fn = new three$1.BufferGeometry().applyMatrix4 ? "applyMatrix4" : "applyMatrix"; var ForceGraph = index2({ props: { jsonUrl: { onChange: function onChange(jsonUrl, state) { var _this = this; if (jsonUrl && !state.fetchingJson) { state.fetchingJson = true; state.onLoading(); fetch(jsonUrl).then(function(r) { return r.json(); }).then(function(json) { state.fetchingJson = false; state.onFinishLoading(json); _this.graphData(json); }); } }, triggerUpdate: false }, graphData: { "default": { nodes: [], links: [] }, onChange: function onChange2(graphData, state) { state.engineRunning = false; } }, numDimensions: { "default": 3, onChange: function onChange3(numDim, state) { var chargeForce = state.d3ForceLayout.force("charge"); if (chargeForce) { chargeForce.strength(numDim > 2 ? -60 : -30); } if (numDim < 3) { eraseDimension(state.graphData.nodes, "z"); } if (numDim < 2) { eraseDimension(state.graphData.nodes, "y"); } function eraseDimension(nodes, dim) { nodes.forEach(function(d) { delete d[dim]; delete d["v".concat(dim)]; }); } } }, dagMode: { onChange: function onChange4(dagMode, state) { !dagMode && state.forceEngine === "d3" && (state.graphData.nodes || []).forEach(function(n) { return n.fx = n.fy = n.fz = void 0; }); } }, dagLevelDistance: {}, dagNodeFilter: { "default": function _default(node) { return true; } }, onDagError: { triggerUpdate: false }, nodeRelSize: { "default": 4 }, // volume per val unit nodeId: { "default": "id" }, nodeVal: { "default": "val" }, nodeResolution: { "default": 8 }, // how many slice segments in the sphere's circumference nodeColor: { "default": "color" }, nodeAutoColorBy: {}, nodeOpacity: { "default": 0.75 }, nodeVisibility: { "default": true }, nodeThreeObject: {}, nodeThreeObjectExtend: { "default": false }, nodePositionUpdate: { triggerUpdate: false }, // custom function to call for updating the node's position. Signature: (threeObj, { x, y, z}, node). If the function returns a truthy value, the regular node position update will not run. linkSource: { "default": "source" }, linkTarget: { "default": "target" }, linkVisibility: { "default": true }, linkColor: { "default": "color" }, linkAutoColorBy: {}, linkOpacity: { "default": 0.2 }, linkWidth: {}, // Rounded to nearest decimal. For falsy values use dimensionless line with 1px regardless of distance. linkResolution: { "default": 6 }, // how many radial segments in each line tube's geometry linkCurvature: { "default": 0, triggerUpdate: false }, // line curvature radius (0: straight, 1: semi-circle) linkCurveRotation: { "default": 0, triggerUpdate: false }, // line curve rotation along the line axis (0: interection with XY plane, PI: upside down) linkMaterial: {}, linkThreeObject: {}, linkThreeObjectExtend: { "default": false }, linkPositionUpdate: { triggerUpdate: false }, // custom function to call for updating the link's position. Signature: (threeObj, { start: { x, y, z}, end: { x, y, z }}, link). If the function returns a truthy value, the regular link position update will not run. linkDirectionalArrowLength: { "default": 0 }, linkDirectionalArrowColor: {}, linkDirectionalArrowRelPos: { "default": 0.5, triggerUpdate: false }, // value between 0<>1 indicating the relative pos along the (exposed) line linkDirectionalArrowResolution: { "default": 8 }, // how many slice segments in the arrow's conic circumference linkDirectionalParticles: { "default": 0 }, // animate photons travelling in the link direction linkDirectionalParticleSpeed: { "default": 0.01, triggerUpdate: false }, // in link length ratio per frame linkDirectionalParticleWidth: { "default": 0.5 }, linkDirectionalParticleColor: {}, linkDirectionalParticleResolution: { "default": 4 }, // how many slice segments in the particle sphere's circumference forceEngine: { "default": "d3" }, // d3 or ngraph d3AlphaMin: { "default": 0 }, d3AlphaDecay: { "default": 0.0228, triggerUpdate: false, onChange: function onChange5(alphaDecay, state) { state.d3ForceLayout.alphaDecay(alphaDecay); } }, d3AlphaTarget: { "default": 0, triggerUpdate: false, onChange: function onChange6(alphaTarget, state) { state.d3ForceLayout.alphaTarget(alphaTarget); } }, d3VelocityDecay: { "default": 0.4, triggerUpdate: false, onChange: function onChange7(velocityDecay, state) { state.d3ForceLayout.velocityDecay(velocityDecay); } }, ngraphPhysics: { "default": { // defaults from https://github.com/anvaka/ngraph.physics.simulator/blob/master/index.js timeStep: 20, gravity: -1.2, theta: 0.8, springLength: 30, springCoefficient: 8e-4, dragCoefficient: 0.02 } }, warmupTicks: { "default": 0, triggerUpdate: false }, // how many times to tick the force engine at init before starting to render cooldownTicks: { "default": Infinity, triggerUpdate: false }, cooldownTime: { "default": 15e3, triggerUpdate: false }, // ms onLoading: { "default": function _default2() { }, triggerUpdate: false }, onFinishLoading: { "default": function _default3() { }, triggerUpdate: false }, onUpdate: { "default": function _default4() { }, triggerUpdate: false }, onFinishUpdate: { "default": function _default5() { }, triggerUpdate: false }, onEngineTick: { "default": function _default6() { }, triggerUpdate: false }, onEngineStop: { "default": function _default7() { }, triggerUpdate: false } }, methods: { refresh: function refresh(state) { state._flushObjects = true; state._rerender(); return this; }, // Expose d3 forces for external manipulation d3Force: function d3Force(state, forceName, forceFn) { if (forceFn === void 0) { return state.d3ForceLayout.force(forceName); } state.d3ForceLayout.force(forceName, forceFn); return this; }, d3ReheatSimulation: function d3ReheatSimulation(state) { state.d3ForceLayout.alpha(1); this.resetCountdown(); return this; }, // reset cooldown state resetCountdown: function resetCountdown(state) { state.cntTicks = 0; state.startTickTime = /* @__PURE__ */ new Date(); state.engineRunning = true; return this; }, tickFrame: function tickFrame(state) { var isD3Sim = state.forceEngine !== "ngraph"; if (state.engineRunning) { layoutTick(); } updateArrows(); updatePhotons(); return this; function layoutTick() { if (++state.cntTicks > state.cooldownTicks || /* @__PURE__ */ new Date() - state.startTickTime > state.cooldownTime || isD3Sim && state.d3AlphaMin > 0 && state.d3ForceLayout.alpha() < state.d3AlphaMin) { state.engineRunning = false; state.onEngineStop(); } else { state.layout[isD3Sim ? "tick" : "step"](); state.onEngineTick(); } var nodeThreeObjectExtendAccessor = index3(state.nodeThreeObjectExtend); state.graphData.nodes.forEach(function(node) { var obj = node.__threeObj; if (!obj) return; var pos = isD3Sim ? node : state.layout.getNodePosition(node[state.nodeId]); var extendedObj = nodeThreeObjectExtendAccessor(node); if (!state.nodePositionUpdate || !state.nodePositionUpdate(extendedObj ? obj.children[0] : obj, { x: pos.x, y: pos.y, z: pos.z }, node) || extendedObj) { obj.position.x = pos.x; obj.position.y = pos.y || 0; obj.position.z = pos.z || 0; } }); var linkWidthAccessor = index3(state.linkWidth); var linkCurvatureAccessor = index3(state.linkCurvature); var linkCurveRotationAccessor = index3(state.linkCurveRotation); var linkThreeObjectExtendAccessor = index3(state.linkThreeObjectExtend); state.graphData.links.forEach(function(link) { var lineObj = link.__lineObj; if (!lineObj) return; var pos = isD3Sim ? link : state.layout.getLinkPosition(state.layout.graph.getLink(link.source, link.target).id); var start = pos[isD3Sim ? "source" : "from"]; var end = pos[isD3Sim ? "target" : "to"]; if (!start || !end || !start.hasOwnProperty("x") || !end.hasOwnProperty("x")) return; calcLinkCurve(link); var extendedObj = linkThreeObjectExtendAccessor(link); if (state.linkPositionUpdate && state.linkPositionUpdate( extendedObj ? lineObj.children[1] : lineObj, // pass child custom object if extending the default { start: { x: start.x, y: start.y, z: start.z }, end: { x: end.x, y: end.y, z: end.z } }, link ) && !extendedObj) { return; } var curveResolution = 30; var curve = link.__curve; var line = lineObj.children.length ? lineObj.children[0] : lineObj; if (line.type === "Line") { if (!curve) { var linePos = line.geometry.getAttribute("position"); if (!linePos || !linePos.array || linePos.array.length !== 6) { line.geometry[setAttributeFn]("position", linePos = new three$1.BufferAttribute(new Float32Array(2 * 3), 3)); } linePos.array[0] = start.x; linePos.array[1] = start.y || 0; linePos.array[2] = start.z || 0; linePos.array[3] = end.x; linePos.array[4] = end.y || 0; linePos.array[5] = end.z || 0; linePos.needsUpdate = true; } else { var curvePnts = curve.getPoints(curveResolution); if (line.geometry.getAttribute("position").array.length !== curvePnts.length * 3) { line.geometry[setAttributeFn]("position", new three$1.BufferAttribute(new Float32Array(curvePnts.length * 3), 3)); } line.geometry.setFromPoints(curvePnts); } line.geometry.computeBoundingSphere(); } else if (line.type === "Mesh") { if (!curve) { if (!line.geometry.type.match(/^Cylinder(Buffer)?Geometry$/)) { var linkWidth = Math.ceil(linkWidthAccessor(link) * 10) / 10; var r = linkWidth / 2; var geometry = new three$1.CylinderGeometry(r, r, 1, state.linkResolution, 1, false); geometry[applyMatrix4Fn](new three$1.Matrix4().makeTranslation(0, 1 / 2, 0)); geometry[applyMatrix4Fn](new three$1.Matrix4().makeRotationX(Math.PI / 2)); line.geometry.dispose(); line.geometry = geometry; } var vStart = new three$1.Vector3(start.x, start.y || 0, start.z || 0); var vEnd = new three$1.Vector3(end.x, end.y || 0, end.z || 0); var distance2 = vStart.distanceTo(vEnd); line.position.x = vStart.x; line.position.y = vStart.y; line.position.z = vStart.z; line.scale.z = distance2; line.parent.localToWorld(vEnd); line.lookAt(vEnd); } else { if (!line.geometry.type.match(/^Tube(Buffer)?Geometry$/)) { line.position.set(0, 0, 0); line.rotation.set(0, 0, 0); line.scale.set(1, 1, 1); } var _linkWidth = Math.ceil(linkWidthAccessor(link) * 10) / 10; var _r = _linkWidth / 2; var _geometry3 = new three$1.TubeGeometry(curve, curveResolution, _r, state.linkResolution, false); line.geometry.dispose(); line.geometry = _geometry3; } } }); function calcLinkCurve(link) { var pos = isD3Sim ? link : state.layout.getLinkPosition(state.layout.graph.getLink(link.source, link.target).id); var start = pos[isD3Sim ? "source" : "from"]; var end = pos[isD3Sim ? "target" : "to"]; if (!start || !end || !start.hasOwnProperty("x") || !end.hasOwnProperty("x")) return; var curvature = linkCurvatureAccessor(link); if (!curvature) { link.__curve = null; } else { var vStart = new three$1.Vector3(start.x, start.y || 0, start.z || 0); var vEnd = new three$1.Vector3(end.x, end.y || 0, end.z || 0); var l = vStart.distanceTo(vEnd); var curve; var curveRotation = linkCurveRotationAccessor(link); if (l > 0) { var dx = end.x - start.x; var dy = end.y - start.y || 0; var vLine = new three$1.Vector3().subVectors(vEnd, vStart); var cp = vLine.clone().multiplyScalar(curvature).cross(dx !== 0 || dy !== 0 ? new three$1.Vector3(0, 0, 1) : new three$1.Vector3(0, 1, 0)).applyAxisAngle(vLine.normalize(), curveRotation).add(new three$1.Vector3().addVectors(vStart, vEnd).divideScalar(2)); curve = new three$1.QuadraticBezierCurve3(vStart, cp, vEnd); } else { var d = curvature * 70; var endAngle = -curveRotation; var startAngle = endAngle + Math.PI / 2; curve = new three$1.CubicBezierCurve3(vStart, new three$1.Vector3(d * Math.cos(startAngle), d * Math.sin(startAngle), 0).add(vStart), new three$1.Vector3(d * Math.cos(endAngle), d * Math.sin(endAngle), 0).add(vStart), vEnd); } link.__curve = curve; } } } function updateArrows() { var arrowRelPosAccessor = index3(state.linkDirectionalArrowRelPos); var arrowLengthAccessor = index3(state.linkDirectionalArrowLength); var nodeValAccessor = index3(state.nodeVal); state.graphData.links.forEach(function(link) { var arrowObj = link.__arrowObj; if (!arrowObj) return; var pos = isD3Sim ? link : state.layout.getLinkPosition(state.layout.graph.getLink(link.source, link.target).id); var start = pos[isD3Sim ? "source" : "from"]; var end = pos[isD3Sim ? "target" : "to"]; if (!start || !end || !start.hasOwnProperty("x") || !end.hasOwnProperty("x")) return; var startR = Math.cbrt(Math.max(0, nodeValAccessor(start) || 1)) * state.nodeRelSize; var endR = Math.cbrt(Math.max(0, nodeValAccessor(end) || 1)) * state.nodeRelSize; var arrowLength = arrowLengthAccessor(link); var arrowRelPos = arrowRelPosAccessor(link); var getPosAlongLine = link.__curve ? function(t) { return link.__curve.getPoint(t); } : function(t) { var iplt = function iplt2(dim, start2, end2, t2) { return start2[dim] + (end2[dim] - start2[dim]) * t2 || 0; }; return { x: iplt("x", start, end, t), y: iplt("y", start, end, t), z: iplt("z", start, end, t) }; }; var lineLen = link.__curve ? link.__curve.getLength() : Math.sqrt(["x", "y", "z"].map(function(dim) { return Math.pow((end[dim] || 0) - (start[dim] || 0), 2); }).reduce(function(acc, v) { return acc + v; }, 0)); var posAlongLine = startR + arrowLength + (lineLen - startR - endR - arrowLength) * arrowRelPos; var arrowHead = getPosAlongLine(posAlongLine / lineLen); var arrowTail = getPosAlongLine((posAlongLine - arrowLength) / lineLen); ["x", "y", "z"].forEach(function(dim) { return arrowObj.position[dim] = arrowTail[dim]; }); var headVec = _construct(three$1.Vector3, _toConsumableArray3(["x", "y", "z"].map(function(c2) { return arrowHead[c2]; }))); arrowObj.parent.localToWorld(headVec); arrowObj.lookAt(headVec); }); } function updatePhotons() { var particleSpeedAccessor = index3(state.linkDirectionalParticleSpeed); state.graphData.links.forEach(function(link) { var cyclePhotons = link.__photonsObj && link.__photonsObj.children; var singleHopPhotons = link.__singleHopPhotonsObj && link.__singleHopPhotonsObj.children; if ((!singleHopPhotons || !singleHopPhotons.length) && (!cyclePhotons || !cyclePhotons.length)) return; var pos = isD3Sim ? link : state.layout.getLinkPosition(state.layout.graph.getLink(link.source, link.target).id); var start = pos[isD3Sim ? "source" : "from"]; var end = pos[isD3Sim ? "target" : "to"]; if (!start || !end || !start.hasOwnProperty("x") || !end.hasOwnProperty("x")) return; var particleSpeed = particleSpeedAccessor(link); var getPhotonPos = link.__curve ? function(t) { return link.__curve.getPoint(t); } : function(t) { var iplt = function iplt2(dim, start2, end2, t2) { return start2[dim] + (end2[dim] - start2[dim]) * t2 || 0; }; return { x: iplt("x", start, end, t), y: iplt("y", start, end, t), z: iplt("z", start, end, t) }; }; var photons = [].concat(_toConsumableArray3(cyclePhotons || []), _toConsumableArray3(singleHopPhotons || [])); photons.forEach(function(photon, idx) { var singleHop = photon.parent.__linkThreeObjType === "singleHopPhotons"; if (!photon.hasOwnProperty("__progressRatio")) { photon.__progressRatio = singleHop ? 0 : idx / cyclePhotons.length; } photon.__progressRatio += particleSpeed; if (photon.__progressRatio >= 1) { if (!singleHop) { photon.__progressRatio = photon.__progressRatio % 1; } else { photon.parent.remove(photon); emptyObject(photon); return; } } var photonPosRatio = photon.__progressRatio; var pos2 = getPhotonPos(photonPosRatio); ["x", "y", "z"].forEach(function(dim) { return photon.position[dim] = pos2[dim]; }); }); }); } }, emitParticle: function emitParticle(state, link) { if (link && state.graphData.links.includes(link)) { if (!link.__singleHopPhotonsObj) { var obj = new three$1.Group(); obj.__linkThreeObjType = "singleHopPhotons"; link.__singleHopPhotonsObj = obj; state.graphScene.add(obj); } var particleWidthAccessor = index3(state.linkDirectionalParticleWidth); var photonR = Math.ceil(particleWidthAccessor(link) * 10) / 10 / 2; var numSegments = state.linkDirectionalParticleResolution; var particleGeometry = new three$1.SphereGeometry(photonR, numSegments, numSegments); var linkColorAccessor = index3(state.linkColor); var particleColorAccessor = index3(state.linkDirectionalParticleColor); var photonColor = particleColorAccessor(link) || linkColorAccessor(link) || "#f0f0f0"; var materialColor2 = new three$1.Color(colorStr2Hex(photonColor)); var opacity = state.linkOpacity * 3; var particleMaterial = new three$1.MeshLambertMaterial({ color: materialColor2, transparent: true, opacity }); link.__singleHopPhotonsObj.add(new three$1.Mesh(particleGeometry, particleMaterial)); } return this; }, getGraphBbox: function getGraphBbox(state) { var nodeFilter = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : function() { return true; }; if (!state.initialised) return null; var bboxes = function getBboxes(obj) { var bboxes2 = []; if (obj.geometry) { obj.geometry.computeBoundingBox(); var box = new three$1.Box3(); box.copy(obj.geometry.boundingBox).applyMatrix4(obj.matrixWorld); bboxes2.push(box); } return bboxes2.concat.apply(bboxes2, _toConsumableArray3((obj.children || []).filter( function(obj2) { return !obj2.hasOwnProperty("__graphObjType") || obj2.__graphObjType === "node" && nodeFilter(obj2.__data); } // exclude filtered out nodes ).map(getBboxes))); }(state.graphScene); if (!bboxes.length) return null; return Object.assign.apply(Object, _toConsumableArray3(["x", "y", "z"].map(function(c2) { return _defineProperty2({}, c2, [min(bboxes, function(bb) { return bb.min[c2]; }), max(bboxes, function(bb) { return bb.max[c2]; })]); }))); } }, stateInit: function stateInit() { return { d3ForceLayout: simulation_default().force("link", link_default()).force("charge", manyBody_default()).force("center", center_default()).force("dagRadial", null).stop(), engineRunning: false }; }, init: function init(threeObj, state) { state.graphScene = threeObj; }, update: function update(state, changedProps) { var hasAnyPropChanged = function hasAnyPropChanged2(propList) { return propList.some(function(p) { return changedProps.hasOwnProperty(p); }); }; state.engineRunning = false; state.onUpdate(); if (state.nodeAutoColorBy !== null && hasAnyPropChanged(["nodeAutoColorBy", "graphData", "nodeColor"])) { autoColorObjects(state.graphData.nodes, index3(state.nodeAutoColorBy), state.nodeColor); } if (state.linkAutoColorBy !== null && hasAnyPropChanged(["linkAutoColorBy", "graphData", "linkColor"])) { autoColorObjects(state.graphData.links, index3(state.linkAutoColorBy), state.linkColor); } if (state._flushObjects || hasAnyPropChanged(["graphData", "nodeThreeObject", "nodeThreeObjectExtend", "nodeVal", "nodeColor", "nodeVisibility", "nodeRelSize", "nodeResolution", "nodeOpacity"])) { var customObjectAccessor = index3(state.nodeThreeObject); var customObjectExtendAccessor = index3(state.nodeThreeObjectExtend); var valAccessor = index3(state.nodeVal); var colorAccessor = index3(state.nodeColor); var visibilityAccessor = index3(state.nodeVisibility); var sphereGeometries = {}; var sphereMaterials = {}; threeDigest(state.graphData.nodes.filter(visibilityAccessor), state.graphScene, { purge: state._flushObjects || hasAnyPropChanged([ // recreate objects if any of these props have changed "nodeThreeObject", "nodeThreeObjectExtend" ]), objFilter: function objFilter(obj) { return obj.__graphObjType === "node"; }, createObj: function createObj(node) { var customObj = customObjectAccessor(node); var extendObj = customObjectExtendAccessor(node); if (customObj && state.nodeThreeObject === customObj) { customObj = customObj.clone(); } var obj; if (customObj && !extendObj) { obj = customObj; } else { obj = new three$1.Mesh(); obj.__graphDefaultObj = true; if (customObj && extendObj) { obj.add(customObj); } } obj.__graphObjType = "node"; return obj; }, updateObj: function updateObj(obj, node) { if (obj.__graphDefaultObj) { var val = valAccessor(node) || 1; var radius = Math.cbrt(val) * state.nodeRelSize; var numSegments = state.nodeResolution; if (!obj.geometry.type.match(/^Sphere(Buffer)?Geometry$/) || obj.geometry.parameters.radius !== radius || obj.geometry.parameters.widthSegments !== numSegments) { if (!sphereGeometries.hasOwnProperty(val)) { sphereGeometries[val] = new three$1.SphereGeometry(radius, numSegments, numSegments); } obj.geometry.dispose(); obj.geometry = sphereGeometries[val]; } var color2 = colorAccessor(node); var materialColor2 = new three$1.Color(colorStr2Hex(color2 || "#ffffaa")); var opacity = state.nodeOpacity * colorAlpha(color2); if (obj.material.type !== "MeshLambertMaterial" || !obj.material.color.equals(materialColor2) || obj.material.opacity !== opacity) { if (!sphereMaterials.hasOwnProperty(color2)) { sphereMaterials[color2] = new three$1.MeshLambertMaterial({ color: materialColor2, transparent: true, opacity }); } obj.material.dispose(); obj.material = sphereMaterials[color2]; } } } }); } if (state._flushObjects || hasAnyPropChanged(["graphData", "linkThreeObject", "linkThreeObjectExtend", "linkMaterial", "linkColor", "linkWidth", "linkVisibility", "linkResolution", "linkOpacity", "linkDirectionalArrowLength", "linkDirectionalArrowColor", "linkDirectionalArrowResolution", "linkDirectionalParticles", "linkDirectionalParticleWidth", "linkDirectionalParticleColor", "linkDirectionalParticleResolution"])) { var _customObjectAccessor = index3(state.linkThreeObject); var _customObjectExtendAccessor = index3(state.linkThreeObjectExtend); var customMaterialAccessor = index3(state.linkMaterial); var _visibilityAccessor = index3(state.linkVisibility); var _colorAccessor = index3(state.linkColor); var widthAccessor = index3(state.linkWidth); var cylinderGeometries = {}; var lambertLineMaterials = {}; var basicLineMaterials = {}; var visibleLinks = state.graphData.links.filter(_visibilityAccessor); threeDigest(visibleLinks, state.graphScene, { objBindAttr: "__lineObj", purge: state._flushObjects || hasAnyPropChanged([ // recreate objects if any of these props have changed "linkThreeObject", "linkThreeObjectExtend", "linkWidth" ]), objFilter: function objFilter(obj) { return obj.__graphObjType === "link"; }, exitObj: function exitObj(obj) { var singlePhotonsObj = obj.__data && obj.__data.__singleHopPhotonsObj; if (singlePhotonsObj) { singlePhotonsObj.parent.remove(singlePhotonsObj); emptyObject(singlePhotonsObj); delete obj.__data.__singleHopPhotonsObj; } }, createObj: function createObj(link) { var customObj = _customObjectAccessor(link); var extendObj = _customObjectExtendAccessor(link); if (customObj && state.linkThreeObject === customObj) { customObj = customObj.clone(); } var defaultObj; if (!customObj || extendObj) { var useCylinder = !!widthAccessor(link); if (useCylinder) { defaultObj = new three$1.Mesh(); } else { var lineGeometry = new three$1.BufferGeometry(); lineGeometry[setAttributeFn]("position", new three$1.BufferAttribute(new Float32Array(2 * 3), 3)); defaultObj = new three$1.Line(lineGeometry); } } var obj; if (!customObj) { obj = defaultObj; obj.__graphDefaultObj = true; } else { if (!extendObj) { obj = customObj; } else { obj = new three$1.Group(); obj.__graphDefaultObj = true; obj.add(defaultObj); obj.add(customObj); } } obj.renderOrder = 10; obj.__graphObjType = "link"; return obj; }, updateObj: function updateObj(updObj, link) { if (updObj.__graphDefaultObj) { var obj = updObj.children.length ? updObj.children[0] : updObj; var linkWidth = Math.ceil(widthAccessor(link) * 10) / 10; var useCylinder = !!linkWidth; if (useCylinder) { var r = linkWidth / 2; var numSegments = state.linkResolution; if (!obj.geometry.type.match(/^Cylinder(Buffer)?Geometry$/) || obj.geometry.parameters.radiusTop !== r || obj.geometry.parameters.radialSegments !== numSegments) { if (!cylinderGeometries.hasOwnProperty(linkWidth)) { var geometry = new three$1.CylinderGeometry(r, r, 1, numSegments, 1, false); geometry[applyMatrix4Fn](new three$1.Matrix4().makeTranslation(0, 1 / 2, 0)); geometry[applyMatrix4Fn](new three$1.Matrix4().makeRotationX(Math.PI / 2)); cylinderGeometries[linkWidth] = geometry; } obj.geometry.dispose(); obj.geometry = cylinderGeometries[linkWidth]; } } var customMaterial = customMaterialAccessor(link); if (customMaterial) { obj.material = customMaterial; } else { var color2 = _colorAccessor(link); var materialColor2 = new three$1.Color(colorStr2Hex(color2 || "#f0f0f0")); var opacity = state.linkOpacity * colorAlpha(color2); var materialType = useCylinder ? "MeshLambertMaterial" : "LineBasicMaterial"; if (obj.material.type !== materialType || !obj.material.color.equals(materialColor2) || obj.material.opacity !== opacity) { var lineMaterials = useCylinder ? lambertLineMaterials : basicLineMaterials; if (!lineMaterials.hasOwnProperty(color2)) { lineMaterials[color2] = new three$1[materialType]({ color: materialColor2, transparent: opacity < 1, opacity, depthWrite: opacity >= 1 // Prevent transparency issues }); } obj.material.dispose(); obj.material = lineMaterials[color2]; } } } } }); if (state.linkDirectionalArrowLength || changedProps.hasOwnProperty("linkDirectionalArrowLength")) { var arrowLengthAccessor = index3(state.linkDirectionalArrowLength); var arrowColorAccessor = index3(state.linkDirectionalArrowColor); threeDigest(visibleLinks.filter(arrowLengthAccessor), state.graphScene, { objBindAttr: "__arrowObj", objFilter: function objFilter(obj) { return obj.__linkThreeObjType === "arrow"; }, createObj: function createObj() { var obj = new three$1.Mesh(void 0, new three$1.MeshLambertMaterial({ transparent: true })); obj.__linkThreeObjType = "arrow"; return obj; }, updateObj: function updateObj(obj, link) { var arrowLength = arrowLengthAccessor(link); var numSegments = state.linkDirectionalArrowResolution; if (!obj.geometry.type.match(/^Cone(Buffer)?Geometry$/) || obj.geometry.parameters.height !== arrowLength || obj.geometry.parameters.radialSegments !== numSegments) { var coneGeometry = new three$1.ConeGeometry(arrowLength * 0.25, arrowLength, numSegments); coneGeometry.translate(0, arrowLength / 2, 0); coneGeometry.rotateX(Math.PI / 2); obj.geometry.dispose(); obj.geometry = coneGeometry; } var arrowColor = arrowColorAccessor(link) || _colorAccessor(link) || "#f0f0f0"; obj.material.color = new three$1.Color(colorStr2Hex(arrowColor)); obj.material.opacity = state.linkOpacity * 3 * colorAlpha(arrowColor); } }); } if (state.linkDirectionalParticles || changedProps.hasOwnProperty("linkDirectionalParticles")) { var particlesAccessor = index3(state.linkDirectionalParticles); var particleWidthAccessor = index3(state.linkDirectionalParticleWidth); var particleColorAccessor = index3(state.linkDirectionalParticleColor); var particleMaterials = {}; var particleGeometries = {}; threeDigest(visibleLinks.filter(particlesAccessor), state.graphScene, { objBindAttr: "__photonsObj", objFilter: function objFilter(obj) { return obj.__linkThreeObjType === "photons"; }, createObj: function createObj() { var obj = new three$1.Group(); obj.__linkThreeObjType = "photons"; return obj; }, updateObj: function updateObj(obj, link) { var numPhotons = Math.round(Math.abs(particlesAccessor(link))); var curPhoton = !!obj.children.length && obj.children[0]; var photonR = Math.ceil(particleWidthAccessor(link) * 10) / 10 / 2; var numSegments = state.linkDirectionalParticleResolution; var particleGeometry; if (curPhoton && curPhoton.geometry.parameters.radius === photonR && curPhoton.geometry.parameters.widthSegments === numSegments) { particleGeometry = curPhoton.geometry; } else { if (!particleGeometries.hasOwnProperty(photonR)) { particleGeometries[photonR] = new three$1.SphereGeometry(photonR, numSegments, numSegments); } particleGeometry = particleGeometries[photonR]; curPhoton && curPhoton.geometry.dispose(); } var photonColor = particleColorAccessor(link) || _colorAccessor(link) || "#f0f0f0"; var materialColor2 = new three$1.Color(colorStr2Hex(photonColor)); var opacity = state.linkOpacity * 3; var particleMaterial; if (curPhoton && curPhoton.material.color.equals(materialColor2) && curPhoton.material.opacity === opacity) { particleMaterial = curPhoton.material; } else { if (!particleMaterials.hasOwnProperty(photonColor)) { particleMaterials[photonColor] = new three$1.MeshLambertMaterial({ color: materialColor2, transparent: true, opacity }); } particleMaterial = particleMaterials[photonColor]; curPhoton && curPhoton.material.dispose(); } threeDigest(_toConsumableArray3(new Array(numPhotons)).map(function(_, idx) { return { idx }; }), obj, { idAccessor: function idAccessor(d) { return d.idx; }, createObj: function createObj() { return new three$1.Mesh(particleGeometry, particleMaterial); }, updateObj: function updateObj2(obj2) { obj2.geometry = particleGeometry; obj2.material = particleMaterial; } }); } }); } } state._flushObjects = false; if (hasAnyPropChanged(["graphData", "nodeId", "linkSource", "linkTarget", "numDimensions", "forceEngine", "dagMode", "dagNodeFilter", "dagLevelDistance"])) { state.engineRunning = false; state.graphData.links.forEach(function(link) { link.source = link[state.linkSource]; link.target = link[state.linkTarget]; }); var isD3Sim = state.forceEngine !== "ngraph"; var layout; if (isD3Sim) { (layout = state.d3ForceLayout).stop().alpha(1).numDimensions(state.numDimensions).nodes(state.graphData.nodes); var linkForce = state.d3ForceLayout.force("link"); if (linkForce) { linkForce.id(function(d) { return d[state.nodeId]; }).links(state.graphData.links); } var nodeDepths = state.dagMode && getDagDepths(state.graphData, function(node) { return node[state.nodeId]; }, { nodeFilter: state.dagNodeFilter, onLoopError: state.onDagError || void 0 }); var maxDepth = Math.max.apply(Math, _toConsumableArray3(Object.values(nodeDepths || []))); var dagLevelDistance = state.dagLevelDistance || state.graphData.nodes.length / (maxDepth || 1) * DAG_LEVEL_NODE_RATIO * (["radialin", "radialout"].indexOf(state.dagMode) !== -1 ? 0.7 : 1); if (["lr", "rl", "td", "bu", "zin", "zout"].includes(changedProps.dagMode)) { var resetProp = ["lr", "rl"].includes(changedProps.dagMode) ? "fx" : ["td", "bu"].includes(changedProps.dagMode) ? "fy" : "fz"; state.graphData.nodes.filter(state.dagNodeFilter).forEach(function(node) { return delete node[resetProp]; }); } if (["lr", "rl", "td", "bu", "zin", "zout"].includes(state.dagMode)) { var invert = ["rl", "td", "zout"].includes(state.dagMode); var fixFn = function fixFn2(node) { return (nodeDepths[node[state.nodeId]] - maxDepth / 2) * dagLevelDistance * (invert ? -1 : 1); }; var _resetProp = ["lr", "rl"].includes(state.dagMode) ? "fx" : ["td", "bu"].includes(state.dagMode) ? "fy" : "fz"; state.graphData.nodes.filter(state.dagNodeFilter).forEach(function(node) { return node[_resetProp] = fixFn(node); }); } state.d3ForceLayout.force("dagRadial", ["radialin", "radialout"].indexOf(state.dagMode) !== -1 ? radial_default(function(node) { var nodeDepth = nodeDepths[node[state.nodeId]] || -1; return (state.dagMode === "radialin" ? maxDepth - nodeDepth : nodeDepth) * dagLevelDistance; }).strength(function(node) { return state.dagNodeFilter(node) ? 1 : 0; }) : null); } else { var _graph = ngraph.graph(); state.graphData.nodes.forEach(function(node) { _graph.addNode(node[state.nodeId]); }); state.graphData.links.forEach(function(link) { _graph.addLink(link.source, link.target); }); layout = ngraph.forcelayout(_graph, _objectSpread22({ dimensions: state.numDimensions }, state.ngraphPhysics)); layout.graph = _graph; } for (var i = 0; i < state.warmupTicks && !(isD3Sim && state.d3AlphaMin > 0 && state.d3ForceLayout.alpha() < state.d3AlphaMin); i++) { layout[isD3Sim ? "tick" : "step"](); } state.layout = layout; this.resetCountdown(); } state.engineRunning = true; state.onFinishUpdate(); } }); function fromKapsule(kapsule) { var baseClass = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : Object; var initKapsuleWithSelf = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : false; var FromKapsule = /* @__PURE__ */ function(_baseClass) { function FromKapsule2() { var _this; _classCallCheck2(this, FromKapsule2); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _callSuper(this, FromKapsule2, [].concat(args)); _this.__kapsuleInstance = kapsule().apply(void 0, [].concat(_toConsumableArray3(initKapsuleWithSelf ? [_this] : []), args)); return _this; } _inherits(FromKapsule2, _baseClass); return _createClass2(FromKapsule2); }(baseClass); Object.keys(kapsule()).forEach(function(m2) { return FromKapsule.prototype[m2] = function() { var _this$__kapsuleInstan; var returnVal = (_this$__kapsuleInstan = this.__kapsuleInstance)[m2].apply(_this$__kapsuleInstan, arguments); return returnVal === this.__kapsuleInstance ? this : returnVal; }; }); return FromKapsule; } var three = window.THREE ? window.THREE : { Group }; var threeForcegraph = fromKapsule(ForceGraph, three.Group, true); // ../../node_modules/three/build/three.webgpu.js var REVISION2 = "170"; var CullFaceNone2 = 0; var CullFaceBack2 = 1; var CullFaceFront2 = 2; var PCFShadowMap$1 = 1; var VSMShadowMap2 = 3; var FrontSide2 = 0; var BackSide2 = 1; var DoubleSide2 = 2; var NoBlending2 = 0; var NormalBlending2 = 1; var AdditiveBlending2 = 2; var SubtractiveBlending2 = 3; var MultiplyBlending2 = 4; var CustomBlending2 = 5; var AddEquation2 = 100; var SubtractEquation2 = 101; var ReverseSubtractEquation2 = 102; var MinEquation2 = 103; var MaxEquation2 = 104; var ZeroFactor2 = 200; var OneFactor2 = 201; var SrcColorFactor2 = 202; var OneMinusSrcColorFactor2 = 203; var SrcAlphaFactor2 = 204; var OneMinusSrcAlphaFactor2 = 205; var DstAlphaFactor2 = 206; var OneMinusDstAlphaFactor2 = 207; var DstColorFactor2 = 208; var OneMinusDstColorFactor2 = 209; var SrcAlphaSaturateFactor2 = 210; var NeverDepth2 = 0; var AlwaysDepth2 = 1; var LessDepth2 = 2; var LessEqualDepth2 = 3; var EqualDepth2 = 4; var GreaterEqualDepth2 = 5; var GreaterDepth2 = 6; var NotEqualDepth2 = 7; var MultiplyOperation2 = 0; var MixOperation2 = 1; var AddOperation2 = 2; var NoToneMapping2 = 0; var LinearToneMapping2 = 1; var ReinhardToneMapping2 = 2; var CineonToneMapping2 = 3; var ACESFilmicToneMapping2 = 4; var AgXToneMapping2 = 6; var NeutralToneMapping2 = 7; var UVMapping2 = 300; var CubeReflectionMapping2 = 301; var CubeRefractionMapping2 = 302; var EquirectangularReflectionMapping2 = 303; var EquirectangularRefractionMapping2 = 304; var CubeUVReflectionMapping2 = 306; var RepeatWrapping2 = 1e3; var ClampToEdgeWrapping2 = 1001; var MirroredRepeatWrapping2 = 1002; var NearestFilter2 = 1003; var NearestMipmapNearestFilter2 = 1004; var NearestMipmapLinearFilter2 = 1005; var LinearFilter2 = 1006; var LinearMipmapNearestFilter2 = 1007; var LinearMipmapLinearFilter2 = 1008; var UnsignedByteType2 = 1009; var ByteType2 = 1010; var ShortType2 = 1011; var UnsignedShortType2 = 1012; var IntType2 = 1013; var UnsignedIntType2 = 1014; var FloatType2 = 1015; var HalfFloatType2 = 1016; var UnsignedShort4444Type2 = 1017; var UnsignedShort5551Type2 = 1018; var UnsignedInt248Type2 = 1020; var UnsignedInt5999Type2 = 35902; var AlphaFormat2 = 1021; var RGBFormat2 = 1022; var RGBAFormat2 = 1023; var LuminanceFormat2 = 1024; var LuminanceAlphaFormat2 = 1025; var DepthFormat2 = 1026; var DepthStencilFormat2 = 1027; var RedFormat2 = 1028; var RedIntegerFormat2 = 1029; var RGFormat2 = 1030; var RGIntegerFormat2 = 1031; var RGBIntegerFormat = 1032; var RGBAIntegerFormat2 = 1033; var RGB_S3TC_DXT1_Format2 = 33776; var RGBA_S3TC_DXT1_Format2 = 33777; var RGBA_S3TC_DXT3_Format2 = 33778; var RGBA_S3TC_DXT5_Format2 = 33779; var RGB_PVRTC_4BPPV1_Format2 = 35840; var RGB_PVRTC_2BPPV1_Format2 = 35841; var RGBA_PVRTC_4BPPV1_Format2 = 35842; var RGBA_PVRTC_2BPPV1_Format2 = 35843; var RGB_ETC1_Format2 = 36196; var RGB_ETC2_Format2 = 37492; var RGBA_ETC2_EAC_Format2 = 37496; var RGBA_ASTC_4x4_Format2 = 37808; var RGBA_ASTC_5x4_Format2 = 37809; var RGBA_ASTC_5x5_Format2 = 37810; var RGBA_ASTC_6x5_Format2 = 37811; var RGBA_ASTC_6x6_Format2 = 37812; var RGBA_ASTC_8x5_Format2 = 37813; var RGBA_ASTC_8x6_Format2 = 37814; var RGBA_ASTC_8x8_Format2 = 37815; var RGBA_ASTC_10x5_Format2 = 37816; var RGBA_ASTC_10x6_Format2 = 37817; var RGBA_ASTC_10x8_Format2 = 37818; var RGBA_ASTC_10x10_Format2 = 37819; var RGBA_ASTC_12x10_Format2 = 37820; var RGBA_ASTC_12x12_Format2 = 37821; var RGBA_BPTC_Format2 = 36492; var RED_RGTC1_Format2 = 36283; var SIGNED_RED_RGTC1_Format2 = 36284; var RED_GREEN_RGTC2_Format2 = 36285; var SIGNED_RED_GREEN_RGTC2_Format2 = 36286; var InterpolateDiscrete2 = 2300; var InterpolateLinear2 = 2301; var InterpolateSmooth2 = 2302; var ZeroCurvatureEnding2 = 2400; var ZeroSlopeEnding2 = 2401; var WrapAroundEnding2 = 2402; var TangentSpaceNormalMap2 = 0; var ObjectSpaceNormalMap2 = 1; var NoColorSpace2 = ""; var SRGBColorSpace2 = "srgb"; var LinearSRGBColorSpace2 = "srgb-linear"; var LinearTransfer2 = "linear"; var SRGBTransfer2 = "srgb"; var ZeroStencilOp = 0; var KeepStencilOp2 = 7680; var ReplaceStencilOp = 7681; var IncrementStencilOp = 7682; var DecrementStencilOp = 7683; var IncrementWrapStencilOp = 34055; var DecrementWrapStencilOp = 34056; var InvertStencilOp = 5386; var NeverStencilFunc = 512; var LessStencilFunc = 513; var EqualStencilFunc = 514; var LessEqualStencilFunc = 515; var GreaterStencilFunc = 516; var NotEqualStencilFunc = 517; var GreaterEqualStencilFunc = 518; var AlwaysStencilFunc2 = 519; var NeverCompare2 = 512; var LessCompare2 = 513; var EqualCompare2 = 514; var LessEqualCompare2 = 515; var GreaterCompare2 = 516; var NotEqualCompare2 = 517; var GreaterEqualCompare2 = 518; var AlwaysCompare2 = 519; var StaticDrawUsage2 = 35044; var DynamicDrawUsage = 35048; var WebGLCoordinateSystem2 = 2e3; var WebGPUCoordinateSystem2 = 2001; var EventDispatcher2 = class { addEventListener(type, listener) { if (this._listeners === void 0) this._listeners = {}; const listeners = this._listeners; if (listeners[type] === void 0) { listeners[type] = []; } if (listeners[type].indexOf(listener) === -1) { listeners[type].push(listener); } } hasEventListener(type, listener) { if (this._listeners === void 0) return false; const listeners = this._listeners; return listeners[type] !== void 0 && listeners[type].indexOf(listener) !== -1; } removeEventListener(type, listener) { if (this._listeners === void 0) return; const listeners = this._listeners; const listenerArray = listeners[type]; if (listenerArray !== void 0) { const index5 = listenerArray.indexOf(listener); if (index5 !== -1) { listenerArray.splice(index5, 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 _lut2 = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"]; var _seed2 = 1234567; var DEG2RAD2 = Math.PI / 180; var RAD2DEG2 = 180 / Math.PI; function generateUUID2() { 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 = _lut2[d0 & 255] + _lut2[d0 >> 8 & 255] + _lut2[d0 >> 16 & 255] + _lut2[d0 >> 24 & 255] + "-" + _lut2[d1 & 255] + _lut2[d1 >> 8 & 255] + "-" + _lut2[d1 >> 16 & 15 | 64] + _lut2[d1 >> 24 & 255] + "-" + _lut2[d2 & 63 | 128] + _lut2[d2 >> 8 & 255] + "-" + _lut2[d2 >> 16 & 255] + _lut2[d2 >> 24 & 255] + _lut2[d3 & 255] + _lut2[d3 >> 8 & 255] + _lut2[d3 >> 16 & 255] + _lut2[d3 >> 24 & 255]; return uuid.toLowerCase(); } function clamp$1(value, min2, max2) { return Math.max(min2, Math.min(max2, value)); } function euclideanModulo2(n, m2) { return (n % m2 + m2) % m2; } function mapLinear2(x2, a1, a2, b1, b2) { return b1 + (x2 - a1) * (b2 - b1) / (a2 - a1); } function inverseLerp2(x2, y2, value) { if (x2 !== y2) { return (value - x2) / (y2 - x2); } else { return 0; } } function lerp2(x2, y2, t) { return (1 - t) * x2 + t * y2; } function damp2(x2, y2, lambda, dt) { return lerp2(x2, y2, 1 - Math.exp(-lambda * dt)); } function pingpong2(x2, length2 = 1) { return length2 - Math.abs(euclideanModulo2(x2, length2 * 2) - length2); } function smoothstep$1(x2, min2, max2) { if (x2 <= min2) return 0; if (x2 >= max2) return 1; x2 = (x2 - min2) / (max2 - min2); return x2 * x2 * (3 - 2 * x2); } function smootherstep2(x2, min2, max2) { if (x2 <= min2) return 0; if (x2 >= max2) return 1; x2 = (x2 - min2) / (max2 - min2); return x2 * x2 * x2 * (x2 * (x2 * 6 - 15) + 10); } function randInt2(low, high) { return low + Math.floor(Math.random() * (high - low + 1)); } function randFloat2(low, high) { return low + Math.random() * (high - low); } function randFloatSpread2(range) { return range * (0.5 - Math.random()); } function seededRandom2(s) { if (s !== void 0) _seed2 = s; let t = _seed2 += 1831565813; t = Math.imul(t ^ t >>> 15, t | 1); t ^= t + Math.imul(t ^ t >>> 7, t | 61); return ((t ^ t >>> 14) >>> 0) / 4294967296; } function degToRad2(degrees2) { return degrees2 * DEG2RAD2; } function radToDeg2(radians2) { return radians2 * RAD2DEG2; } function isPowerOfTwo2(value) { return (value & value - 1) === 0 && value !== 0; } function ceilPowerOfTwo2(value) { return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2)); } function floorPowerOfTwo2(value) { return Math.pow(2, Math.floor(Math.log(value) / Math.LN2)); } function setQuaternionFromProperEuler2(q, a2, b, c2, order) { const cos2 = Math.cos; const sin2 = Math.sin; const c22 = cos2(b / 2); const s2 = sin2(b / 2); const c13 = cos2((a2 + c2) / 2); const s13 = sin2((a2 + c2) / 2); const c1_3 = cos2((a2 - c2) / 2); const s1_3 = sin2((a2 - c2) / 2); const c3_1 = cos2((c2 - a2) / 2); const s3_1 = sin2((c2 - a2) / 2); switch (order) { case "XYX": q.set(c22 * s13, s2 * c1_3, s2 * s1_3, c22 * c13); break; case "YZY": q.set(s2 * s1_3, c22 * s13, s2 * c1_3, c22 * c13); break; case "ZXZ": q.set(s2 * c1_3, s2 * s1_3, c22 * s13, c22 * c13); break; case "XZX": q.set(c22 * s13, s2 * s3_1, s2 * c3_1, c22 * c13); break; case "YXY": q.set(s2 * c3_1, c22 * s13, s2 * s3_1, c22 * c13); break; case "ZYZ": q.set(s2 * s3_1, s2 * c3_1, c22 * s13, c22 * c13); break; default: console.warn("THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: " + order); } } function denormalize2(value, array) { switch (array.constructor) { case Float32Array: return value; case Uint32Array: return value / 4294967295; case Uint16Array: return value / 65535; case Uint8Array: return value / 255; case Int32Array: return Math.max(value / 2147483647, -1); case Int16Array: return Math.max(value / 32767, -1); case Int8Array: return Math.max(value / 127, -1); default: throw new Error("Invalid component type."); } } function normalize$1(value, array) { switch (array.constructor) { case Float32Array: return value; case Uint32Array: return Math.round(value * 4294967295); case Uint16Array: return Math.round(value * 65535); case Uint8Array: return Math.round(value * 255); case Int32Array: return Math.round(value * 2147483647); case Int16Array: return Math.round(value * 32767); case Int8Array: return Math.round(value * 127); default: throw new Error("Invalid component type."); } } var MathUtils2 = { DEG2RAD: DEG2RAD2, RAD2DEG: RAD2DEG2, generateUUID: generateUUID2, clamp: clamp$1, euclideanModulo: euclideanModulo2, mapLinear: mapLinear2, inverseLerp: inverseLerp2, lerp: lerp2, damp: damp2, pingpong: pingpong2, smoothstep: smoothstep$1, smootherstep: smootherstep2, randInt: randInt2, randFloat: randFloat2, randFloatSpread: randFloatSpread2, seededRandom: seededRandom2, degToRad: degToRad2, radToDeg: radToDeg2, isPowerOfTwo: isPowerOfTwo2, ceilPowerOfTwo: ceilPowerOfTwo2, floorPowerOfTwo: floorPowerOfTwo2, setQuaternionFromProperEuler: setQuaternionFromProperEuler2, normalize: normalize$1, denormalize: denormalize2 }; var Vector22 = class _Vector2 { constructor(x2 = 0, y2 = 0) { _Vector2.prototype.isVector2 = true; this.x = x2; this.y = y2; } get width() { return this.x; } set width(value) { this.x = value; } get height() { return this.y; } set height(value) { this.y = value; } set(x2, y2) { this.x = x2; this.y = y2; return this; } setScalar(scalar) { this.x = scalar; this.y = scalar; return this; } setX(x2) { this.x = x2; return this; } setY(y2) { this.y = y2; return this; } setComponent(index5, value) { switch (index5) { case 0: this.x = value; break; case 1: this.y = value; break; default: throw new Error("index is out of range: " + index5); } return this; } getComponent(index5) { switch (index5) { case 0: return this.x; case 1: return this.y; default: throw new Error("index is out of range: " + index5); } } clone() { return new this.constructor(this.x, this.y); } copy(v) { this.x = v.x; this.y = v.y; return this; } add(v) { this.x += v.x; this.y += v.y; return this; } addScalar(s) { this.x += s; this.y += s; return this; } addVectors(a2, b) { this.x = a2.x + b.x; this.y = a2.y + b.y; return this; } addScaledVector(v, s) { this.x += v.x * s; this.y += v.y * s; return this; } sub(v) { this.x -= v.x; this.y -= v.y; return this; } subScalar(s) { this.x -= s; this.y -= s; return this; } subVectors(a2, b) { this.x = a2.x - b.x; this.y = a2.y - b.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(m2) { const x2 = this.x, y2 = this.y; const e = m2.elements; this.x = e[0] * x2 + e[3] * y2 + e[6]; this.y = e[1] * x2 + e[4] * y2 + 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(min2, max2) { this.x = Math.max(min2.x, Math.min(max2.x, this.x)); this.y = Math.max(min2.y, Math.min(max2.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(min2, max2) { const length2 = this.length(); return this.divideScalar(length2 || 1).multiplyScalar(Math.max(min2, Math.min(max2, length2))); } 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 = Math.trunc(this.x); this.y = Math.trunc(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; } 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$1(theta, -1, 1)); } 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(length2) { return this.normalize().multiplyScalar(length2); } lerp(v, alpha) { this.x += (v.x - this.x) * alpha; this.y += (v.y - this.y) * alpha; return this; } lerpVectors(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.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(attribute2, index5) { this.x = attribute2.getX(index5); this.y = attribute2.getY(index5); return this; } rotateAround(center, angle) { const c2 = Math.cos(angle), s = Math.sin(angle); const x2 = this.x - center.x; const y2 = this.y - center.y; this.x = x2 * c2 - y2 * s + center.x; this.y = x2 * s + y2 * c2 + center.y; return this; } random() { this.x = Math.random(); this.y = Math.random(); return this; } *[Symbol.iterator]() { yield this.x; yield this.y; } }; var Matrix32 = class _Matrix3 { constructor(n11, n12, n13, n21, n22, n23, n31, n32, n33) { _Matrix3.prototype.isMatrix3 = true; this.elements = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; if (n11 !== void 0) { this.set(n11, n12, n13, n21, n22, n23, n31, n32, n33); } } 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(m2) { const te = this.elements; const me = m2.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(m2) { const me = m2.elements; this.set( me[0], me[4], me[8], me[1], me[5], me[9], me[2], me[6], me[10] ); return this; } multiply(m2) { return this.multiplyMatrices(this, m2); } premultiply(m2) { return this.multiplyMatrices(m2, this); } multiplyMatrices(a2, b) { const ae = a2.elements; const be = b.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], b = 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 - b * d * i + b * 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 tmp2; const m2 = this.elements; tmp2 = m2[1]; m2[1] = m2[3]; m2[3] = tmp2; tmp2 = m2[2]; m2[2] = m2[6]; m2[6] = tmp2; tmp2 = m2[5]; m2[5] = m2[7]; m2[7] = tmp2; return this; } getNormalMatrix(matrix4) { return this.setFromMatrix4(matrix4).invert().transpose(); } transposeIntoArray(r) { const m2 = this.elements; r[0] = m2[0]; r[1] = m2[3]; r[2] = m2[6]; r[3] = m2[1]; r[4] = m2[4]; r[5] = m2[7]; r[6] = m2[2]; r[7] = m2[5]; r[8] = m2[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) { this.premultiply(_m32.makeScale(sx, sy)); return this; } rotate(theta) { this.premultiply(_m32.makeRotation(-theta)); return this; } translate(tx, ty) { this.premultiply(_m32.makeTranslation(tx, ty)); return this; } // for 2D Transforms makeTranslation(x2, y2) { if (x2.isVector2) { this.set( 1, 0, x2.x, 0, 1, x2.y, 0, 0, 1 ); } else { this.set( 1, 0, x2, 0, 1, y2, 0, 0, 1 ); } return this; } makeRotation(theta) { const c2 = Math.cos(theta); const s = Math.sin(theta); this.set( c2, -s, 0, s, c2, 0, 0, 0, 1 ); return this; } makeScale(x2, y2) { this.set( x2, 0, 0, 0, y2, 0, 0, 0, 1 ); 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); } }; var _m32 = /* @__PURE__ */ new Matrix32(); function arrayNeedsUint32$1(array) { for (let i = array.length - 1; i >= 0; --i) { if (array[i] >= 65535) return true; } return false; } function createElementNS2(name) { return document.createElementNS("http://www.w3.org/1999/xhtml", name); } function createCanvasElement2() { const canvas = createElementNS2("canvas"); canvas.style.display = "block"; return canvas; } var _cache$2 = {}; function warnOnce2(message) { if (message in _cache$2) return; _cache$2[message] = true; console.warn(message); } var ColorManagement2 = { enabled: true, workingColorSpace: LinearSRGBColorSpace2, /** * Implementations of supported color spaces. * * Required: * - primaries: chromaticity coordinates [ rx ry gx gy bx by ] * - whitePoint: reference white [ x y ] * - transfer: transfer function (pre-defined) * - toXYZ: Matrix3 RGB to XYZ transform * - fromXYZ: Matrix3 XYZ to RGB transform * - luminanceCoefficients: RGB luminance coefficients * * Optional: * - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace } * - workingColorSpaceConfig: { unpackColorSpace: ColorSpace } * * Reference: * - https://www.russellcottrell.com/photo/matrixCalculator.htm */ spaces: {}, convert: function(color2, sourceColorSpace, targetColorSpace) { if (this.enabled === false || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) { return color2; } if (this.spaces[sourceColorSpace].transfer === SRGBTransfer2) { color2.r = SRGBToLinear2(color2.r); color2.g = SRGBToLinear2(color2.g); color2.b = SRGBToLinear2(color2.b); } if (this.spaces[sourceColorSpace].primaries !== this.spaces[targetColorSpace].primaries) { color2.applyMatrix3(this.spaces[sourceColorSpace].toXYZ); color2.applyMatrix3(this.spaces[targetColorSpace].fromXYZ); } if (this.spaces[targetColorSpace].transfer === SRGBTransfer2) { color2.r = LinearToSRGB2(color2.r); color2.g = LinearToSRGB2(color2.g); color2.b = LinearToSRGB2(color2.b); } return color2; }, fromWorkingColorSpace: function(color2, targetColorSpace) { return this.convert(color2, this.workingColorSpace, targetColorSpace); }, toWorkingColorSpace: function(color2, sourceColorSpace) { return this.convert(color2, sourceColorSpace, this.workingColorSpace); }, getPrimaries: function(colorSpace) { return this.spaces[colorSpace].primaries; }, getTransfer: function(colorSpace) { if (colorSpace === NoColorSpace2) return LinearTransfer2; return this.spaces[colorSpace].transfer; }, getLuminanceCoefficients: function(target, colorSpace = this.workingColorSpace) { return target.fromArray(this.spaces[colorSpace].luminanceCoefficients); }, define: function(colorSpaces) { Object.assign(this.spaces, colorSpaces); }, // Internal APIs _getMatrix: function(targetMatrix, sourceColorSpace, targetColorSpace) { return targetMatrix.copy(this.spaces[sourceColorSpace].toXYZ).multiply(this.spaces[targetColorSpace].fromXYZ); }, _getDrawingBufferColorSpace: function(colorSpace) { return this.spaces[colorSpace].outputColorSpaceConfig.drawingBufferColorSpace; }, _getUnpackColorSpace: function(colorSpace = this.workingColorSpace) { return this.spaces[colorSpace].workingColorSpaceConfig.unpackColorSpace; } }; function SRGBToLinear2(c2) { return c2 < 0.04045 ? c2 * 0.0773993808 : Math.pow(c2 * 0.9478672986 + 0.0521327014, 2.4); } function LinearToSRGB2(c2) { return c2 < 31308e-7 ? c2 * 12.92 : 1.055 * Math.pow(c2, 0.41666) - 0.055; } var REC709_PRIMARIES2 = [0.64, 0.33, 0.3, 0.6, 0.15, 0.06]; var REC709_LUMINANCE_COEFFICIENTS2 = [0.2126, 0.7152, 0.0722]; var D652 = [0.3127, 0.329]; var LINEAR_REC709_TO_XYZ2 = /* @__PURE__ */ new Matrix32().set( 0.4123908, 0.3575843, 0.1804808, 0.212639, 0.7151687, 0.0721923, 0.0193308, 0.1191948, 0.9505322 ); var XYZ_TO_LINEAR_REC7092 = /* @__PURE__ */ new Matrix32().set( 3.2409699, -1.5373832, -0.4986108, -0.9692436, 1.8759675, 0.0415551, 0.0556301, -0.203977, 1.0569715 ); ColorManagement2.define({ [LinearSRGBColorSpace2]: { primaries: REC709_PRIMARIES2, whitePoint: D652, transfer: LinearTransfer2, toXYZ: LINEAR_REC709_TO_XYZ2, fromXYZ: XYZ_TO_LINEAR_REC7092, luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS2, workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace2 }, outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace2 } }, [SRGBColorSpace2]: { primaries: REC709_PRIMARIES2, whitePoint: D652, transfer: SRGBTransfer2, toXYZ: LINEAR_REC709_TO_XYZ2, fromXYZ: XYZ_TO_LINEAR_REC7092, luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS2, outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace2 } } }); var _canvas2; var ImageUtils2 = 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 (_canvas2 === void 0) _canvas2 = createElementNS2("canvas"); _canvas2.width = image.width; _canvas2.height = image.height; const context2 = _canvas2.getContext("2d"); if (image instanceof ImageData) { context2.putImageData(image, 0, 0); } else { context2.drawImage(image, 0, 0, image.width, image.height); } canvas = _canvas2; } 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"); } } static sRGBToLinear(image) { if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) { const canvas = createElementNS2("canvas"); canvas.width = image.width; canvas.height = image.height; const context2 = canvas.getContext("2d"); context2.drawImage(image, 0, 0, image.width, image.height); const imageData = context2.getImageData(0, 0, image.width, image.height); const data = imageData.data; for (let i = 0; i < data.length; i++) { data[i] = SRGBToLinear2(data[i] / 255) * 255; } context2.putImageData(imageData, 0, 0); return canvas; } else if (image.data) { const data = image.data.slice(0); for (let i = 0; i < data.length; i++) { if (data instanceof Uint8Array || data instanceof Uint8ClampedArray) { data[i] = Math.floor(SRGBToLinear2(data[i] / 255) * 255); } else { data[i] = SRGBToLinear2(data[i]); } } return { data, width: image.width, height: image.height }; } else { console.warn("THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied."); return image; } } }; var _sourceId2 = 0; var Source2 = class { constructor(data = null) { this.isSource = true; Object.defineProperty(this, "id", { value: _sourceId2++ }); this.uuid = generateUUID2(); this.data = data; this.dataReady = true; this.version = 0; } set needsUpdate(value) { if (value === true) this.version++; } toJSON(meta) { const isRootObject = meta === void 0 || typeof meta === "string"; if (!isRootObject && meta.images[this.uuid] !== void 0) { return meta.images[this.uuid]; } const output2 = { uuid: this.uuid, url: "" }; const data = this.data; if (data !== null) { let url; if (Array.isArray(data)) { url = []; for (let i = 0, l = data.length; i < l; i++) { if (data[i].isDataTexture) { url.push(serializeImage2(data[i].image)); } else { url.push(serializeImage2(data[i])); } } } else { url = serializeImage2(data); } output2.url = url; } if (!isRootObject) { meta.images[this.uuid] = output2; } return output2; } }; function serializeImage2(image) { if (typeof HTMLImageElement !== "undefined" && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== "undefined" && image instanceof HTMLCanvasElement || typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) { return ImageUtils2.getDataURL(image); } else { if (image.data) { return { data: Array.from(image.data), width: image.width, height: image.height, type: image.data.constructor.name }; } else { console.warn("THREE.Texture: Unable to serialize Texture."); return {}; } } } var _textureId2 = 0; var Texture2 = class _Texture extends EventDispatcher2 { constructor(image = _Texture.DEFAULT_IMAGE, mapping = _Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping2, wrapT = ClampToEdgeWrapping2, magFilter = LinearFilter2, minFilter = LinearMipmapLinearFilter2, format2 = RGBAFormat2, type = UnsignedByteType2, anisotropy2 = _Texture.DEFAULT_ANISOTROPY, colorSpace = NoColorSpace2) { super(); this.isTexture = true; Object.defineProperty(this, "id", { value: _textureId2++ }); this.uuid = generateUUID2(); this.name = ""; this.source = new Source2(image); this.mipmaps = []; this.mapping = mapping; this.channel = 0; this.wrapS = wrapS; this.wrapT = wrapT; this.magFilter = magFilter; this.minFilter = minFilter; this.anisotropy = anisotropy2; this.format = format2; this.internalFormat = null; this.type = type; this.offset = new Vector22(0, 0); this.repeat = new Vector22(1, 1); this.center = new Vector22(0, 0); this.rotation = 0; this.matrixAutoUpdate = true; this.matrix = new Matrix32(); this.generateMipmaps = true; this.premultiplyAlpha = false; this.flipY = true; this.unpackAlignment = 4; this.colorSpace = colorSpace; this.userData = {}; this.version = 0; this.onUpdate = null; this.isRenderTargetTexture = false; this.pmremVersion = 0; } get image() { return this.source.data; } set image(value = null) { this.source.data = value; } 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.source = source.source; this.mipmaps = source.mipmaps.slice(0); this.mapping = source.mapping; this.channel = source.channel; 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.colorSpace = source.colorSpace; this.userData = JSON.parse(JSON.stringify(source.userData)); this.needsUpdate = true; 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 output2 = { metadata: { version: 4.6, type: "Texture", generator: "Texture.toJSON" }, uuid: this.uuid, name: this.name, image: this.source.toJSON(meta).uuid, mapping: this.mapping, channel: this.channel, 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, internalFormat: this.internalFormat, type: this.type, colorSpace: this.colorSpace, minFilter: this.minFilter, magFilter: this.magFilter, anisotropy: this.anisotropy, flipY: this.flipY, generateMipmaps: this.generateMipmaps, premultiplyAlpha: this.premultiplyAlpha, unpackAlignment: this.unpackAlignment }; if (Object.keys(this.userData).length > 0) output2.userData = this.userData; if (!isRootObject) { meta.textures[this.uuid] = output2; } return output2; } dispose() { this.dispatchEvent({ type: "dispose" }); } transformUv(uv2) { if (this.mapping !== UVMapping2) return uv2; uv2.applyMatrix3(this.matrix); if (uv2.x < 0 || uv2.x > 1) { switch (this.wrapS) { case RepeatWrapping2: uv2.x = uv2.x - Math.floor(uv2.x); break; case ClampToEdgeWrapping2: uv2.x = uv2.x < 0 ? 0 : 1; break; case MirroredRepeatWrapping2: if (Math.abs(Math.floor(uv2.x) % 2) === 1) { uv2.x = Math.ceil(uv2.x) - uv2.x; } else { uv2.x = uv2.x - Math.floor(uv2.x); } break; } } if (uv2.y < 0 || uv2.y > 1) { switch (this.wrapT) { case RepeatWrapping2: uv2.y = uv2.y - Math.floor(uv2.y); break; case ClampToEdgeWrapping2: uv2.y = uv2.y < 0 ? 0 : 1; break; case MirroredRepeatWrapping2: if (Math.abs(Math.floor(uv2.y) % 2) === 1) { uv2.y = Math.ceil(uv2.y) - uv2.y; } else { uv2.y = uv2.y - Math.floor(uv2.y); } break; } } if (this.flipY) { uv2.y = 1 - uv2.y; } return uv2; } set needsUpdate(value) { if (value === true) { this.version++; this.source.needsUpdate = true; } } set needsPMREMUpdate(value) { if (value === true) { this.pmremVersion++; } } }; Texture2.DEFAULT_IMAGE = null; Texture2.DEFAULT_MAPPING = UVMapping2; Texture2.DEFAULT_ANISOTROPY = 1; var Vector42 = class _Vector4 { constructor(x2 = 0, y2 = 0, z2 = 0, w = 1) { _Vector4.prototype.isVector4 = true; this.x = x2; this.y = y2; this.z = z2; this.w = w; } get width() { return this.z; } set width(value) { this.z = value; } get height() { return this.w; } set height(value) { this.w = value; } set(x2, y2, z2, w) { this.x = x2; this.y = y2; this.z = z2; this.w = w; return this; } setScalar(scalar) { this.x = scalar; this.y = scalar; this.z = scalar; this.w = scalar; return this; } setX(x2) { this.x = x2; return this; } setY(y2) { this.y = y2; return this; } setZ(z2) { this.z = z2; return this; } setW(w) { this.w = w; return this; } setComponent(index5, value) { switch (index5) { 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: " + index5); } return this; } getComponent(index5) { switch (index5) { 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: " + index5); } } 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) { 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, b) { this.x = a2.x + b.x; this.y = a2.y + b.y; this.z = a2.z + b.z; this.w = a2.w + b.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) { 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, b) { this.x = a2.x - b.x; this.y = a2.y - b.y; this.z = a2.z - b.z; this.w = a2.w - b.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(m2) { const x2 = this.x, y2 = this.y, z2 = this.z, w = this.w; const e = m2.elements; this.x = e[0] * x2 + e[4] * y2 + e[8] * z2 + e[12] * w; this.y = e[1] * x2 + e[5] * y2 + e[9] * z2 + e[13] * w; this.z = e[2] * x2 + e[6] * y2 + e[10] * z2 + e[14] * w; this.w = e[3] * x2 + e[7] * y2 + e[11] * z2 + e[15] * w; return this; } divide(v) { this.x /= v.x; this.y /= v.y; this.z /= v.z; this.w /= v.w; 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(m2) { let angle, x2, y2, z2; const epsilon = 0.01, epsilon2 = 0.1, te = m2.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) { x2 = 0; y2 = 0.707106781; z2 = 0.707106781; } else { x2 = Math.sqrt(xx); y2 = xy / x2; z2 = xz / x2; } } else if (yy > zz) { if (yy < epsilon) { x2 = 0.707106781; y2 = 0; z2 = 0.707106781; } else { y2 = Math.sqrt(yy); x2 = xy / y2; z2 = yz / y2; } } else { if (zz < epsilon) { x2 = 0.707106781; y2 = 0.707106781; z2 = 0; } else { z2 = Math.sqrt(zz); x2 = xz / z2; y2 = yz / z2; } } this.set(x2, y2, z2, 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; } setFromMatrixPosition(m2) { const e = m2.elements; this.x = e[12]; this.y = e[13]; this.z = e[14]; this.w = e[15]; 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(min2, max2) { this.x = Math.max(min2.x, Math.min(max2.x, this.x)); this.y = Math.max(min2.y, Math.min(max2.y, this.y)); this.z = Math.max(min2.z, Math.min(max2.z, this.z)); this.w = Math.max(min2.w, Math.min(max2.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(min2, max2) { const length2 = this.length(); return this.divideScalar(length2 || 1).multiplyScalar(Math.max(min2, Math.min(max2, length2))); } 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 = Math.trunc(this.x); this.y = Math.trunc(this.y); this.z = Math.trunc(this.z); this.w = Math.trunc(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(length2) { return this.normalize().multiplyScalar(length2); } 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(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.y) * alpha; this.z = v1.z + (v2.z - v1.z) * alpha; this.w = v1.w + (v2.w - v1.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(attribute2, index5) { this.x = attribute2.getX(index5); this.y = attribute2.getY(index5); this.z = attribute2.getZ(index5); this.w = attribute2.getW(index5); return this; } random() { this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); this.w = Math.random(); return this; } *[Symbol.iterator]() { yield this.x; yield this.y; yield this.z; yield this.w; } }; var RenderTarget2 = class extends EventDispatcher2 { constructor(width = 1, height = 1, options = {}) { super(); this.isRenderTarget = true; this.width = width; this.height = height; this.depth = 1; this.scissor = new Vector42(0, 0, width, height); this.scissorTest = false; this.viewport = new Vector42(0, 0, width, height); const image = { width, height, depth: 1 }; options = Object.assign({ generateMipmaps: false, internalFormat: null, minFilter: LinearFilter2, depthBuffer: true, stencilBuffer: false, resolveDepthBuffer: true, resolveStencilBuffer: true, depthTexture: null, samples: 0, count: 1 }, options); const texture2 = new Texture2(image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.colorSpace); texture2.flipY = false; texture2.generateMipmaps = options.generateMipmaps; texture2.internalFormat = options.internalFormat; this.textures = []; const count = options.count; for (let i = 0; i < count; i++) { this.textures[i] = texture2.clone(); this.textures[i].isRenderTargetTexture = true; } this.depthBuffer = options.depthBuffer; this.stencilBuffer = options.stencilBuffer; this.resolveDepthBuffer = options.resolveDepthBuffer; this.resolveStencilBuffer = options.resolveStencilBuffer; this.depthTexture = options.depthTexture; this.samples = options.samples; } get texture() { return this.textures[0]; } set texture(value) { this.textures[0] = value; } setSize(width, height, depth2 = 1) { if (this.width !== width || this.height !== height || this.depth !== depth2) { this.width = width; this.height = height; this.depth = depth2; for (let i = 0, il = this.textures.length; i < il; i++) { this.textures[i].image.width = width; this.textures[i].image.height = height; this.textures[i].image.depth = depth2; } 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.scissor.copy(source.scissor); this.scissorTest = source.scissorTest; this.viewport.copy(source.viewport); this.textures.length = 0; for (let i = 0, il = source.textures.length; i < il; i++) { this.textures[i] = source.textures[i].clone(); this.textures[i].isRenderTargetTexture = true; } const image = Object.assign({}, source.texture.image); this.texture.source = new Source2(image); this.depthBuffer = source.depthBuffer; this.stencilBuffer = source.stencilBuffer; this.resolveDepthBuffer = source.resolveDepthBuffer; this.resolveStencilBuffer = source.resolveStencilBuffer; if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone(); this.samples = source.samples; return this; } dispose() { this.dispatchEvent({ type: "dispose" }); } }; var WebGLRenderTarget2 = class extends RenderTarget2 { constructor(width = 1, height = 1, options = {}) { super(width, height, options); this.isWebGLRenderTarget = true; } }; var DataArrayTexture2 = class extends Texture2 { constructor(data = null, width = 1, height = 1, depth2 = 1) { super(null); this.isDataArrayTexture = true; this.image = { data, width, height, depth: depth2 }; this.magFilter = NearestFilter2; this.minFilter = NearestFilter2; this.wrapR = ClampToEdgeWrapping2; this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; this.layerUpdates = /* @__PURE__ */ new Set(); } addLayerUpdate(layerIndex) { this.layerUpdates.add(layerIndex); } clearLayerUpdates() { this.layerUpdates.clear(); } }; var Quaternion2 = class { constructor(x2 = 0, y2 = 0, z2 = 0, w = 1) { this.isQuaternion = true; this._x = x2; this._y = y2; this._z = z2; this._w = w; } static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) { let x0 = src0[srcOffset0 + 0], y0 = src0[srcOffset0 + 1], z0 = src0[srcOffset0 + 2], w02 = src0[srcOffset0 + 3]; const x1 = src1[srcOffset1 + 0], y1 = src1[srcOffset1 + 1], z1 = src1[srcOffset1 + 2], w12 = src1[srcOffset1 + 3]; if (t === 0) { dst[dstOffset + 0] = x0; dst[dstOffset + 1] = y0; dst[dstOffset + 2] = z0; dst[dstOffset + 3] = w02; return; } if (t === 1) { dst[dstOffset + 0] = x1; dst[dstOffset + 1] = y1; dst[dstOffset + 2] = z1; dst[dstOffset + 3] = w12; return; } if (w02 !== w12 || x0 !== x1 || y0 !== y1 || z0 !== z1) { let s = 1 - t; const cos2 = x0 * x1 + y0 * y1 + z0 * z1 + w02 * w12, dir = cos2 >= 0 ? 1 : -1, sqrSin = 1 - cos2 * cos2; if (sqrSin > Number.EPSILON) { const sin2 = Math.sqrt(sqrSin), len = Math.atan2(sin2, cos2 * dir); s = Math.sin(s * len) / sin2; t = Math.sin(t * len) / sin2; } const tDir = t * dir; x0 = x0 * s + x1 * tDir; y0 = y0 * s + y1 * tDir; z0 = z0 * s + z1 * tDir; w02 = w02 * s + w12 * tDir; if (s === 1 - t) { const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w02 * w02); x0 *= f; y0 *= f; z0 *= f; w02 *= f; } } dst[dstOffset] = x0; dst[dstOffset + 1] = y0; dst[dstOffset + 2] = z0; dst[dstOffset + 3] = w02; } static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) { const x0 = src0[srcOffset0]; const y0 = src0[srcOffset0 + 1]; const z0 = src0[srcOffset0 + 2]; const w02 = src0[srcOffset0 + 3]; const x1 = src1[srcOffset1]; const y1 = src1[srcOffset1 + 1]; const z1 = src1[srcOffset1 + 2]; const w12 = src1[srcOffset1 + 3]; dst[dstOffset] = x0 * w12 + w02 * x1 + y0 * z1 - z0 * y1; dst[dstOffset + 1] = y0 * w12 + w02 * y1 + z0 * x1 - x0 * z1; dst[dstOffset + 2] = z0 * w12 + w02 * z1 + x0 * y1 - y0 * x1; dst[dstOffset + 3] = w02 * w12 - 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(x2, y2, z2, w) { this._x = x2; this._y = y2; this._z = z2; this._w = w; 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, update4 = true) { const x2 = euler._x, y2 = euler._y, z2 = euler._z, order = euler._order; const cos2 = Math.cos; const sin2 = Math.sin; const c1 = cos2(x2 / 2); const c2 = cos2(y2 / 2); const c3 = cos2(z2 / 2); const s1 = sin2(x2 / 2); const s2 = sin2(y2 / 2); const s3 = sin2(z2 / 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 (update4 === true) 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(m2) { const te = m2.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$1(this.dot(q), -1, 1))); } rotateTowards(q, step2) { const angle = this.angleTo(q); if (angle === 0) return this; const t = Math.min(1, step2 / 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) { return this.multiplyQuaternions(this, q); } premultiply(q) { return this.multiplyQuaternions(q, this); } multiplyQuaternions(a2, b) { const qax = a2._x, qay = a2._y, qaz = a2._z, qaw = a2._w; const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; this._onChangeCallback(); return this; } slerp(qb, t) { if (t === 0) return this; if (t === 1) return this.copy(qb); const x2 = this._x, y2 = this._y, z2 = this._z, w = this._w; let cosHalfTheta = w * qb._w + x2 * qb._x + y2 * qb._y + z2 * 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 = w; this._x = x2; this._y = y2; this._z = z2; return this; } const sqrSinHalfTheta = 1 - cosHalfTheta * cosHalfTheta; if (sqrSinHalfTheta <= Number.EPSILON) { const s = 1 - t; this._w = s * w + t * this._w; this._x = s * x2 + t * this._x; this._y = s * y2 + t * this._y; this._z = s * z2 + t * this._z; this.normalize(); 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 = w * ratioA + this._w * ratioB; this._x = x2 * ratioA + this._x * ratioB; this._y = y2 * ratioA + this._y * ratioB; this._z = z2 * ratioA + this._z * ratioB; this._onChangeCallback(); return this; } slerpQuaternions(qa, qb, t) { return this.copy(qa).slerp(qb, t); } random() { const theta1 = 2 * Math.PI * Math.random(); const theta2 = 2 * Math.PI * Math.random(); const x0 = Math.random(); const r1 = Math.sqrt(1 - x0); const r2 = Math.sqrt(x0); return this.set( r1 * Math.sin(theta1), r1 * Math.cos(theta1), r2 * Math.sin(theta2), r2 * Math.cos(theta2) ); } 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(attribute2, index5) { this._x = attribute2.getX(index5); this._y = attribute2.getY(index5); this._z = attribute2.getZ(index5); this._w = attribute2.getW(index5); this._onChangeCallback(); return this; } toJSON() { return this.toArray(); } _onChange(callback) { this._onChangeCallback = callback; return this; } _onChangeCallback() { } *[Symbol.iterator]() { yield this._x; yield this._y; yield this._z; yield this._w; } }; var Vector32 = class _Vector3 { constructor(x2 = 0, y2 = 0, z2 = 0) { _Vector3.prototype.isVector3 = true; this.x = x2; this.y = y2; this.z = z2; } set(x2, y2, z2) { if (z2 === void 0) z2 = this.z; this.x = x2; this.y = y2; this.z = z2; return this; } setScalar(scalar) { this.x = scalar; this.y = scalar; this.z = scalar; return this; } setX(x2) { this.x = x2; return this; } setY(y2) { this.y = y2; return this; } setZ(z2) { this.z = z2; return this; } setComponent(index5, value) { switch (index5) { 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: " + index5); } return this; } getComponent(index5) { switch (index5) { case 0: return this.x; case 1: return this.y; case 2: return this.z; default: throw new Error("index is out of range: " + index5); } } 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) { 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, b) { this.x = a2.x + b.x; this.y = a2.y + b.y; this.z = a2.z + b.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) { 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, b) { this.x = a2.x - b.x; this.y = a2.y - b.y; this.z = a2.z - b.z; return this; } multiply(v) { 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, b) { this.x = a2.x * b.x; this.y = a2.y * b.y; this.z = a2.z * b.z; return this; } applyEuler(euler) { return this.applyQuaternion(_quaternion$42.setFromEuler(euler)); } applyAxisAngle(axis, angle) { return this.applyQuaternion(_quaternion$42.setFromAxisAngle(axis, angle)); } applyMatrix3(m2) { const x2 = this.x, y2 = this.y, z2 = this.z; const e = m2.elements; this.x = e[0] * x2 + e[3] * y2 + e[6] * z2; this.y = e[1] * x2 + e[4] * y2 + e[7] * z2; this.z = e[2] * x2 + e[5] * y2 + e[8] * z2; return this; } applyNormalMatrix(m2) { return this.applyMatrix3(m2).normalize(); } applyMatrix4(m2) { const x2 = this.x, y2 = this.y, z2 = this.z; const e = m2.elements; const w = 1 / (e[3] * x2 + e[7] * y2 + e[11] * z2 + e[15]); this.x = (e[0] * x2 + e[4] * y2 + e[8] * z2 + e[12]) * w; this.y = (e[1] * x2 + e[5] * y2 + e[9] * z2 + e[13]) * w; this.z = (e[2] * x2 + e[6] * y2 + e[10] * z2 + e[14]) * w; return this; } applyQuaternion(q) { const vx = this.x, vy = this.y, vz = this.z; const qx = q.x, qy = q.y, qz = q.z, qw = q.w; const tx = 2 * (qy * vz - qz * vy); const ty = 2 * (qz * vx - qx * vz); const tz = 2 * (qx * vy - qy * vx); this.x = vx + qw * tx + qy * tz - qz * ty; this.y = vy + qw * ty + qz * tx - qx * tz; this.z = vz + qw * tz + qx * ty - qy * tx; return this; } project(camera3) { return this.applyMatrix4(camera3.matrixWorldInverse).applyMatrix4(camera3.projectionMatrix); } unproject(camera3) { return this.applyMatrix4(camera3.projectionMatrixInverse).applyMatrix4(camera3.matrixWorld); } transformDirection(m2) { const x2 = this.x, y2 = this.y, z2 = this.z; const e = m2.elements; this.x = e[0] * x2 + e[4] * y2 + e[8] * z2; this.y = e[1] * x2 + e[5] * y2 + e[9] * z2; this.z = e[2] * x2 + e[6] * y2 + e[10] * z2; 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(min2, max2) { this.x = Math.max(min2.x, Math.min(max2.x, this.x)); this.y = Math.max(min2.y, Math.min(max2.y, this.y)); this.z = Math.max(min2.z, Math.min(max2.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(min2, max2) { const length2 = this.length(); return this.divideScalar(length2 || 1).multiplyScalar(Math.max(min2, Math.min(max2, length2))); } 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 = Math.trunc(this.x); this.y = Math.trunc(this.y); this.z = Math.trunc(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; } // TODO lengthSquared? 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(length2) { return this.normalize().multiplyScalar(length2); } 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(v1, v2, alpha) { this.x = v1.x + (v2.x - v1.x) * alpha; this.y = v1.y + (v2.y - v1.y) * alpha; this.z = v1.z + (v2.z - v1.z) * alpha; return this; } cross(v) { return this.crossVectors(this, v); } crossVectors(a2, b) { const ax = a2.x, ay = a2.y, az = a2.z; const bx = b.x, by = b.y, bz = b.z; this.x = ay * bz - az * by; this.y = az * bx - ax * bz; this.z = ax * by - ay * bx; return this; } projectOnVector(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$c2.copy(this).projectOnVector(planeNormal); return this.sub(_vector$c2); } reflect(normal2) { return this.sub(_vector$c2.copy(normal2).multiplyScalar(2 * this.dot(normal2))); } 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$1(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, y2) { this.x = radius * Math.sin(theta); this.y = y2; this.z = radius * Math.cos(theta); return this; } setFromMatrixPosition(m2) { const e = m2.elements; this.x = e[12]; this.y = e[13]; this.z = e[14]; return this; } setFromMatrixScale(m2) { const sx = this.setFromMatrixColumn(m2, 0).length(); const sy = this.setFromMatrixColumn(m2, 1).length(); const sz = this.setFromMatrixColumn(m2, 2).length(); this.x = sx; this.y = sy; this.z = sz; return this; } setFromMatrixColumn(m2, index5) { return this.fromArray(m2.elements, index5 * 4); } setFromMatrix3Column(m2, index5) { return this.fromArray(m2.elements, index5 * 3); } setFromEuler(e) { this.x = e._x; this.y = e._y; this.z = e._z; return this; } setFromColor(c2) { this.x = c2.r; this.y = c2.g; this.z = c2.b; return this; } 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(attribute2, index5) { this.x = attribute2.getX(index5); this.y = attribute2.getY(index5); this.z = attribute2.getZ(index5); return this; } random() { this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); return this; } randomDirection() { const theta = Math.random() * Math.PI * 2; const u = Math.random() * 2 - 1; const c2 = Math.sqrt(1 - u * u); this.x = c2 * Math.cos(theta); this.y = u; this.z = c2 * Math.sin(theta); return this; } *[Symbol.iterator]() { yield this.x; yield this.y; yield this.z; } }; var _vector$c2 = /* @__PURE__ */ new Vector32(); var _quaternion$42 = /* @__PURE__ */ new Quaternion2(); var Box32 = class { constructor(min2 = new Vector32(Infinity, Infinity, Infinity), max2 = new Vector32(-Infinity, -Infinity, -Infinity)) { this.isBox3 = true; this.min = min2; this.max = max2; } set(min2, max2) { this.min.copy(min2); this.max.copy(max2); return this; } setFromArray(array) { this.makeEmpty(); for (let i = 0, il = array.length; i < il; i += 3) { this.expandByPoint(_vector$b2.fromArray(array, i)); } return this; } setFromBufferAttribute(attribute2) { this.makeEmpty(); for (let i = 0, il = attribute2.count; i < il; i++) { this.expandByPoint(_vector$b2.fromBufferAttribute(attribute2, i)); } 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$b2.copy(size).multiplyScalar(0.5); this.min.copy(center).sub(halfSize); this.max.copy(center).add(halfSize); return this; } setFromObject(object, precise = false) { this.makeEmpty(); return this.expandByObject(object, precise); } 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, precise = false) { object.updateWorldMatrix(false, false); const geometry = object.geometry; if (geometry !== void 0) { const positionAttribute = geometry.getAttribute("position"); if (precise === true && positionAttribute !== void 0 && object.isInstancedMesh !== true) { for (let i = 0, l = positionAttribute.count; i < l; i++) { if (object.isMesh === true) { object.getVertexPosition(i, _vector$b2); } else { _vector$b2.fromBufferAttribute(positionAttribute, i); } _vector$b2.applyMatrix4(object.matrixWorld); this.expandByPoint(_vector$b2); } } else { if (object.boundingBox !== void 0) { if (object.boundingBox === null) { object.computeBoundingBox(); } _box$42.copy(object.boundingBox); } else { if (geometry.boundingBox === null) { geometry.computeBoundingBox(); } _box$42.copy(geometry.boundingBox); } _box$42.applyMatrix4(object.matrixWorld); this.union(_box$42); } } const children = object.children; for (let i = 0, l = children.length; i < l; i++) { this.expandByObject(children[i], precise); } 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; } 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; } intersectsSphere(sphere) { this.clampPoint(sphere.center, _vector$b2); return _vector$b2.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius; } intersectsPlane(plane) { let min2, max2; if (plane.normal.x > 0) { min2 = plane.normal.x * this.min.x; max2 = plane.normal.x * this.max.x; } else { min2 = plane.normal.x * this.max.x; max2 = plane.normal.x * this.min.x; } if (plane.normal.y > 0) { min2 += plane.normal.y * this.min.y; max2 += plane.normal.y * this.max.y; } else { min2 += plane.normal.y * this.max.y; max2 += plane.normal.y * this.min.y; } if (plane.normal.z > 0) { min2 += plane.normal.z * this.min.z; max2 += plane.normal.z * this.max.z; } else { min2 += plane.normal.z * this.max.z; max2 += plane.normal.z * this.min.z; } return min2 <= -plane.constant && max2 >= -plane.constant; } intersectsTriangle(triangle) { if (this.isEmpty()) { return false; } this.getCenter(_center2); _extents2.subVectors(this.max, _center2); _v0$22.subVectors(triangle.a, _center2); _v1$72.subVectors(triangle.b, _center2); _v2$42.subVectors(triangle.c, _center2); _f02.subVectors(_v1$72, _v0$22); _f12.subVectors(_v2$42, _v1$72); _f22.subVectors(_v0$22, _v2$42); let axes = [ 0, -_f02.z, _f02.y, 0, -_f12.z, _f12.y, 0, -_f22.z, _f22.y, _f02.z, 0, -_f02.x, _f12.z, 0, -_f12.x, _f22.z, 0, -_f22.x, -_f02.y, _f02.x, 0, -_f12.y, _f12.x, 0, -_f22.y, _f22.x, 0 ]; if (!satForAxes2(axes, _v0$22, _v1$72, _v2$42, _extents2)) { return false; } axes = [1, 0, 0, 0, 1, 0, 0, 0, 1]; if (!satForAxes2(axes, _v0$22, _v1$72, _v2$42, _extents2)) { return false; } _triangleNormal2.crossVectors(_f02, _f12); axes = [_triangleNormal2.x, _triangleNormal2.y, _triangleNormal2.z]; return satForAxes2(axes, _v0$22, _v1$72, _v2$42, _extents2); } clampPoint(point, target) { return target.copy(point).clamp(this.min, this.max); } distanceToPoint(point) { return this.clampPoint(point, _vector$b2).distanceTo(point); } getBoundingSphere(target) { if (this.isEmpty()) { target.makeEmpty(); } else { this.getCenter(target.center); target.radius = this.getSize(_vector$b2).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; _points2[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); _points2[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); _points2[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); _points2[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); _points2[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); _points2[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); _points2[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); _points2[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); this.setFromPoints(_points2); 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); } }; var _points2 = [ /* @__PURE__ */ new Vector32(), /* @__PURE__ */ new Vector32(), /* @__PURE__ */ new Vector32(), /* @__PURE__ */ new Vector32(), /* @__PURE__ */ new Vector32(), /* @__PURE__ */ new Vector32(), /* @__PURE__ */ new Vector32(), /* @__PURE__ */ new Vector32() ]; var _vector$b2 = /* @__PURE__ */ new Vector32(); var _box$42 = /* @__PURE__ */ new Box32(); var _v0$22 = /* @__PURE__ */ new Vector32(); var _v1$72 = /* @__PURE__ */ new Vector32(); var _v2$42 = /* @__PURE__ */ new Vector32(); var _f02 = /* @__PURE__ */ new Vector32(); var _f12 = /* @__PURE__ */ new Vector32(); var _f22 = /* @__PURE__ */ new Vector32(); var _center2 = /* @__PURE__ */ new Vector32(); var _extents2 = /* @__PURE__ */ new Vector32(); var _triangleNormal2 = /* @__PURE__ */ new Vector32(); var _testAxis2 = /* @__PURE__ */ new Vector32(); function satForAxes2(axes, v0, v1, v2, extents) { for (let i = 0, j = axes.length - 3; i <= j; i += 3) { _testAxis2.fromArray(axes, i); const r = extents.x * Math.abs(_testAxis2.x) + extents.y * Math.abs(_testAxis2.y) + extents.z * Math.abs(_testAxis2.z); const p0 = v0.dot(_testAxis2); const p1 = v1.dot(_testAxis2); const p2 = v2.dot(_testAxis2); if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) { return false; } } return true; } var _box$32 = /* @__PURE__ */ new Box32(); var _v1$62 = /* @__PURE__ */ new Vector32(); var _v2$32 = /* @__PURE__ */ new Vector32(); var Sphere2 = class { constructor(center = new Vector32(), radius = -1) { this.isSphere = true; 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$32.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) { if (this.isEmpty()) { this.center.copy(point); this.radius = 0; return this; } _v1$62.subVectors(point, this.center); const lengthSq2 = _v1$62.lengthSq(); if (lengthSq2 > this.radius * this.radius) { const length2 = Math.sqrt(lengthSq2); const delta = (length2 - this.radius) * 0.5; this.center.addScaledVector(_v1$62, delta / length2); this.radius += delta; } return this; } union(sphere) { if (sphere.isEmpty()) { return this; } if (this.isEmpty()) { this.copy(sphere); return this; } if (this.center.equals(sphere.center) === true) { this.radius = Math.max(this.radius, sphere.radius); } else { _v2$32.subVectors(sphere.center, this.center).setLength(sphere.radius); this.expandByPoint(_v1$62.copy(sphere.center).add(_v2$32)); this.expandByPoint(_v1$62.copy(sphere.center).sub(_v2$32)); } return this; } equals(sphere) { return sphere.center.equals(this.center) && sphere.radius === this.radius; } clone() { return new this.constructor().copy(this); } }; var _vector$a2 = /* @__PURE__ */ new Vector32(); var _segCenter2 = /* @__PURE__ */ new Vector32(); var _segDir2 = /* @__PURE__ */ new Vector32(); var _diff3 = /* @__PURE__ */ new Vector32(); var _edge12 = /* @__PURE__ */ new Vector32(); var _edge22 = /* @__PURE__ */ new Vector32(); var _normal$2 = /* @__PURE__ */ new Vector32(); var Ray2 = class { constructor(origin = new Vector32(), direction2 = new Vector32(0, 0, -1)) { this.origin = origin; this.direction = direction2; } set(origin, direction2) { this.origin.copy(origin); this.direction.copy(direction2); return this; } copy(ray) { this.origin.copy(ray.origin); this.direction.copy(ray.direction); return this; } at(t, target) { return target.copy(this.origin).addScaledVector(this.direction, t); } lookAt(v) { this.direction.copy(v).sub(this.origin).normalize(); return this; } recast(t) { this.origin.copy(this.at(t, _vector$a2)); 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.origin).addScaledVector(this.direction, directionDistance); } distanceToPoint(point) { return Math.sqrt(this.distanceSqToPoint(point)); } distanceSqToPoint(point) { const directionDistance = _vector$a2.subVectors(point, this.origin).dot(this.direction); if (directionDistance < 0) { return this.origin.distanceToSquared(point); } _vector$a2.copy(this.origin).addScaledVector(this.direction, directionDistance); return _vector$a2.distanceToSquared(point); } distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) { _segCenter2.copy(v0).add(v1).multiplyScalar(0.5); _segDir2.copy(v1).sub(v0).normalize(); _diff3.copy(this.origin).sub(_segCenter2); const segExtent = v0.distanceTo(v1) * 0.5; const a01 = -this.direction.dot(_segDir2); const b0 = _diff3.dot(this.direction); const b1 = -_diff3.dot(_segDir2); const c2 = _diff3.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.origin).addScaledVector(this.direction, s0); } if (optionalPointOnSegment) { optionalPointOnSegment.copy(_segCenter2).addScaledVector(_segDir2, s1); } return sqrDist; } intersectSphere(sphere, target) { _vector$a2.subVectors(sphere.center, this.origin); const tca = _vector$a2.dot(this.direction); const d2 = _vector$a2.dot(_vector$a2) - 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 (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 || isNaN(tmin)) tmin = tymin; if (tymax < tmax || isNaN(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$a2) !== null; } intersectTriangle(a2, b, c2, backfaceCulling, target) { _edge12.subVectors(b, a2); _edge22.subVectors(c2, a2); _normal$2.crossVectors(_edge12, _edge22); let DdN = this.direction.dot(_normal$2); let sign2; if (DdN > 0) { if (backfaceCulling) return null; sign2 = 1; } else if (DdN < 0) { sign2 = -1; DdN = -DdN; } else { return null; } _diff3.subVectors(this.origin, a2); const DdQxE2 = sign2 * this.direction.dot(_edge22.crossVectors(_diff3, _edge22)); if (DdQxE2 < 0) { return null; } const DdE1xQ = sign2 * this.direction.dot(_edge12.cross(_diff3)); if (DdE1xQ < 0) { return null; } if (DdQxE2 + DdE1xQ > DdN) { return null; } const QdN = -sign2 * _diff3.dot(_normal$2); 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 Matrix42 = class _Matrix4 { constructor(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) { _Matrix4.prototype.isMatrix4 = true; this.elements = [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]; if (n11 !== void 0) { this.set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44); } } 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(m2) { const te = this.elements; const me = m2.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(m2) { const te = this.elements, me = m2.elements; te[12] = me[12]; te[13] = me[13]; te[14] = me[14]; return this; } setFromMatrix3(m2) { const me = m2.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(m2) { const te = this.elements; const me = m2.elements; const scaleX = 1 / _v1$52.setFromMatrixColumn(m2, 0).length(); const scaleY = 1 / _v1$52.setFromMatrixColumn(m2, 1).length(); const scaleZ = 1 / _v1$52.setFromMatrixColumn(m2, 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) { const te = this.elements; const x2 = euler.x, y2 = euler.y, z2 = euler.z; const a2 = Math.cos(x2), b = Math.sin(x2); const c2 = Math.cos(y2), d = Math.sin(y2); const e = Math.cos(z2), f = Math.sin(z2); if (euler.order === "XYZ") { const ae = a2 * e, af = a2 * f, be = b * e, bf = b * f; te[0] = c2 * e; te[4] = -c2 * f; te[8] = d; te[1] = af + be * d; te[5] = ae - bf * d; te[9] = -b * 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 * b; te[4] = de * b - cf; te[8] = a2 * d; te[1] = a2 * f; te[5] = a2 * e; te[9] = -b; te[2] = cf * b - de; te[6] = df + ce * b; 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 * b; te[4] = -a2 * f; te[8] = de + cf * b; te[1] = cf + de * b; te[5] = a2 * e; te[9] = df - ce * b; te[2] = -a2 * d; te[6] = b; te[10] = a2 * c2; } else if (euler.order === "ZYX") { const ae = a2 * e, af = a2 * f, be = b * e, bf = b * 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] = b * c2; te[10] = a2 * c2; } else if (euler.order === "YZX") { const ac = a2 * c2, ad = a2 * d, bc = b * c2, bd = b * d; te[0] = c2 * e; te[4] = bd - ac * f; te[8] = bc * f + ad; te[1] = f; te[5] = a2 * e; te[9] = -b * 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 = b * c2, bd = b * 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] = b * 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(_zero2, q, _one2); } lookAt(eye, target, up) { const te = this.elements; _z2.subVectors(eye, target); if (_z2.lengthSq() === 0) { _z2.z = 1; } _z2.normalize(); _x2.crossVectors(up, _z2); if (_x2.lengthSq() === 0) { if (Math.abs(up.z) === 1) { _z2.x += 1e-4; } else { _z2.z += 1e-4; } _z2.normalize(); _x2.crossVectors(up, _z2); } _x2.normalize(); _y2.crossVectors(_z2, _x2); te[0] = _x2.x; te[4] = _y2.x; te[8] = _z2.x; te[1] = _x2.y; te[5] = _y2.y; te[9] = _z2.y; te[2] = _x2.z; te[6] = _y2.z; te[10] = _z2.z; return this; } multiply(m2) { return this.multiplyMatrices(this, m2); } premultiply(m2) { return this.multiplyMatrices(m2, this); } multiplyMatrices(a2, b) { const ae = a2.elements; const be = b.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 tmp2; tmp2 = te[1]; te[1] = te[4]; te[4] = tmp2; tmp2 = te[2]; te[2] = te[8]; te[8] = tmp2; tmp2 = te[6]; te[6] = te[9]; te[9] = tmp2; tmp2 = te[3]; te[3] = te[12]; te[12] = tmp2; tmp2 = te[7]; te[7] = te[13]; te[13] = tmp2; tmp2 = te[11]; te[11] = te[14]; te[14] = tmp2; return this; } setPosition(x2, y2, z2) { const te = this.elements; if (x2.isVector3) { te[12] = x2.x; te[13] = x2.y; te[14] = x2.z; } else { te[12] = x2; te[13] = y2; te[14] = z2; } 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 x2 = v.x, y2 = v.y, z2 = v.z; te[0] *= x2; te[4] *= y2; te[8] *= z2; te[1] *= x2; te[5] *= y2; te[9] *= z2; te[2] *= x2; te[6] *= y2; te[10] *= z2; te[3] *= x2; te[7] *= y2; te[11] *= z2; 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(x2, y2, z2) { if (x2.isVector3) { this.set( 1, 0, 0, x2.x, 0, 1, 0, x2.y, 0, 0, 1, x2.z, 0, 0, 0, 1 ); } else { this.set( 1, 0, 0, x2, 0, 1, 0, y2, 0, 0, 1, z2, 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 x2 = axis.x, y2 = axis.y, z2 = axis.z; const tx = t * x2, ty = t * y2; this.set( tx * x2 + c2, tx * y2 - s * z2, tx * z2 + s * y2, 0, tx * y2 + s * z2, ty * y2 + c2, ty * z2 - s * x2, 0, tx * z2 - s * y2, ty * z2 + s * x2, t * z2 * z2 + c2, 0, 0, 0, 0, 1 ); return this; } makeScale(x2, y2, z2) { this.set( x2, 0, 0, 0, 0, y2, 0, 0, 0, 0, z2, 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 x2 = quaternion._x, y2 = quaternion._y, z2 = quaternion._z, w = quaternion._w; const x22 = x2 + x2, y22 = y2 + y2, z22 = z2 + z2; const xx = x2 * x22, xy = x2 * y22, xz = x2 * z22; const yy = y2 * y22, yz = y2 * z22, zz = z2 * z22; const wx = w * x22, wy = w * y22, wz = w * z22; 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$52.set(te[0], te[1], te[2]).length(); const sy = _v1$52.set(te[4], te[5], te[6]).length(); const sz = _v1$52.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$32.copy(this); const invSX = 1 / sx; const invSY = 1 / sy; const invSZ = 1 / sz; _m1$32.elements[0] *= invSX; _m1$32.elements[1] *= invSX; _m1$32.elements[2] *= invSX; _m1$32.elements[4] *= invSY; _m1$32.elements[5] *= invSY; _m1$32.elements[6] *= invSY; _m1$32.elements[8] *= invSZ; _m1$32.elements[9] *= invSZ; _m1$32.elements[10] *= invSZ; quaternion.setFromRotationMatrix(_m1$32); scale.x = sx; scale.y = sy; scale.z = sz; return this; } makePerspective(left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem2) { const te = this.elements; const x2 = 2 * near / (right - left); const y2 = 2 * near / (top - bottom); const a2 = (right + left) / (right - left); const b = (top + bottom) / (top - bottom); let c2, d; if (coordinateSystem === WebGLCoordinateSystem2) { c2 = -(far + near) / (far - near); d = -2 * far * near / (far - near); } else if (coordinateSystem === WebGPUCoordinateSystem2) { c2 = -far / (far - near); d = -far * near / (far - near); } else { throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: " + coordinateSystem); } te[0] = x2; te[4] = 0; te[8] = a2; te[12] = 0; te[1] = 0; te[5] = y2; te[9] = b; 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, coordinateSystem = WebGLCoordinateSystem2) { const te = this.elements; const w = 1 / (right - left); const h = 1 / (top - bottom); const p = 1 / (far - near); const x2 = (right + left) * w; const y2 = (top + bottom) * h; let z2, zInv; if (coordinateSystem === WebGLCoordinateSystem2) { z2 = (far + near) * p; zInv = -2 * p; } else if (coordinateSystem === WebGPUCoordinateSystem2) { z2 = near * p; zInv = -1 * p; } else { throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: " + coordinateSystem); } te[0] = 2 * w; te[4] = 0; te[8] = 0; te[12] = -x2; te[1] = 0; te[5] = 2 * h; te[9] = 0; te[13] = -y2; te[2] = 0; te[6] = 0; te[10] = zInv; te[14] = -z2; 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; } }; var _v1$52 = /* @__PURE__ */ new Vector32(); var _m1$32 = /* @__PURE__ */ new Matrix42(); var _zero2 = /* @__PURE__ */ new Vector32(0, 0, 0); var _one2 = /* @__PURE__ */ new Vector32(1, 1, 1); var _x2 = /* @__PURE__ */ new Vector32(); var _y2 = /* @__PURE__ */ new Vector32(); var _z2 = /* @__PURE__ */ new Vector32(); var _matrix$22 = /* @__PURE__ */ new Matrix42(); var _quaternion$32 = /* @__PURE__ */ new Quaternion2(); var Euler2 = class _Euler { constructor(x2 = 0, y2 = 0, z2 = 0, order = _Euler.DEFAULT_ORDER) { this.isEuler = true; this._x = x2; this._y = y2; this._z = z2; 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(x2, y2, z2, order = this._order) { this._x = x2; this._y = y2; this._z = z2; 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(m2, order = this._order, update4 = true) { const te = m2.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$1(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$1(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$1(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$1(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$1(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$1(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 (update4 === true) this._onChangeCallback(); return this; } setFromQuaternion(q, order, update4) { _matrix$22.makeRotationFromQuaternion(q); return this.setFromRotationMatrix(_matrix$22, order, update4); } setFromVector3(v, order = this._order) { return this.set(v.x, v.y, v.z, order); } reorder(newOrder) { _quaternion$32.setFromEuler(this); return this.setFromQuaternion(_quaternion$32, 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; } _onChange(callback) { this._onChangeCallback = callback; return this; } _onChangeCallback() { } *[Symbol.iterator]() { yield this._x; yield this._y; yield this._z; yield this._order; } }; Euler2.DEFAULT_ORDER = "XYZ"; var Layers2 = class { constructor() { this.mask = 1 | 0; } set(channel) { this.mask = (1 << channel | 0) >>> 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; } isEnabled(channel) { return (this.mask & (1 << channel | 0)) !== 0; } }; var _object3DId2 = 0; var _v1$42 = /* @__PURE__ */ new Vector32(); var _q12 = /* @__PURE__ */ new Quaternion2(); var _m1$22 = /* @__PURE__ */ new Matrix42(); var _target$1 = /* @__PURE__ */ new Vector32(); var _position$32 = /* @__PURE__ */ new Vector32(); var _scale$22 = /* @__PURE__ */ new Vector32(); var _quaternion$22 = /* @__PURE__ */ new Quaternion2(); var _xAxis2 = /* @__PURE__ */ new Vector32(1, 0, 0); var _yAxis2 = /* @__PURE__ */ new Vector32(0, 1, 0); var _zAxis2 = /* @__PURE__ */ new Vector32(0, 0, 1); var _addedEvent2 = { type: "added" }; var _removedEvent2 = { type: "removed" }; var _childaddedEvent2 = { type: "childadded", child: null }; var _childremovedEvent2 = { type: "childremoved", child: null }; var Object3D2 = class _Object3D extends EventDispatcher2 { constructor() { super(); this.isObject3D = true; Object.defineProperty(this, "id", { value: _object3DId2++ }); this.uuid = generateUUID2(); this.name = ""; this.type = "Object3D"; this.parent = null; this.children = []; this.up = _Object3D.DEFAULT_UP.clone(); const position = new Vector32(); const rotation = new Euler2(); const quaternion = new Quaternion2(); const scale = new Vector32(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 Matrix42() }, normalMatrix: { value: new Matrix32() } }); this.matrix = new Matrix42(); this.matrixWorld = new Matrix42(); this.matrixAutoUpdate = _Object3D.DEFAULT_MATRIX_AUTO_UPDATE; this.matrixWorldAutoUpdate = _Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; this.matrixWorldNeedsUpdate = false; this.layers = new Layers2(); this.visible = true; this.castShadow = false; this.receiveShadow = false; this.frustumCulled = true; this.renderOrder = 0; this.animations = []; this.userData = {}; } onBeforeShadow() { } onAfterShadow() { } 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(m2) { this.quaternion.setFromRotationMatrix(m2); } setRotationFromQuaternion(q) { this.quaternion.copy(q); } rotateOnAxis(axis, angle) { _q12.setFromAxisAngle(axis, angle); this.quaternion.multiply(_q12); return this; } rotateOnWorldAxis(axis, angle) { _q12.setFromAxisAngle(axis, angle); this.quaternion.premultiply(_q12); return this; } rotateX(angle) { return this.rotateOnAxis(_xAxis2, angle); } rotateY(angle) { return this.rotateOnAxis(_yAxis2, angle); } rotateZ(angle) { return this.rotateOnAxis(_zAxis2, angle); } translateOnAxis(axis, distance2) { _v1$42.copy(axis).applyQuaternion(this.quaternion); this.position.add(_v1$42.multiplyScalar(distance2)); return this; } translateX(distance2) { return this.translateOnAxis(_xAxis2, distance2); } translateY(distance2) { return this.translateOnAxis(_yAxis2, distance2); } translateZ(distance2) { return this.translateOnAxis(_zAxis2, distance2); } localToWorld(vector) { this.updateWorldMatrix(true, false); return vector.applyMatrix4(this.matrixWorld); } worldToLocal(vector) { this.updateWorldMatrix(true, false); return vector.applyMatrix4(_m1$22.copy(this.matrixWorld).invert()); } lookAt(x2, y2, z2) { if (x2.isVector3) { _target$1.copy(x2); } else { _target$1.set(x2, y2, z2); } const parent = this.parent; this.updateWorldMatrix(true, false); _position$32.setFromMatrixPosition(this.matrixWorld); if (this.isCamera || this.isLight) { _m1$22.lookAt(_position$32, _target$1, this.up); } else { _m1$22.lookAt(_target$1, _position$32, this.up); } this.quaternion.setFromRotationMatrix(_m1$22); if (parent) { _m1$22.extractRotation(parent.matrixWorld); _q12.setFromRotationMatrix(_m1$22); this.quaternion.premultiply(_q12.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) { object.removeFromParent(); object.parent = this; this.children.push(object); object.dispatchEvent(_addedEvent2); _childaddedEvent2.child = object; this.dispatchEvent(_childaddedEvent2); _childaddedEvent2.child = null; } 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 index5 = this.children.indexOf(object); if (index5 !== -1) { object.parent = null; this.children.splice(index5, 1); object.dispatchEvent(_removedEvent2); _childremovedEvent2.child = object; this.dispatchEvent(_childremovedEvent2); _childremovedEvent2.child = null; } return this; } removeFromParent() { const parent = this.parent; if (parent !== null) { parent.remove(this); } return this; } clear() { return this.remove(...this.children); } attach(object) { this.updateWorldMatrix(true, false); _m1$22.copy(this.matrixWorld).invert(); if (object.parent !== null) { object.parent.updateWorldMatrix(true, false); _m1$22.multiply(object.parent.matrixWorld); } object.applyMatrix4(_m1$22); object.removeFromParent(); object.parent = this; this.children.push(object); object.updateWorldMatrix(false, true); object.dispatchEvent(_addedEvent2); _childaddedEvent2.child = object; this.dispatchEvent(_childaddedEvent2); _childaddedEvent2.child = null; return this; } getObjectById(id2) { return this.getObjectByProperty("id", id2); } 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; } getObjectsByProperty(name, value, result = []) { if (this[name] === value) result.push(this); const children = this.children; for (let i = 0, l = children.length; i < l; i++) { children[i].getObjectsByProperty(name, value, result); } return result; } getWorldPosition(target) { this.updateWorldMatrix(true, false); return target.setFromMatrixPosition(this.matrixWorld); } getWorldQuaternion(target) { this.updateWorldMatrix(true, false); this.matrixWorld.decompose(_position$32, target, _scale$22); return target; } getWorldScale(target) { this.updateWorldMatrix(true, false); this.matrixWorld.decompose(_position$32, _quaternion$22, 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.matrixWorldAutoUpdate === true) { 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++) { const child = children[i]; child.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.matrixWorldAutoUpdate === true) { 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++) { const child = children[i]; child.updateWorldMatrix(false, true); } } } toJSON(meta) { const isRootObject = meta === void 0 || typeof meta === "string"; const output2 = {}; if (isRootObject) { meta = { geometries: {}, materials: {}, textures: {}, images: {}, shapes: {}, skeletons: {}, animations: {}, nodes: {} }; output2.metadata = { version: 4.6, 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 (Object.keys(this.userData).length > 0) object.userData = this.userData; object.layers = this.layers.mask; object.matrix = this.matrix.toArray(); object.up = this.up.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(); } if (this.isBatchedMesh) { object.type = "BatchedMesh"; object.perObjectFrustumCulled = this.perObjectFrustumCulled; object.sortObjects = this.sortObjects; object.drawRanges = this._drawRanges; object.reservedRanges = this._reservedRanges; object.visibility = this._visibility; object.active = this._active; object.bounds = this._bounds.map((bound) => ({ boxInitialized: bound.boxInitialized, boxMin: bound.box.min.toArray(), boxMax: bound.box.max.toArray(), sphereInitialized: bound.sphereInitialized, sphereRadius: bound.sphere.radius, sphereCenter: bound.sphere.center.toArray() })); object.maxInstanceCount = this._maxInstanceCount; object.maxVertexCount = this._maxVertexCount; object.maxIndexCount = this._maxIndexCount; object.geometryInitialized = this._geometryInitialized; object.geometryCount = this._geometryCount; object.matricesTexture = this._matricesTexture.toJSON(meta); if (this._colorsTexture !== null) object.colorsTexture = this._colorsTexture.toJSON(meta); if (this.boundingSphere !== null) { object.boundingSphere = { center: object.boundingSphere.center.toArray(), radius: object.boundingSphere.radius }; } if (this.boundingBox !== null) { object.boundingBox = { min: object.boundingBox.min.toArray(), max: object.boundingBox.max.toArray() }; } } function serialize(library, element2) { if (library[element2.uuid] === void 0) { library[element2.uuid] = element2.toJSON(meta); } return element2.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 && this.environment.isRenderTargetTexture !== true) { 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); const nodes = extractFromCache(meta.nodes); if (geometries.length > 0) output2.geometries = geometries; if (materials.length > 0) output2.materials = materials; if (textures.length > 0) output2.textures = textures; if (images.length > 0) output2.images = images; if (shapes.length > 0) output2.shapes = shapes; if (skeletons.length > 0) output2.skeletons = skeletons; if (animations.length > 0) output2.animations = animations; if (nodes.length > 0) output2.nodes = nodes; } output2.object = object; return output2; function extractFromCache(cache2) { const values = []; for (const key in cache2) { const data = cache2[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.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; 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.animations = source.animations.slice(); 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; } }; Object3D2.DEFAULT_UP = /* @__PURE__ */ new Vector32(0, 1, 0); Object3D2.DEFAULT_MATRIX_AUTO_UPDATE = true; Object3D2.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true; var _v0$12 = /* @__PURE__ */ new Vector32(); var _v1$32 = /* @__PURE__ */ new Vector32(); var _v2$22 = /* @__PURE__ */ new Vector32(); var _v3$22 = /* @__PURE__ */ new Vector32(); var _vab2 = /* @__PURE__ */ new Vector32(); var _vac2 = /* @__PURE__ */ new Vector32(); var _vbc2 = /* @__PURE__ */ new Vector32(); var _vap2 = /* @__PURE__ */ new Vector32(); var _vbp2 = /* @__PURE__ */ new Vector32(); var _vcp2 = /* @__PURE__ */ new Vector32(); var _v402 = /* @__PURE__ */ new Vector42(); var _v412 = /* @__PURE__ */ new Vector42(); var _v422 = /* @__PURE__ */ new Vector42(); var Triangle2 = class _Triangle { constructor(a2 = new Vector32(), b = new Vector32(), c2 = new Vector32()) { this.a = a2; this.b = b; this.c = c2; } static getNormal(a2, b, c2, target) { target.subVectors(c2, b); _v0$12.subVectors(a2, b); target.cross(_v0$12); const targetLengthSq = target.lengthSq(); if (targetLengthSq > 0) { return target.multiplyScalar(1 / Math.sqrt(targetLengthSq)); } return target.set(0, 0, 0); } // static/instance method to calculate barycentric coordinates // based on: http://www.blackpawn.com/texts/pointinpoly/default.html static getBarycoord(point, a2, b, c2, target) { _v0$12.subVectors(c2, a2); _v1$32.subVectors(b, a2); _v2$22.subVectors(point, a2); const dot00 = _v0$12.dot(_v0$12); const dot01 = _v0$12.dot(_v1$32); const dot02 = _v0$12.dot(_v2$22); const dot11 = _v1$32.dot(_v1$32); const dot12 = _v1$32.dot(_v2$22); const denom = dot00 * dot11 - dot01 * dot01; if (denom === 0) { target.set(0, 0, 0); return null; } 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, b, c2) { if (this.getBarycoord(point, a2, b, c2, _v3$22) === null) { return false; } return _v3$22.x >= 0 && _v3$22.y >= 0 && _v3$22.x + _v3$22.y <= 1; } static getInterpolation(point, p1, p2, p3, v1, v2, v3, target) { if (this.getBarycoord(point, p1, p2, p3, _v3$22) === null) { target.x = 0; target.y = 0; if ("z" in target) target.z = 0; if ("w" in target) target.w = 0; return null; } target.setScalar(0); target.addScaledVector(v1, _v3$22.x); target.addScaledVector(v2, _v3$22.y); target.addScaledVector(v3, _v3$22.z); return target; } static getInterpolatedAttribute(attr, i1, i2, i3, barycoord, target) { _v402.setScalar(0); _v412.setScalar(0); _v422.setScalar(0); _v402.fromBufferAttribute(attr, i1); _v412.fromBufferAttribute(attr, i2); _v422.fromBufferAttribute(attr, i3); target.setScalar(0); target.addScaledVector(_v402, barycoord.x); target.addScaledVector(_v412, barycoord.y); target.addScaledVector(_v422, barycoord.z); return target; } static isFrontFacing(a2, b, c2, direction2) { _v0$12.subVectors(c2, b); _v1$32.subVectors(a2, b); return _v0$12.cross(_v1$32).dot(direction2) < 0 ? true : false; } set(a2, b, c2) { this.a.copy(a2); this.b.copy(b); 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; } setFromAttributeAndIndices(attribute2, i0, i1, i2) { this.a.fromBufferAttribute(attribute2, i0); this.b.fromBufferAttribute(attribute2, i1); this.c.fromBufferAttribute(attribute2, 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$12.subVectors(this.c, this.b); _v1$32.subVectors(this.a, this.b); return _v0$12.cross(_v1$32).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); } getInterpolation(point, v1, v2, v3, target) { return _Triangle.getInterpolation(point, this.a, this.b, this.c, v1, v2, v3, target); } containsPoint(point) { return _Triangle.containsPoint(point, this.a, this.b, this.c); } isFrontFacing(direction2) { return _Triangle.isFrontFacing(this.a, this.b, this.c, direction2); } intersectsBox(box) { return box.intersectsTriangle(this); } closestPointToPoint(p, target) { const a2 = this.a, b = this.b, c2 = this.c; let v, w; _vab2.subVectors(b, a2); _vac2.subVectors(c2, a2); _vap2.subVectors(p, a2); const d1 = _vab2.dot(_vap2); const d2 = _vac2.dot(_vap2); if (d1 <= 0 && d2 <= 0) { return target.copy(a2); } _vbp2.subVectors(p, b); const d3 = _vab2.dot(_vbp2); const d4 = _vac2.dot(_vbp2); if (d3 >= 0 && d4 <= d3) { return target.copy(b); } const vc = d1 * d4 - d3 * d2; if (vc <= 0 && d1 >= 0 && d3 <= 0) { v = d1 / (d1 - d3); return target.copy(a2).addScaledVector(_vab2, v); } _vcp2.subVectors(p, c2); const d5 = _vab2.dot(_vcp2); const d6 = _vac2.dot(_vcp2); if (d6 >= 0 && d5 <= d6) { return target.copy(c2); } const vb = d5 * d2 - d1 * d6; if (vb <= 0 && d2 >= 0 && d6 <= 0) { w = d2 / (d2 - d6); return target.copy(a2).addScaledVector(_vac2, w); } const va = d3 * d6 - d5 * d4; if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) { _vbc2.subVectors(c2, b); w = (d4 - d3) / (d4 - d3 + (d5 - d6)); return target.copy(b).addScaledVector(_vbc2, w); } const denom = 1 / (va + vb + vc); v = vb * denom; w = vc * denom; return target.copy(a2).addScaledVector(_vab2, v).addScaledVector(_vac2, w); } equals(triangle) { return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c); } }; var _colorKeywords2 = { "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 _hslA2 = { h: 0, s: 0, l: 0 }; var _hslB2 = { h: 0, s: 0, l: 0 }; function hue2rgb2(p, q, t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t); return p; } var Color2 = class { constructor(r, g, b) { this.isColor = true; this.r = 1; this.g = 1; this.b = 1; return this.set(r, g, b); } set(r, g, b) { if (g === void 0 && b === void 0) { const value = r; if (value && value.isColor) { this.copy(value); } else if (typeof value === "number") { this.setHex(value); } else if (typeof value === "string") { this.setStyle(value); } } else { this.setRGB(r, g, b); } return this; } setScalar(scalar) { this.r = scalar; this.g = scalar; this.b = scalar; return this; } setHex(hex, colorSpace = SRGBColorSpace2) { hex = Math.floor(hex); this.r = (hex >> 16 & 255) / 255; this.g = (hex >> 8 & 255) / 255; this.b = (hex & 255) / 255; ColorManagement2.toWorkingColorSpace(this, colorSpace); return this; } setRGB(r, g, b, colorSpace = ColorManagement2.workingColorSpace) { this.r = r; this.g = g; this.b = b; ColorManagement2.toWorkingColorSpace(this, colorSpace); return this; } setHSL(h, s, l, colorSpace = ColorManagement2.workingColorSpace) { h = euclideanModulo2(h, 1); s = clamp$1(s, 0, 1); l = clamp$1(l, 0, 1); if (s === 0) { this.r = this.g = this.b = l; } else { const p = l <= 0.5 ? l * (1 + s) : l + s - l * s; const q = 2 * l - p; this.r = hue2rgb2(q, p, h + 1 / 3); this.g = hue2rgb2(q, p, h); this.b = hue2rgb2(q, p, h - 1 / 3); } ColorManagement2.toWorkingColorSpace(this, colorSpace); return this; } setStyle(style, colorSpace = SRGBColorSpace2) { function handleAlpha(string) { if (string === void 0) return; if (parseFloat(string) < 1) { console.warn("THREE.Color: Alpha component of " + style + " will be ignored."); } } let m2; if (m2 = /^(\w+)\(([^\)]*)\)/.exec(style)) { let color2; const name = m2[1]; const components = m2[2]; switch (name) { case "rgb": case "rgba": if (color2 = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { handleAlpha(color2[4]); return this.setRGB( Math.min(255, parseInt(color2[1], 10)) / 255, Math.min(255, parseInt(color2[2], 10)) / 255, Math.min(255, parseInt(color2[3], 10)) / 255, colorSpace ); } if (color2 = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { handleAlpha(color2[4]); return this.setRGB( Math.min(100, parseInt(color2[1], 10)) / 100, Math.min(100, parseInt(color2[2], 10)) / 100, Math.min(100, parseInt(color2[3], 10)) / 100, colorSpace ); } break; case "hsl": case "hsla": if (color2 = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) { handleAlpha(color2[4]); return this.setHSL( parseFloat(color2[1]) / 360, parseFloat(color2[2]) / 100, parseFloat(color2[3]) / 100, colorSpace ); } break; default: console.warn("THREE.Color: Unknown color model " + style); } } else if (m2 = /^\#([A-Fa-f\d]+)$/.exec(style)) { const hex = m2[1]; const size = hex.length; if (size === 3) { return this.setRGB( parseInt(hex.charAt(0), 16) / 15, parseInt(hex.charAt(1), 16) / 15, parseInt(hex.charAt(2), 16) / 15, colorSpace ); } else if (size === 6) { return this.setHex(parseInt(hex, 16), colorSpace); } else { console.warn("THREE.Color: Invalid hex color " + style); } } else if (style && style.length > 0) { return this.setColorName(style, colorSpace); } return this; } setColorName(style, colorSpace = SRGBColorSpace2) { const hex = _colorKeywords2[style.toLowerCase()]; if (hex !== void 0) { this.setHex(hex, colorSpace); } else { console.warn("THREE.Color: Unknown color " + style); } return this; } clone() { return new this.constructor(this.r, this.g, this.b); } copy(color2) { this.r = color2.r; this.g = color2.g; this.b = color2.b; return this; } copySRGBToLinear(color2) { this.r = SRGBToLinear2(color2.r); this.g = SRGBToLinear2(color2.g); this.b = SRGBToLinear2(color2.b); return this; } copyLinearToSRGB(color2) { this.r = LinearToSRGB2(color2.r); this.g = LinearToSRGB2(color2.g); this.b = LinearToSRGB2(color2.b); return this; } convertSRGBToLinear() { this.copySRGBToLinear(this); return this; } convertLinearToSRGB() { this.copyLinearToSRGB(this); return this; } getHex(colorSpace = SRGBColorSpace2) { ColorManagement2.fromWorkingColorSpace(_color2.copy(this), colorSpace); return Math.round(clamp$1(_color2.r * 255, 0, 255)) * 65536 + Math.round(clamp$1(_color2.g * 255, 0, 255)) * 256 + Math.round(clamp$1(_color2.b * 255, 0, 255)); } getHexString(colorSpace = SRGBColorSpace2) { return ("000000" + this.getHex(colorSpace).toString(16)).slice(-6); } getHSL(target, colorSpace = ColorManagement2.workingColorSpace) { ColorManagement2.fromWorkingColorSpace(_color2.copy(this), colorSpace); const r = _color2.r, g = _color2.g, b = _color2.b; const max2 = Math.max(r, g, b); const min2 = Math.min(r, g, b); let hue, saturation; const lightness = (min2 + max2) / 2; if (min2 === max2) { hue = 0; saturation = 0; } else { const delta = max2 - min2; saturation = lightness <= 0.5 ? delta / (max2 + min2) : delta / (2 - max2 - min2); switch (max2) { case r: hue = (g - b) / delta + (g < b ? 6 : 0); break; case g: hue = (b - r) / delta + 2; break; case b: hue = (r - g) / delta + 4; break; } hue /= 6; } target.h = hue; target.s = saturation; target.l = lightness; return target; } getRGB(target, colorSpace = ColorManagement2.workingColorSpace) { ColorManagement2.fromWorkingColorSpace(_color2.copy(this), colorSpace); target.r = _color2.r; target.g = _color2.g; target.b = _color2.b; return target; } getStyle(colorSpace = SRGBColorSpace2) { ColorManagement2.fromWorkingColorSpace(_color2.copy(this), colorSpace); const r = _color2.r, g = _color2.g, b = _color2.b; if (colorSpace !== SRGBColorSpace2) { return `color(${colorSpace} ${r.toFixed(3)} ${g.toFixed(3)} ${b.toFixed(3)})`; } return `rgb(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)})`; } offsetHSL(h, s, l) { this.getHSL(_hslA2); return this.setHSL(_hslA2.h + h, _hslA2.s + s, _hslA2.l + l); } add(color2) { this.r += color2.r; this.g += color2.g; this.b += color2.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(color2) { this.r = Math.max(0, this.r - color2.r); this.g = Math.max(0, this.g - color2.g); this.b = Math.max(0, this.b - color2.b); return this; } multiply(color2) { this.r *= color2.r; this.g *= color2.g; this.b *= color2.b; return this; } multiplyScalar(s) { this.r *= s; this.g *= s; this.b *= s; return this; } lerp(color2, alpha) { this.r += (color2.r - this.r) * alpha; this.g += (color2.g - this.g) * alpha; this.b += (color2.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(color2, alpha) { this.getHSL(_hslA2); color2.getHSL(_hslB2); const h = lerp2(_hslA2.h, _hslB2.h, alpha); const s = lerp2(_hslA2.s, _hslB2.s, alpha); const l = lerp2(_hslA2.l, _hslB2.l, alpha); this.setHSL(h, s, l); return this; } setFromVector3(v) { this.r = v.x; this.g = v.y; this.b = v.z; return this; } applyMatrix3(m2) { const r = this.r, g = this.g, b = this.b; const e = m2.elements; this.r = e[0] * r + e[3] * g + e[6] * b; this.g = e[1] * r + e[4] * g + e[7] * b; this.b = e[2] * r + e[5] * g + e[8] * b; 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(attribute2, index5) { this.r = attribute2.getX(index5); this.g = attribute2.getY(index5); this.b = attribute2.getZ(index5); return this; } toJSON() { return this.getHex(); } *[Symbol.iterator]() { yield this.r; yield this.g; yield this.b; } }; var _color2 = /* @__PURE__ */ new Color2(); Color2.NAMES = _colorKeywords2; var _materialId2 = 0; var Material2 = class extends EventDispatcher2 { static get type() { return "Material"; } get type() { return this.constructor.type; } set type(_value) { } constructor() { super(); this.isMaterial = true; Object.defineProperty(this, "id", { value: _materialId2++ }); this.uuid = generateUUID2(); this.name = ""; this.blending = NormalBlending2; this.side = FrontSide2; this.vertexColors = false; this.opacity = 1; this.transparent = false; this.alphaHash = false; this.blendSrc = SrcAlphaFactor2; this.blendDst = OneMinusSrcAlphaFactor2; this.blendEquation = AddEquation2; this.blendSrcAlpha = null; this.blendDstAlpha = null; this.blendEquationAlpha = null; this.blendColor = new Color2(0, 0, 0); this.blendAlpha = 0; this.depthFunc = LessEqualDepth2; this.depthTest = true; this.depthWrite = true; this.stencilWriteMask = 255; this.stencilFunc = AlwaysStencilFunc2; this.stencilRef = 0; this.stencilFuncMask = 255; this.stencilFail = KeepStencilOp2; this.stencilZFail = KeepStencilOp2; this.stencilZPass = KeepStencilOp2; 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.forceSinglePass = 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; } // onBeforeRender and onBeforeCompile only supported in WebGLRenderer onBeforeRender() { } 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: parameter '${key}' has value of undefined.`); continue; } const currentValue = this[key]; if (currentValue === void 0) { console.warn(`THREE.Material: '${key}' is not a property of THREE.${this.type}.`); 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 isRootObject = meta === void 0 || typeof meta === "string"; if (isRootObject) { meta = { textures: {}, images: {} }; } const data = { metadata: { version: 4.6, 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.sheen !== void 0) data.sheen = this.sheen; if (this.sheenColor && this.sheenColor.isColor) data.sheenColor = this.sheenColor.getHex(); if (this.sheenRoughness !== void 0) data.sheenRoughness = this.sheenRoughness; if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex(); if (this.emissiveIntensity !== void 0 && 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.specularColor && this.specularColor.isColor) data.specularColor = this.specularColor.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.dispersion !== void 0) data.dispersion = this.dispersion; if (this.iridescence !== void 0) data.iridescence = this.iridescence; if (this.iridescenceIOR !== void 0) data.iridescenceIOR = this.iridescenceIOR; if (this.iridescenceThicknessRange !== void 0) data.iridescenceThicknessRange = this.iridescenceThicknessRange; if (this.iridescenceMap && this.iridescenceMap.isTexture) { data.iridescenceMap = this.iridescenceMap.toJSON(meta).uuid; } if (this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture) { data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON(meta).uuid; } if (this.anisotropy !== void 0) data.anisotropy = this.anisotropy; if (this.anisotropyRotation !== void 0) data.anisotropyRotation = this.anisotropyRotation; if (this.anisotropyMap && this.anisotropyMap.isTexture) { data.anisotropyMap = this.anisotropyMap.toJSON(meta).uuid; } 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.specularColorMap && this.specularColorMap.isTexture) data.specularColorMap = this.specularColorMap.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.envMapRotation !== void 0) data.envMapRotation = this.envMapRotation.toArray(); 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 && this.attenuationDistance !== Infinity) data.attenuationDistance = this.attenuationDistance; if (this.attenuationColor !== void 0) data.attenuationColor = this.attenuationColor.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 !== NormalBlending2) data.blending = this.blending; if (this.side !== FrontSide2) data.side = this.side; if (this.vertexColors === true) data.vertexColors = true; if (this.opacity < 1) data.opacity = this.opacity; if (this.transparent === true) data.transparent = true; if (this.blendSrc !== SrcAlphaFactor2) data.blendSrc = this.blendSrc; if (this.blendDst !== OneMinusSrcAlphaFactor2) data.blendDst = this.blendDst; if (this.blendEquation !== AddEquation2) data.blendEquation = this.blendEquation; if (this.blendSrcAlpha !== null) data.blendSrcAlpha = this.blendSrcAlpha; if (this.blendDstAlpha !== null) data.blendDstAlpha = this.blendDstAlpha; if (this.blendEquationAlpha !== null) data.blendEquationAlpha = this.blendEquationAlpha; if (this.blendColor && this.blendColor.isColor) data.blendColor = this.blendColor.getHex(); if (this.blendAlpha !== 0) data.blendAlpha = this.blendAlpha; if (this.depthFunc !== LessEqualDepth2) data.depthFunc = this.depthFunc; if (this.depthTest === false) data.depthTest = this.depthTest; if (this.depthWrite === false) data.depthWrite = this.depthWrite; if (this.colorWrite === false) data.colorWrite = this.colorWrite; if (this.stencilWriteMask !== 255) data.stencilWriteMask = this.stencilWriteMask; if (this.stencilFunc !== AlwaysStencilFunc2) data.stencilFunc = this.stencilFunc; if (this.stencilRef !== 0) data.stencilRef = this.stencilRef; if (this.stencilFuncMask !== 255) data.stencilFuncMask = this.stencilFuncMask; if (this.stencilFail !== KeepStencilOp2) data.stencilFail = this.stencilFail; if (this.stencilZFail !== KeepStencilOp2) data.stencilZFail = this.stencilZFail; if (this.stencilZPass !== KeepStencilOp2) data.stencilZPass = this.stencilZPass; if (this.stencilWrite === true) data.stencilWrite = this.stencilWrite; if (this.rotation !== void 0 && 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 !== void 0 && 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.alphaHash === true) data.alphaHash = true; if (this.alphaToCoverage === true) data.alphaToCoverage = true; if (this.premultipliedAlpha === true) data.premultipliedAlpha = true; if (this.forceSinglePass === true) data.forceSinglePass = true; if (this.wireframe === true) data.wireframe = true; 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 = true; if (this.visible === false) data.visible = false; if (this.toneMapped === false) data.toneMapped = false; if (this.fog === false) data.fog = false; if (Object.keys(this.userData).length > 0) data.userData = this.userData; function extractFromCache(cache2) { const values = []; for (const key in cache2) { const data2 = cache2[key]; delete data2.metadata; values.push(data2); } return values; } if (isRootObject) { 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.blending = source.blending; this.side = source.side; this.vertexColors = source.vertexColors; this.opacity = source.opacity; this.transparent = source.transparent; this.blendSrc = source.blendSrc; this.blendDst = source.blendDst; this.blendEquation = source.blendEquation; this.blendSrcAlpha = source.blendSrcAlpha; this.blendDstAlpha = source.blendDstAlpha; this.blendEquationAlpha = source.blendEquationAlpha; this.blendColor.copy(source.blendColor); this.blendAlpha = source.blendAlpha; 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.alphaHash = source.alphaHash; this.alphaToCoverage = source.alphaToCoverage; this.premultipliedAlpha = source.premultipliedAlpha; this.forceSinglePass = source.forceSinglePass; 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++; } onBuild() { console.warn("Material: onBuild() has been removed."); } }; var MeshBasicMaterial2 = class extends Material2 { static get type() { return "MeshBasicMaterial"; } constructor(parameters) { super(); this.isMeshBasicMaterial = true; this.color = new Color2(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.envMapRotation = new Euler2(); this.combine = MultiplyOperation2; this.reflectivity = 1; this.refractionRatio = 0.98; this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = "round"; this.wireframeLinejoin = "round"; this.fog = true; 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.envMapRotation.copy(source.envMapRotation); 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.fog = source.fog; return this; } }; var _tables = /* @__PURE__ */ _generateTables(); function _generateTables() { const buffer2 = new ArrayBuffer(4); const floatView = new Float32Array(buffer2); const uint32View = new Uint32Array(buffer2); const baseTable = new Uint32Array(512); const shiftTable = new Uint32Array(512); for (let i = 0; i < 256; ++i) { const e = i - 127; if (e < -27) { baseTable[i] = 0; baseTable[i | 256] = 32768; shiftTable[i] = 24; shiftTable[i | 256] = 24; } else if (e < -14) { baseTable[i] = 1024 >> -e - 14; baseTable[i | 256] = 1024 >> -e - 14 | 32768; shiftTable[i] = -e - 1; shiftTable[i | 256] = -e - 1; } else if (e <= 15) { baseTable[i] = e + 15 << 10; baseTable[i | 256] = e + 15 << 10 | 32768; shiftTable[i] = 13; shiftTable[i | 256] = 13; } else if (e < 128) { baseTable[i] = 31744; baseTable[i | 256] = 64512; shiftTable[i] = 24; shiftTable[i | 256] = 24; } else { baseTable[i] = 31744; baseTable[i | 256] = 64512; shiftTable[i] = 13; shiftTable[i | 256] = 13; } } const mantissaTable = new Uint32Array(2048); const exponentTable = new Uint32Array(64); const offsetTable = new Uint32Array(64); for (let i = 1; i < 1024; ++i) { let m2 = i << 13; let e = 0; while ((m2 & 8388608) === 0) { m2 <<= 1; e -= 8388608; } m2 &= ~8388608; e += 947912704; mantissaTable[i] = m2 | e; } for (let i = 1024; i < 2048; ++i) { mantissaTable[i] = 939524096 + (i - 1024 << 13); } for (let i = 1; i < 31; ++i) { exponentTable[i] = i << 23; } exponentTable[31] = 1199570944; exponentTable[32] = 2147483648; for (let i = 33; i < 63; ++i) { exponentTable[i] = 2147483648 + (i - 32 << 23); } exponentTable[63] = 3347054592; for (let i = 1; i < 64; ++i) { if (i !== 32) { offsetTable[i] = 1024; } } return { floatView, uint32View, baseTable, shiftTable, mantissaTable, exponentTable, offsetTable }; } function toHalfFloat(val) { if (Math.abs(val) > 65504) console.warn("THREE.DataUtils.toHalfFloat(): Value out of range."); val = clamp$1(val, -65504, 65504); _tables.floatView[0] = val; const f = _tables.uint32View[0]; const e = f >> 23 & 511; return _tables.baseTable[e] + ((f & 8388607) >> _tables.shiftTable[e]); } function fromHalfFloat(val) { const m2 = val >> 10; _tables.uint32View[0] = _tables.mantissaTable[_tables.offsetTable[m2] + (val & 1023)] + _tables.exponentTable[m2]; return _tables.floatView[0]; } var _vector$92 = /* @__PURE__ */ new Vector32(); var _vector2$12 = /* @__PURE__ */ new Vector22(); var BufferAttribute2 = class { constructor(array, itemSize, normalized = false) { if (Array.isArray(array)) { throw new TypeError("THREE.BufferAttribute: array should be a Typed Array."); } this.isBufferAttribute = true; this.name = ""; this.array = array; this.itemSize = itemSize; this.count = array !== void 0 ? array.length / itemSize : 0; this.normalized = normalized; this.usage = StaticDrawUsage2; this.updateRanges = []; this.gpuType = FloatType2; this.version = 0; } onUploadCallback() { } set needsUpdate(value) { if (value === true) this.version++; } setUsage(value) { this.usage = value; return this; } addUpdateRange(start, count) { this.updateRanges.push({ start, count }); } clearUpdateRanges() { this.updateRanges.length = 0; } 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; this.gpuType = source.gpuType; return this; } copyAt(index1, attribute2, index22) { index1 *= this.itemSize; index22 *= attribute2.itemSize; for (let i = 0, l = this.itemSize; i < l; i++) { this.array[index1 + i] = attribute2.array[index22 + i]; } return this; } copyArray(array) { this.array.set(array); return this; } applyMatrix3(m2) { if (this.itemSize === 2) { for (let i = 0, l = this.count; i < l; i++) { _vector2$12.fromBufferAttribute(this, i); _vector2$12.applyMatrix3(m2); this.setXY(i, _vector2$12.x, _vector2$12.y); } } else if (this.itemSize === 3) { for (let i = 0, l = this.count; i < l; i++) { _vector$92.fromBufferAttribute(this, i); _vector$92.applyMatrix3(m2); this.setXYZ(i, _vector$92.x, _vector$92.y, _vector$92.z); } } return this; } applyMatrix4(m2) { for (let i = 0, l = this.count; i < l; i++) { _vector$92.fromBufferAttribute(this, i); _vector$92.applyMatrix4(m2); this.setXYZ(i, _vector$92.x, _vector$92.y, _vector$92.z); } return this; } applyNormalMatrix(m2) { for (let i = 0, l = this.count; i < l; i++) { _vector$92.fromBufferAttribute(this, i); _vector$92.applyNormalMatrix(m2); this.setXYZ(i, _vector$92.x, _vector$92.y, _vector$92.z); } return this; } transformDirection(m2) { for (let i = 0, l = this.count; i < l; i++) { _vector$92.fromBufferAttribute(this, i); _vector$92.transformDirection(m2); this.setXYZ(i, _vector$92.x, _vector$92.y, _vector$92.z); } return this; } set(value, offset = 0) { this.array.set(value, offset); return this; } getComponent(index5, component) { let value = this.array[index5 * this.itemSize + component]; if (this.normalized) value = denormalize2(value, this.array); return value; } setComponent(index5, component, value) { if (this.normalized) value = normalize$1(value, this.array); this.array[index5 * this.itemSize + component] = value; return this; } getX(index5) { let x2 = this.array[index5 * this.itemSize]; if (this.normalized) x2 = denormalize2(x2, this.array); return x2; } setX(index5, x2) { if (this.normalized) x2 = normalize$1(x2, this.array); this.array[index5 * this.itemSize] = x2; return this; } getY(index5) { let y2 = this.array[index5 * this.itemSize + 1]; if (this.normalized) y2 = denormalize2(y2, this.array); return y2; } setY(index5, y2) { if (this.normalized) y2 = normalize$1(y2, this.array); this.array[index5 * this.itemSize + 1] = y2; return this; } getZ(index5) { let z2 = this.array[index5 * this.itemSize + 2]; if (this.normalized) z2 = denormalize2(z2, this.array); return z2; } setZ(index5, z2) { if (this.normalized) z2 = normalize$1(z2, this.array); this.array[index5 * this.itemSize + 2] = z2; return this; } getW(index5) { let w = this.array[index5 * this.itemSize + 3]; if (this.normalized) w = denormalize2(w, this.array); return w; } setW(index5, w) { if (this.normalized) w = normalize$1(w, this.array); this.array[index5 * this.itemSize + 3] = w; return this; } setXY(index5, x2, y2) { index5 *= this.itemSize; if (this.normalized) { x2 = normalize$1(x2, this.array); y2 = normalize$1(y2, this.array); } this.array[index5 + 0] = x2; this.array[index5 + 1] = y2; return this; } setXYZ(index5, x2, y2, z2) { index5 *= this.itemSize; if (this.normalized) { x2 = normalize$1(x2, this.array); y2 = normalize$1(y2, this.array); z2 = normalize$1(z2, this.array); } this.array[index5 + 0] = x2; this.array[index5 + 1] = y2; this.array[index5 + 2] = z2; return this; } setXYZW(index5, x2, y2, z2, w) { index5 *= this.itemSize; if (this.normalized) { x2 = normalize$1(x2, this.array); y2 = normalize$1(y2, this.array); z2 = normalize$1(z2, this.array); w = normalize$1(w, this.array); } this.array[index5 + 0] = x2; this.array[index5 + 1] = y2; this.array[index5 + 2] = z2; this.array[index5 + 3] = w; 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.from(this.array), normalized: this.normalized }; if (this.name !== "") data.name = this.name; if (this.usage !== StaticDrawUsage2) data.usage = this.usage; return data; } }; var Uint16BufferAttribute2 = class extends BufferAttribute2 { constructor(array, itemSize, normalized) { super(new Uint16Array(array), itemSize, normalized); } }; var Uint32BufferAttribute2 = class extends BufferAttribute2 { constructor(array, itemSize, normalized) { super(new Uint32Array(array), itemSize, normalized); } }; var Float16BufferAttribute = class extends BufferAttribute2 { constructor(array, itemSize, normalized) { super(new Uint16Array(array), itemSize, normalized); this.isFloat16BufferAttribute = true; } getX(index5) { let x2 = fromHalfFloat(this.array[index5 * this.itemSize]); if (this.normalized) x2 = denormalize2(x2, this.array); return x2; } setX(index5, x2) { if (this.normalized) x2 = normalize$1(x2, this.array); this.array[index5 * this.itemSize] = toHalfFloat(x2); return this; } getY(index5) { let y2 = fromHalfFloat(this.array[index5 * this.itemSize + 1]); if (this.normalized) y2 = denormalize2(y2, this.array); return y2; } setY(index5, y2) { if (this.normalized) y2 = normalize$1(y2, this.array); this.array[index5 * this.itemSize + 1] = toHalfFloat(y2); return this; } getZ(index5) { let z2 = fromHalfFloat(this.array[index5 * this.itemSize + 2]); if (this.normalized) z2 = denormalize2(z2, this.array); return z2; } setZ(index5, z2) { if (this.normalized) z2 = normalize$1(z2, this.array); this.array[index5 * this.itemSize + 2] = toHalfFloat(z2); return this; } getW(index5) { let w = fromHalfFloat(this.array[index5 * this.itemSize + 3]); if (this.normalized) w = denormalize2(w, this.array); return w; } setW(index5, w) { if (this.normalized) w = normalize$1(w, this.array); this.array[index5 * this.itemSize + 3] = toHalfFloat(w); return this; } setXY(index5, x2, y2) { index5 *= this.itemSize; if (this.normalized) { x2 = normalize$1(x2, this.array); y2 = normalize$1(y2, this.array); } this.array[index5 + 0] = toHalfFloat(x2); this.array[index5 + 1] = toHalfFloat(y2); return this; } setXYZ(index5, x2, y2, z2) { index5 *= this.itemSize; if (this.normalized) { x2 = normalize$1(x2, this.array); y2 = normalize$1(y2, this.array); z2 = normalize$1(z2, this.array); } this.array[index5 + 0] = toHalfFloat(x2); this.array[index5 + 1] = toHalfFloat(y2); this.array[index5 + 2] = toHalfFloat(z2); return this; } setXYZW(index5, x2, y2, z2, w) { index5 *= this.itemSize; if (this.normalized) { x2 = normalize$1(x2, this.array); y2 = normalize$1(y2, this.array); z2 = normalize$1(z2, this.array); w = normalize$1(w, this.array); } this.array[index5 + 0] = toHalfFloat(x2); this.array[index5 + 1] = toHalfFloat(y2); this.array[index5 + 2] = toHalfFloat(z2); this.array[index5 + 3] = toHalfFloat(w); return this; } }; var Float32BufferAttribute2 = class extends BufferAttribute2 { constructor(array, itemSize, normalized) { super(new Float32Array(array), itemSize, normalized); } }; var _id$9 = 0; var _m1$12 = /* @__PURE__ */ new Matrix42(); var _obj2 = /* @__PURE__ */ new Object3D2(); var _offset3 = /* @__PURE__ */ new Vector32(); var _box$22 = /* @__PURE__ */ new Box32(); var _boxMorphTargets2 = /* @__PURE__ */ new Box32(); var _vector$82 = /* @__PURE__ */ new Vector32(); var BufferGeometry2 = class _BufferGeometry extends EventDispatcher2 { constructor() { super(); this.isBufferGeometry = true; Object.defineProperty(this, "id", { value: _id$9++ }); this.uuid = generateUUID2(); this.name = ""; this.type = "BufferGeometry"; this.index = null; this.indirect = 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(index5) { if (Array.isArray(index5)) { this.index = new (arrayNeedsUint32$1(index5) ? Uint32BufferAttribute2 : Uint16BufferAttribute2)(index5, 1); } else { this.index = index5; } return this; } setIndirect(indirect) { this.indirect = indirect; return this; } getIndirect() { return this.indirect; } getAttribute(name) { return this.attributes[name]; } setAttribute(name, attribute2) { this.attributes[name] = attribute2; 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 normal2 = this.attributes.normal; if (normal2 !== void 0) { const normalMatrix = new Matrix32().getNormalMatrix(matrix); normal2.applyNormalMatrix(normalMatrix); normal2.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$12.makeRotationFromQuaternion(q); this.applyMatrix4(_m1$12); return this; } rotateX(angle) { _m1$12.makeRotationX(angle); this.applyMatrix4(_m1$12); return this; } rotateY(angle) { _m1$12.makeRotationY(angle); this.applyMatrix4(_m1$12); return this; } rotateZ(angle) { _m1$12.makeRotationZ(angle); this.applyMatrix4(_m1$12); return this; } translate(x2, y2, z2) { _m1$12.makeTranslation(x2, y2, z2); this.applyMatrix4(_m1$12); return this; } scale(x2, y2, z2) { _m1$12.makeScale(x2, y2, z2); this.applyMatrix4(_m1$12); return this; } lookAt(vector) { _obj2.lookAt(vector); _obj2.updateMatrix(); this.applyMatrix4(_obj2.matrix); return this; } center() { this.computeBoundingBox(); this.boundingBox.getCenter(_offset3).negate(); this.translate(_offset3.x, _offset3.y, _offset3.z); return this; } setFromPoints(points) { const positionAttribute = this.getAttribute("position"); if (positionAttribute === void 0) { 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 Float32BufferAttribute2(position, 3)); } else { for (let i = 0, l = positionAttribute.count; i < l; i++) { const point = points[i]; positionAttribute.setXYZ(i, point.x, point.y, point.z || 0); } if (points.length > positionAttribute.count) { console.warn("THREE.BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry."); } positionAttribute.needsUpdate = true; } return this; } computeBoundingBox() { if (this.boundingBox === null) { this.boundingBox = new Box32(); } 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.", this); this.boundingBox.set( new Vector32(-Infinity, -Infinity, -Infinity), new Vector32(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$22.setFromBufferAttribute(morphAttribute); if (this.morphTargetsRelative) { _vector$82.addVectors(this.boundingBox.min, _box$22.min); this.boundingBox.expandByPoint(_vector$82); _vector$82.addVectors(this.boundingBox.max, _box$22.max); this.boundingBox.expandByPoint(_vector$82); } else { this.boundingBox.expandByPoint(_box$22.min); this.boundingBox.expandByPoint(_box$22.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 Sphere2(); } 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.", this); this.boundingSphere.set(new Vector32(), Infinity); return; } if (position) { const center = this.boundingSphere.center; _box$22.setFromBufferAttribute(position); if (morphAttributesPosition) { for (let i = 0, il = morphAttributesPosition.length; i < il; i++) { const morphAttribute = morphAttributesPosition[i]; _boxMorphTargets2.setFromBufferAttribute(morphAttribute); if (this.morphTargetsRelative) { _vector$82.addVectors(_box$22.min, _boxMorphTargets2.min); _box$22.expandByPoint(_vector$82); _vector$82.addVectors(_box$22.max, _boxMorphTargets2.max); _box$22.expandByPoint(_vector$82); } else { _box$22.expandByPoint(_boxMorphTargets2.min); _box$22.expandByPoint(_boxMorphTargets2.max); } } } _box$22.getCenter(center); let maxRadiusSq = 0; for (let i = 0, il = position.count; i < il; i++) { _vector$82.fromBufferAttribute(position, i); maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$82)); } 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$82.fromBufferAttribute(morphAttribute, j); if (morphTargetsRelative) { _offset3.fromBufferAttribute(position, j); _vector$82.add(_offset3); } maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$82)); } } } 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 index5 = this.index; const attributes = this.attributes; if (index5 === 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 positionAttribute = attributes.position; const normalAttribute = attributes.normal; const uvAttribute = attributes.uv; if (this.hasAttribute("tangent") === false) { this.setAttribute("tangent", new BufferAttribute2(new Float32Array(4 * positionAttribute.count), 4)); } const tangentAttribute = this.getAttribute("tangent"); const tan1 = [], tan2 = []; for (let i = 0; i < positionAttribute.count; i++) { tan1[i] = new Vector32(); tan2[i] = new Vector32(); } const vA = new Vector32(), vB = new Vector32(), vC = new Vector32(), uvA = new Vector22(), uvB = new Vector22(), uvC = new Vector22(), sdir = new Vector32(), tdir = new Vector32(); function handleTriangle(a2, b, c2) { vA.fromBufferAttribute(positionAttribute, a2); vB.fromBufferAttribute(positionAttribute, b); vC.fromBufferAttribute(positionAttribute, c2); uvA.fromBufferAttribute(uvAttribute, a2); uvB.fromBufferAttribute(uvAttribute, b); uvC.fromBufferAttribute(uvAttribute, c2); 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[b].add(sdir); tan1[c2].add(sdir); tan2[a2].add(tdir); tan2[b].add(tdir); tan2[c2].add(tdir); } let groups = this.groups; if (groups.length === 0) { groups = [{ start: 0, count: index5.count }]; } 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( index5.getX(j + 0), index5.getX(j + 1), index5.getX(j + 2) ); } } const tmp2 = new Vector32(), tmp22 = new Vector32(); const n = new Vector32(), n2 = new Vector32(); function handleVertex(v) { n.fromBufferAttribute(normalAttribute, v); n2.copy(n); const t = tan1[v]; tmp2.copy(t); tmp2.sub(n.multiplyScalar(n.dot(t))).normalize(); tmp22.crossVectors(n2, t); const test = tmp22.dot(tan2[v]); const w = test < 0 ? -1 : 1; tangentAttribute.setXYZW(v, tmp2.x, tmp2.y, tmp2.z, w); } 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(index5.getX(j + 0)); handleVertex(index5.getX(j + 1)); handleVertex(index5.getX(j + 2)); } } } computeVertexNormals() { const index5 = this.index; const positionAttribute = this.getAttribute("position"); if (positionAttribute !== void 0) { let normalAttribute = this.getAttribute("normal"); if (normalAttribute === void 0) { normalAttribute = new BufferAttribute2(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 Vector32(), pB = new Vector32(), pC = new Vector32(); const nA = new Vector32(), nB = new Vector32(), nC = new Vector32(); const cb = new Vector32(), ab = new Vector32(); if (index5) { for (let i = 0, il = index5.count; i < il; i += 3) { const vA = index5.getX(i + 0); const vB = index5.getX(i + 1); const vC = index5.getX(i + 2); pA.fromBufferAttribute(positionAttribute, vA); pB.fromBufferAttribute(positionAttribute, vB); pC.fromBufferAttribute(positionAttribute, vC); cb.subVectors(pC, pB); ab.subVectors(pA, pB); cb.cross(ab); nA.fromBufferAttribute(normalAttribute, vA); nB.fromBufferAttribute(normalAttribute, vB); nC.fromBufferAttribute(normalAttribute, vC); nA.add(cb); nB.add(cb); nC.add(cb); 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); cb.subVectors(pC, pB); ab.subVectors(pA, pB); cb.cross(ab); normalAttribute.setXYZ(i + 0, cb.x, cb.y, cb.z); normalAttribute.setXYZ(i + 1, cb.x, cb.y, cb.z); normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z); } } this.normalizeNormals(); normalAttribute.needsUpdate = true; } } normalizeNormals() { const normals = this.attributes.normal; for (let i = 0, il = normals.count; i < il; i++) { _vector$82.fromBufferAttribute(normals, i); _vector$82.normalize(); normals.setXYZ(i, _vector$82.x, _vector$82.y, _vector$82.z); } } toNonIndexed() { function convertBufferAttribute(attribute2, indices2) { const array = attribute2.array; const itemSize = attribute2.itemSize; const normalized = attribute2.normalized; const array2 = new array.constructor(indices2.length * itemSize); let index5 = 0, index22 = 0; for (let i = 0, l = indices2.length; i < l; i++) { if (attribute2.isInterleavedBufferAttribute) { index5 = indices2[i] * attribute2.data.stride + attribute2.offset; } else { index5 = indices2[i] * itemSize; } for (let j = 0; j < itemSize; j++) { array2[index22++] = array[index5++]; } } return new BufferAttribute2(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 attribute2 = attributes[name]; const newAttribute = convertBufferAttribute(attribute2, 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 attribute2 = morphAttribute[i]; const newAttribute = convertBufferAttribute(attribute2, 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.6, 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 index5 = this.index; if (index5 !== null) { data.data.index = { type: index5.array.constructor.name, array: Array.prototype.slice.call(index5.array) }; } const attributes = this.attributes; for (const key in attributes) { const attribute2 = attributes[key]; data.data.attributes[key] = attribute2.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 attribute2 = attributeArray[i]; array.push(attribute2.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 this.constructor().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 index5 = source.index; if (index5 !== null) { this.setIndex(index5.clone(data)); } const attributes = source.attributes; for (const name in attributes) { const attribute2 = attributes[name]; this.setAttribute(name, attribute2.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" }); } }; var _inverseMatrix$32 = /* @__PURE__ */ new Matrix42(); var _ray$32 = /* @__PURE__ */ new Ray2(); var _sphere$62 = /* @__PURE__ */ new Sphere2(); var _sphereHitAt2 = /* @__PURE__ */ new Vector32(); var _vA$12 = /* @__PURE__ */ new Vector32(); var _vB$12 = /* @__PURE__ */ new Vector32(); var _vC$12 = /* @__PURE__ */ new Vector32(); var _tempA2 = /* @__PURE__ */ new Vector32(); var _morphA2 = /* @__PURE__ */ new Vector32(); var _intersectionPoint2 = /* @__PURE__ */ new Vector32(); var _intersectionPointWorld2 = /* @__PURE__ */ new Vector32(); var Mesh2 = class extends Object3D2 { constructor(geometry = new BufferGeometry2(), material = new MeshBasicMaterial2()) { super(); this.isMesh = true; this.type = "Mesh"; this.geometry = geometry; this.material = material; this.updateMorphTargets(); } copy(source, recursive) { super.copy(source, recursive); if (source.morphTargetInfluences !== void 0) { this.morphTargetInfluences = source.morphTargetInfluences.slice(); } if (source.morphTargetDictionary !== void 0) { this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary); } this.material = Array.isArray(source.material) ? source.material.slice() : source.material; this.geometry = source.geometry; return this; } updateMorphTargets() { const geometry = this.geometry; 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 m2 = 0, ml = morphAttribute.length; m2 < ml; m2++) { const name = morphAttribute[m2].name || String(m2); this.morphTargetInfluences.push(0); this.morphTargetDictionary[name] = m2; } } } } getVertexPosition(index5, target) { const geometry = this.geometry; const position = geometry.attributes.position; const morphPosition = geometry.morphAttributes.position; const morphTargetsRelative = geometry.morphTargetsRelative; target.fromBufferAttribute(position, index5); const morphInfluences = this.morphTargetInfluences; if (morphPosition && morphInfluences) { _morphA2.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; _tempA2.fromBufferAttribute(morphAttribute, index5); if (morphTargetsRelative) { _morphA2.addScaledVector(_tempA2, influence); } else { _morphA2.addScaledVector(_tempA2.sub(target), influence); } } target.add(_morphA2); } return target; } raycast(raycaster, intersects) { const geometry = this.geometry; const material = this.material; const matrixWorld = this.matrixWorld; if (material === void 0) return; if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$62.copy(geometry.boundingSphere); _sphere$62.applyMatrix4(matrixWorld); _ray$32.copy(raycaster.ray).recast(raycaster.near); if (_sphere$62.containsPoint(_ray$32.origin) === false) { if (_ray$32.intersectSphere(_sphere$62, _sphereHitAt2) === null) return; if (_ray$32.origin.distanceToSquared(_sphereHitAt2) > (raycaster.far - raycaster.near) ** 2) return; } _inverseMatrix$32.copy(matrixWorld).invert(); _ray$32.copy(raycaster.ray).applyMatrix4(_inverseMatrix$32); if (geometry.boundingBox !== null) { if (_ray$32.intersectsBox(geometry.boundingBox) === false) return; } this._computeIntersections(raycaster, intersects, _ray$32); } _computeIntersections(raycaster, intersects, rayLocalSpace) { let intersection; const geometry = this.geometry; const material = this.material; const index5 = geometry.index; const position = geometry.attributes.position; const uv2 = geometry.attributes.uv; const uv1 = geometry.attributes.uv1; const normal2 = geometry.attributes.normal; const groups = geometry.groups; const drawRange = geometry.drawRange; if (index5 !== 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(index5.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); for (let j = start, jl = end; j < jl; j += 3) { const a2 = index5.getX(j); const b = index5.getX(j + 1); const c2 = index5.getX(j + 2); intersection = checkGeometryIntersection2(this, groupMaterial, raycaster, rayLocalSpace, uv2, uv1, normal2, a2, b, c2); if (intersection) { intersection.faceIndex = Math.floor(j / 3); intersection.face.materialIndex = group.materialIndex; intersects.push(intersection); } } } } else { const start = Math.max(0, drawRange.start); const end = Math.min(index5.count, drawRange.start + drawRange.count); for (let i = start, il = end; i < il; i += 3) { const a2 = index5.getX(i); const b = index5.getX(i + 1); const c2 = index5.getX(i + 2); intersection = checkGeometryIntersection2(this, material, raycaster, rayLocalSpace, uv2, uv1, normal2, a2, b, c2); if (intersection) { intersection.faceIndex = Math.floor(i / 3); intersects.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(position.count, Math.min(group.start + group.count, drawRange.start + drawRange.count)); for (let j = start, jl = end; j < jl; j += 3) { const a2 = j; const b = j + 1; const c2 = j + 2; intersection = checkGeometryIntersection2(this, groupMaterial, raycaster, rayLocalSpace, uv2, uv1, normal2, a2, b, c2); if (intersection) { intersection.faceIndex = Math.floor(j / 3); intersection.face.materialIndex = group.materialIndex; intersects.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 b = i + 1; const c2 = i + 2; intersection = checkGeometryIntersection2(this, material, raycaster, rayLocalSpace, uv2, uv1, normal2, a2, b, c2); if (intersection) { intersection.faceIndex = Math.floor(i / 3); intersects.push(intersection); } } } } } }; function checkIntersection$12(object, material, raycaster, ray, pA, pB, pC, point) { let intersect2; if (material.side === BackSide2) { intersect2 = ray.intersectTriangle(pC, pB, pA, true, point); } else { intersect2 = ray.intersectTriangle(pA, pB, pC, material.side === FrontSide2, point); } if (intersect2 === null) return null; _intersectionPointWorld2.copy(point); _intersectionPointWorld2.applyMatrix4(object.matrixWorld); const distance2 = raycaster.ray.origin.distanceTo(_intersectionPointWorld2); if (distance2 < raycaster.near || distance2 > raycaster.far) return null; return { distance: distance2, point: _intersectionPointWorld2.clone(), object }; } function checkGeometryIntersection2(object, material, raycaster, ray, uv2, uv1, normal2, a2, b, c2) { object.getVertexPosition(a2, _vA$12); object.getVertexPosition(b, _vB$12); object.getVertexPosition(c2, _vC$12); const intersection = checkIntersection$12(object, material, raycaster, ray, _vA$12, _vB$12, _vC$12, _intersectionPoint2); if (intersection) { const barycoord = new Vector32(); Triangle2.getBarycoord(_intersectionPoint2, _vA$12, _vB$12, _vC$12, barycoord); if (uv2) { intersection.uv = Triangle2.getInterpolatedAttribute(uv2, a2, b, c2, barycoord, new Vector22()); } if (uv1) { intersection.uv1 = Triangle2.getInterpolatedAttribute(uv1, a2, b, c2, barycoord, new Vector22()); } if (normal2) { intersection.normal = Triangle2.getInterpolatedAttribute(normal2, a2, b, c2, barycoord, new Vector32()); if (intersection.normal.dot(ray.direction) > 0) { intersection.normal.multiplyScalar(-1); } } const face = { a: a2, b, c: c2, normal: new Vector32(), materialIndex: 0 }; Triangle2.getNormal(_vA$12, _vB$12, _vC$12, face.normal); intersection.face = face; intersection.barycoord = barycoord; } return intersection; } var BoxGeometry2 = class _BoxGeometry extends BufferGeometry2 { constructor(width = 1, height = 1, depth2 = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) { super(); this.type = "BoxGeometry"; this.parameters = { width, height, depth: depth2, 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, depth2, height, width, depthSegments, heightSegments, 0); buildPlane("z", "y", "x", 1, -1, depth2, height, -width, depthSegments, heightSegments, 1); buildPlane("x", "z", "y", 1, 1, width, depth2, height, widthSegments, depthSegments, 2); buildPlane("x", "z", "y", 1, -1, width, depth2, -height, widthSegments, depthSegments, 3); buildPlane("x", "y", "z", 1, -1, width, height, depth2, widthSegments, heightSegments, 4); buildPlane("x", "y", "z", -1, -1, width, height, -depth2, widthSegments, heightSegments, 5); this.setIndex(indices); this.setAttribute("position", new Float32BufferAttribute2(vertices, 3)); this.setAttribute("normal", new Float32BufferAttribute2(normals, 3)); this.setAttribute("uv", new Float32BufferAttribute2(uvs, 2)); function buildPlane(u, v, w, udir, vdir, width2, height2, depth3, gridX, gridY, materialIndex) { const segmentWidth = width2 / gridX; const segmentHeight = height2 / gridY; const widthHalf = width2 / 2; const heightHalf = height2 / 2; const depthHalf = depth3 / 2; const gridX1 = gridX + 1; const gridY1 = gridY + 1; let vertexCounter = 0; let groupCount = 0; const vector = new Vector32(); for (let iy = 0; iy < gridY1; iy++) { const y2 = iy * segmentHeight - heightHalf; for (let ix = 0; ix < gridX1; ix++) { const x2 = ix * segmentWidth - widthHalf; vector[u] = x2 * udir; vector[v] = y2 * vdir; vector[w] = depthHalf; vertices.push(vector.x, vector.y, vector.z); vector[u] = 0; vector[v] = 0; vector[w] = depth3 > 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 b = numberOfVertices + ix + gridX1 * (iy + 1); const c2 = numberOfVertices + (ix + 1) + gridX1 * (iy + 1); const d = numberOfVertices + (ix + 1) + gridX1 * iy; indices.push(a2, b, d); indices.push(b, c2, d); groupCount += 6; } } scope.addGroup(groupStart, groupCount, materialIndex); groupStart += groupCount; numberOfVertices += vertexCounter; } } copy(source) { super.copy(source); this.parameters = Object.assign({}, source.parameters); return this; } static fromJSON(data) { return new _BoxGeometry(data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments); } }; function cloneUniforms2(src) { const dst = {}; for (const u in src) { dst[u] = {}; for (const p in src[u]) { const property2 = src[u][p]; if (property2 && (property2.isColor || property2.isMatrix3 || property2.isMatrix4 || property2.isVector2 || property2.isVector3 || property2.isVector4 || property2.isTexture || property2.isQuaternion)) { if (property2.isRenderTargetTexture) { console.warn("UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms()."); dst[u][p] = null; } else { dst[u][p] = property2.clone(); } } else if (Array.isArray(property2)) { dst[u][p] = property2.slice(); } else { dst[u][p] = property2; } } } return dst; } function cloneUniformsGroups2(src) { const dst = []; for (let u = 0; u < src.length; u++) { dst.push(src[u].clone()); } return dst; } var default_vertex2 = ( /* glsl */ ` void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } ` ); var default_fragment2 = ( /* glsl */ ` void main() { gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); } ` ); var ShaderMaterial2 = class extends Material2 { static get type() { return "ShaderMaterial"; } constructor(parameters) { super(); this.isShaderMaterial = true; this.defines = {}; this.uniforms = {}; this.uniformsGroups = []; this.vertexShader = default_vertex2; this.fragmentShader = default_fragment2; this.linewidth = 1; this.wireframe = false; this.wireframeLinewidth = 1; this.fog = false; this.lights = false; this.clipping = false; this.forceSinglePass = true; this.extensions = { clipCullDistance: false, // set to use vertex shader clipping multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID }; this.defaultAttributeValues = { "color": [1, 1, 1], "uv": [0, 0], "uv1": [0, 0] }; this.index0AttributeName = void 0; this.uniformsNeedUpdate = false; this.glslVersion = null; if (parameters !== void 0) { this.setValues(parameters); } } copy(source) { super.copy(source); this.fragmentShader = source.fragmentShader; this.vertexShader = source.vertexShader; this.uniforms = cloneUniforms2(source.uniforms); this.uniformsGroups = cloneUniformsGroups2(source.uniformsGroups); this.defines = Object.assign({}, source.defines); this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; this.fog = source.fog; 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 uniform2 = this.uniforms[name]; const value = uniform2.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; data.lights = this.lights; data.clipping = this.clipping; 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; } }; var Camera2 = class extends Object3D2 { constructor() { super(); this.isCamera = true; this.type = "Camera"; this.matrixWorldInverse = new Matrix42(); this.projectionMatrix = new Matrix42(); this.projectionMatrixInverse = new Matrix42(); this.coordinateSystem = WebGLCoordinateSystem2; } copy(source, recursive) { super.copy(source, recursive); this.matrixWorldInverse.copy(source.matrixWorldInverse); this.projectionMatrix.copy(source.projectionMatrix); this.projectionMatrixInverse.copy(source.projectionMatrixInverse); this.coordinateSystem = source.coordinateSystem; return this; } getWorldDirection(target) { return super.getWorldDirection(target).negate(); } 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); } }; var _v3$12 = /* @__PURE__ */ new Vector32(); var _minTarget2 = /* @__PURE__ */ new Vector22(); var _maxTarget2 = /* @__PURE__ */ new Vector22(); var PerspectiveCamera2 = class extends Camera2 { constructor(fov3 = 50, aspect3 = 1, near = 0.1, far = 2e3) { super(); this.isPerspectiveCamera = true; this.type = "PerspectiveCamera"; this.fov = fov3; this.zoom = 1; this.near = near; this.far = far; this.focus = 10; this.aspect = aspect3; 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; } /** * Sets the FOV by focal length in respect to the current .filmGauge. * * The default film gauge is 35, so that the focal length can be specified for * a 35mm (full frame) camera. * * Values for focal length and film gauge must have the same unit. */ setFocalLength(focalLength) { const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; this.fov = RAD2DEG2 * 2 * Math.atan(vExtentSlope); this.updateProjectionMatrix(); } /** * Calculates the focal length from the current .fov and .filmGauge. */ getFocalLength() { const vExtentSlope = Math.tan(DEG2RAD2 * 0.5 * this.fov); return 0.5 * this.getFilmHeight() / vExtentSlope; } getEffectiveFOV() { return RAD2DEG2 * 2 * Math.atan( Math.tan(DEG2RAD2 * 0.5 * this.fov) / this.zoom ); } getFilmWidth() { return this.filmGauge * Math.min(this.aspect, 1); } getFilmHeight() { return this.filmGauge / Math.max(this.aspect, 1); } /** * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. * Sets minTarget and maxTarget to the coordinates of the lower-left and upper-right corners of the view rectangle. */ getViewBounds(distance2, minTarget, maxTarget) { _v3$12.set(-1, -1, 0.5).applyMatrix4(this.projectionMatrixInverse); minTarget.set(_v3$12.x, _v3$12.y).multiplyScalar(-distance2 / _v3$12.z); _v3$12.set(1, 1, 0.5).applyMatrix4(this.projectionMatrixInverse); maxTarget.set(_v3$12.x, _v3$12.y).multiplyScalar(-distance2 / _v3$12.z); } /** * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. * Copies the result into the target Vector2, where x is width and y is height. */ getViewSize(distance2, target) { this.getViewBounds(distance2, _minTarget2, _maxTarget2); return target.subVectors(_maxTarget2, _minTarget2); } /** * Sets an offset in a larger frustum. This is useful for multi-window or * multi-monitor/multi-machine setups. * * For example, if you have 3x2 monitors and each monitor is 1920x1080 and * the monitors are in grid like this * * +---+---+---+ * | A | B | C | * +---+---+---+ * | D | E | F | * +---+---+---+ * * then for each monitor you would call it like this * * const w = 1920; * const h = 1080; * const fullWidth = w * 3; * const fullHeight = h * 2; * * --A-- * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); * --B-- * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); * --C-- * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); * --D-- * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); * --E-- * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); * --F-- * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); * * Note there is no reason monitors have to be the same size or in a grid. */ setViewOffset(fullWidth, fullHeight, x2, y2, 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 = x2; this.view.offsetY = y2; 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(DEG2RAD2 * 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.coordinateSystem); 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; } }; var fov2 = -90; var aspect2 = 1; var CubeCamera2 = class extends Object3D2 { constructor(near, far, renderTarget) { super(); this.type = "CubeCamera"; this.renderTarget = renderTarget; this.coordinateSystem = null; this.activeMipmapLevel = 0; const cameraPX = new PerspectiveCamera2(fov2, aspect2, near, far); cameraPX.layers = this.layers; this.add(cameraPX); const cameraNX = new PerspectiveCamera2(fov2, aspect2, near, far); cameraNX.layers = this.layers; this.add(cameraNX); const cameraPY = new PerspectiveCamera2(fov2, aspect2, near, far); cameraPY.layers = this.layers; this.add(cameraPY); const cameraNY = new PerspectiveCamera2(fov2, aspect2, near, far); cameraNY.layers = this.layers; this.add(cameraNY); const cameraPZ = new PerspectiveCamera2(fov2, aspect2, near, far); cameraPZ.layers = this.layers; this.add(cameraPZ); const cameraNZ = new PerspectiveCamera2(fov2, aspect2, near, far); cameraNZ.layers = this.layers; this.add(cameraNZ); } updateCoordinateSystem() { const coordinateSystem = this.coordinateSystem; const cameras = this.children.concat(); const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = cameras; for (const camera3 of cameras) this.remove(camera3); if (coordinateSystem === WebGLCoordinateSystem2) { cameraPX.up.set(0, 1, 0); cameraPX.lookAt(1, 0, 0); cameraNX.up.set(0, 1, 0); cameraNX.lookAt(-1, 0, 0); cameraPY.up.set(0, 0, -1); cameraPY.lookAt(0, 1, 0); cameraNY.up.set(0, 0, 1); cameraNY.lookAt(0, -1, 0); cameraPZ.up.set(0, 1, 0); cameraPZ.lookAt(0, 0, 1); cameraNZ.up.set(0, 1, 0); cameraNZ.lookAt(0, 0, -1); } else if (coordinateSystem === WebGPUCoordinateSystem2) { cameraPX.up.set(0, -1, 0); cameraPX.lookAt(-1, 0, 0); cameraNX.up.set(0, -1, 0); cameraNX.lookAt(1, 0, 0); cameraPY.up.set(0, 0, 1); cameraPY.lookAt(0, 1, 0); cameraNY.up.set(0, 0, -1); cameraNY.lookAt(0, -1, 0); cameraPZ.up.set(0, -1, 0); cameraPZ.lookAt(0, 0, 1); cameraNZ.up.set(0, -1, 0); cameraNZ.lookAt(0, 0, -1); } else { throw new Error("THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: " + coordinateSystem); } for (const camera3 of cameras) { this.add(camera3); camera3.updateMatrixWorld(); } } update(renderer3, scene3) { if (this.parent === null) this.updateMatrixWorld(); const { renderTarget, activeMipmapLevel } = this; if (this.coordinateSystem !== renderer3.coordinateSystem) { this.coordinateSystem = renderer3.coordinateSystem; this.updateCoordinateSystem(); } const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = this.children; const currentRenderTarget = renderer3.getRenderTarget(); const currentActiveCubeFace = renderer3.getActiveCubeFace(); const currentActiveMipmapLevel = renderer3.getActiveMipmapLevel(); const currentXrEnabled = renderer3.xr.enabled; renderer3.xr.enabled = false; const generateMipmaps = renderTarget.texture.generateMipmaps; renderTarget.texture.generateMipmaps = false; renderer3.setRenderTarget(renderTarget, 0, activeMipmapLevel); renderer3.render(scene3, cameraPX); renderer3.setRenderTarget(renderTarget, 1, activeMipmapLevel); renderer3.render(scene3, cameraNX); renderer3.setRenderTarget(renderTarget, 2, activeMipmapLevel); renderer3.render(scene3, cameraPY); renderer3.setRenderTarget(renderTarget, 3, activeMipmapLevel); renderer3.render(scene3, cameraNY); renderer3.setRenderTarget(renderTarget, 4, activeMipmapLevel); renderer3.render(scene3, cameraPZ); renderTarget.texture.generateMipmaps = generateMipmaps; renderer3.setRenderTarget(renderTarget, 5, activeMipmapLevel); renderer3.render(scene3, cameraNZ); renderer3.setRenderTarget(currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel); renderer3.xr.enabled = currentXrEnabled; renderTarget.texture.needsPMREMUpdate = true; } }; var CubeTexture2 = class extends Texture2 { constructor(images, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy2, colorSpace) { images = images !== void 0 ? images : []; mapping = mapping !== void 0 ? mapping : CubeReflectionMapping2; super(images, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy2, colorSpace); this.isCubeTexture = true; this.flipY = false; } get images() { return this.image; } set images(value) { this.image = value; } }; var WebGLCubeRenderTarget2 = class extends WebGLRenderTarget2 { constructor(size = 1, options = {}) { super(size, size, options); this.isWebGLCubeRenderTarget = true; const image = { width: size, height: size, depth: 1 }; const images = [image, image, image, image, image, image]; this.texture = new CubeTexture2(images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.colorSpace); this.texture.isRenderTargetTexture = true; this.texture.generateMipmaps = options.generateMipmaps !== void 0 ? options.generateMipmaps : false; this.texture.minFilter = options.minFilter !== void 0 ? options.minFilter : LinearFilter2; } fromEquirectangularTexture(renderer3, texture2) { this.texture.type = texture2.type; this.texture.colorSpace = texture2.colorSpace; this.texture.generateMipmaps = texture2.generateMipmaps; this.texture.minFilter = texture2.minFilter; this.texture.magFilter = texture2.magFilter; const shader = { uniforms: { tEquirect: { value: null } }, vertexShader: ( /* glsl */ ` varying vec3 vWorldDirection; vec3 transformDirection( in vec3 dir, in mat4 matrix ) { return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); } void main() { vWorldDirection = transformDirection( position, modelMatrix ); #include <begin_vertex> #include <project_vertex> } ` ), fragmentShader: ( /* glsl */ ` uniform sampler2D tEquirect; varying vec3 vWorldDirection; #include <common> void main() { vec3 direction = normalize( vWorldDirection ); vec2 sampleUV = equirectUv( direction ); gl_FragColor = texture2D( tEquirect, sampleUV ); } ` ) }; const geometry = new BoxGeometry2(5, 5, 5); const material = new ShaderMaterial2({ name: "CubemapFromEquirect", uniforms: cloneUniforms2(shader.uniforms), vertexShader: shader.vertexShader, fragmentShader: shader.fragmentShader, side: BackSide2, blending: NoBlending2 }); material.uniforms.tEquirect.value = texture2; const mesh = new Mesh2(geometry, material); const currentMinFilter = texture2.minFilter; if (texture2.minFilter === LinearMipmapLinearFilter2) texture2.minFilter = LinearFilter2; const camera3 = new CubeCamera2(1, 10, this); camera3.update(renderer3, mesh); texture2.minFilter = currentMinFilter; mesh.geometry.dispose(); mesh.material.dispose(); return this; } clear(renderer3, color2, depth2, stencil) { const currentRenderTarget = renderer3.getRenderTarget(); for (let i = 0; i < 6; i++) { renderer3.setRenderTarget(this, i); renderer3.clear(color2, depth2, stencil); } renderer3.setRenderTarget(currentRenderTarget); } }; var Scene2 = class extends Object3D2 { constructor() { super(); this.isScene = true; this.type = "Scene"; this.background = null; this.environment = null; this.fog = null; this.backgroundBlurriness = 0; this.backgroundIntensity = 1; this.backgroundRotation = new Euler2(); this.environmentIntensity = 1; this.environmentRotation = new Euler2(); this.overrideMaterial = null; 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(); this.backgroundBlurriness = source.backgroundBlurriness; this.backgroundIntensity = source.backgroundIntensity; this.backgroundRotation.copy(source.backgroundRotation); this.environmentIntensity = source.environmentIntensity; this.environmentRotation.copy(source.environmentRotation); if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone(); this.matrixAutoUpdate = source.matrixAutoUpdate; return this; } toJSON(meta) { const data = super.toJSON(meta); if (this.fog !== null) data.object.fog = this.fog.toJSON(); if (this.backgroundBlurriness > 0) data.object.backgroundBlurriness = this.backgroundBlurriness; if (this.backgroundIntensity !== 1) data.object.backgroundIntensity = this.backgroundIntensity; data.object.backgroundRotation = this.backgroundRotation.toArray(); if (this.environmentIntensity !== 1) data.object.environmentIntensity = this.environmentIntensity; data.object.environmentRotation = this.environmentRotation.toArray(); return data; } }; var InterleavedBuffer = class { constructor(array, stride) { this.isInterleavedBuffer = true; this.array = array; this.stride = stride; this.count = array !== void 0 ? array.length / stride : 0; this.usage = StaticDrawUsage2; this.updateRanges = []; this.version = 0; this.uuid = generateUUID2(); } onUploadCallback() { } set needsUpdate(value) { if (value === true) this.version++; } setUsage(value) { this.usage = value; return this; } addUpdateRange(start, count) { this.updateRanges.push({ start, count }); } clearUpdateRanges() { this.updateRanges.length = 0; } 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, attribute2, index22) { index1 *= this.stride; index22 *= attribute2.stride; for (let i = 0, l = this.stride; i < l; i++) { this.array[index1 + i] = attribute2.array[index22 + 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 = generateUUID2(); } 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 = generateUUID2(); } if (data.arrayBuffers[this.array.buffer._uuid] === void 0) { data.arrayBuffers[this.array.buffer._uuid] = Array.from(new Uint32Array(this.array.buffer)); } return { uuid: this.uuid, buffer: this.array.buffer._uuid, type: this.array.constructor.name, stride: this.stride }; } }; var _vector$72 = /* @__PURE__ */ new Vector32(); var InterleavedBufferAttribute = class _InterleavedBufferAttribute { constructor(interleavedBuffer, itemSize, offset, normalized = false) { this.isInterleavedBufferAttribute = true; this.name = ""; this.data = interleavedBuffer; this.itemSize = itemSize; this.offset = offset; this.normalized = normalized; } get count() { return this.data.count; } get array() { return this.data.array; } set needsUpdate(value) { this.data.needsUpdate = value; } applyMatrix4(m2) { for (let i = 0, l = this.data.count; i < l; i++) { _vector$72.fromBufferAttribute(this, i); _vector$72.applyMatrix4(m2); this.setXYZ(i, _vector$72.x, _vector$72.y, _vector$72.z); } return this; } applyNormalMatrix(m2) { for (let i = 0, l = this.count; i < l; i++) { _vector$72.fromBufferAttribute(this, i); _vector$72.applyNormalMatrix(m2); this.setXYZ(i, _vector$72.x, _vector$72.y, _vector$72.z); } return this; } transformDirection(m2) { for (let i = 0, l = this.count; i < l; i++) { _vector$72.fromBufferAttribute(this, i); _vector$72.transformDirection(m2); this.setXYZ(i, _vector$72.x, _vector$72.y, _vector$72.z); } return this; } getComponent(index5, component) { let value = this.array[index5 * this.data.stride + this.offset + component]; if (this.normalized) value = denormalize2(value, this.array); return value; } setComponent(index5, component, value) { if (this.normalized) value = normalize$1(value, this.array); this.data.array[index5 * this.data.stride + this.offset + component] = value; return this; } setX(index5, x2) { if (this.normalized) x2 = normalize$1(x2, this.array); this.data.array[index5 * this.data.stride + this.offset] = x2; return this; } setY(index5, y2) { if (this.normalized) y2 = normalize$1(y2, this.array); this.data.array[index5 * this.data.stride + this.offset + 1] = y2; return this; } setZ(index5, z2) { if (this.normalized) z2 = normalize$1(z2, this.array); this.data.array[index5 * this.data.stride + this.offset + 2] = z2; return this; } setW(index5, w) { if (this.normalized) w = normalize$1(w, this.array); this.data.array[index5 * this.data.stride + this.offset + 3] = w; return this; } getX(index5) { let x2 = this.data.array[index5 * this.data.stride + this.offset]; if (this.normalized) x2 = denormalize2(x2, this.array); return x2; } getY(index5) { let y2 = this.data.array[index5 * this.data.stride + this.offset + 1]; if (this.normalized) y2 = denormalize2(y2, this.array); return y2; } getZ(index5) { let z2 = this.data.array[index5 * this.data.stride + this.offset + 2]; if (this.normalized) z2 = denormalize2(z2, this.array); return z2; } getW(index5) { let w = this.data.array[index5 * this.data.stride + this.offset + 3]; if (this.normalized) w = denormalize2(w, this.array); return w; } setXY(index5, x2, y2) { index5 = index5 * this.data.stride + this.offset; if (this.normalized) { x2 = normalize$1(x2, this.array); y2 = normalize$1(y2, this.array); } this.data.array[index5 + 0] = x2; this.data.array[index5 + 1] = y2; return this; } setXYZ(index5, x2, y2, z2) { index5 = index5 * this.data.stride + this.offset; if (this.normalized) { x2 = normalize$1(x2, this.array); y2 = normalize$1(y2, this.array); z2 = normalize$1(z2, this.array); } this.data.array[index5 + 0] = x2; this.data.array[index5 + 1] = y2; this.data.array[index5 + 2] = z2; return this; } setXYZW(index5, x2, y2, z2, w) { index5 = index5 * this.data.stride + this.offset; if (this.normalized) { x2 = normalize$1(x2, this.array); y2 = normalize$1(y2, this.array); z2 = normalize$1(z2, this.array); w = normalize$1(w, this.array); } this.data.array[index5 + 0] = x2; this.data.array[index5 + 1] = y2; this.data.array[index5 + 2] = z2; this.data.array[index5 + 3] = w; return this; } clone(data) { if (data === void 0) { console.log("THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data."); const array = []; for (let i = 0; i < this.count; i++) { const index5 = i * this.data.stride + this.offset; for (let j = 0; j < this.itemSize; j++) { array.push(this.data.array[index5 + j]); } } return new BufferAttribute2(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 interleaved buffer attribute will de-interleave buffer data."); const array = []; for (let i = 0; i < this.count; i++) { const index5 = i * this.data.stride + this.offset; for (let j = 0; j < this.itemSize; j++) { array.push(this.data.array[index5 + 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 }; } } }; var SpriteMaterial = class extends Material2 { static get type() { return "SpriteMaterial"; } constructor(parameters) { super(); this.isSpriteMaterial = true; this.color = new Color2(16777215); this.map = null; this.alphaMap = null; this.rotation = 0; this.sizeAttenuation = true; this.transparent = true; this.fog = 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; this.fog = source.fog; return this; } }; var DataTexture = class extends Texture2 { constructor(data = null, width = 1, height = 1, format2, type, mapping, wrapS, wrapT, magFilter = NearestFilter2, minFilter = NearestFilter2, anisotropy2, colorSpace) { super(null, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy2, colorSpace); this.isDataTexture = true; this.image = { data, width, height }; this.generateMipmaps = false; this.flipY = false; this.unpackAlignment = 1; } }; var InstancedBufferAttribute = class extends BufferAttribute2 { constructor(array, itemSize, normalized, meshPerAttribute = 1) { super(array, itemSize, normalized); this.isInstancedBufferAttribute = true; 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; } }; var _vector12 = /* @__PURE__ */ new Vector32(); var _vector22 = /* @__PURE__ */ new Vector32(); var _normalMatrix2 = /* @__PURE__ */ new Matrix32(); var Plane2 = class { constructor(normal2 = new Vector32(1, 0, 0), constant = 0) { this.isPlane = true; this.normal = normal2; this.constant = constant; } set(normal2, constant) { this.normal.copy(normal2); this.constant = constant; return this; } setComponents(x2, y2, z2, w) { this.normal.set(x2, y2, z2); this.constant = w; return this; } setFromNormalAndCoplanarPoint(normal2, point) { this.normal.copy(normal2); this.constant = -point.dot(this.normal); return this; } setFromCoplanarPoints(a2, b, c2) { const normal2 = _vector12.subVectors(c2, b).cross(_vector22.subVectors(a2, b)).normalize(); this.setFromNormalAndCoplanarPoint(normal2, 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(point).addScaledVector(this.normal, -this.distanceToPoint(point)); } intersectLine(line, target) { const direction2 = line.delta(_vector12); const denominator = this.normal.dot(direction2); 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(line.start).addScaledVector(direction2, t); } 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 || _normalMatrix2.getNormalMatrix(matrix); const referencePoint = this.coplanarPoint(_vector12).applyMatrix4(matrix); const normal2 = this.normal.applyMatrix3(normalMatrix).normalize(); this.constant = -referencePoint.dot(normal2); 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); } }; var _sphere$3 = /* @__PURE__ */ new Sphere2(); var _vector$6 = /* @__PURE__ */ new Vector32(); var Frustum2 = class { constructor(p0 = new Plane2(), p1 = new Plane2(), p2 = new Plane2(), p3 = new Plane2(), p4 = new Plane2(), p5 = new Plane2()) { 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(m2, coordinateSystem = WebGLCoordinateSystem2) { const planes = this.planes; const me = m2.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(); if (coordinateSystem === WebGLCoordinateSystem2) { planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize(); } else if (coordinateSystem === WebGPUCoordinateSystem2) { planes[5].setComponents(me2, me6, me10, me14).normalize(); } else { throw new Error("THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: " + coordinateSystem); } return this; } intersectsObject(object) { if (object.boundingSphere !== void 0) { if (object.boundingSphere === null) object.computeBoundingSphere(); _sphere$3.copy(object.boundingSphere).applyMatrix4(object.matrixWorld); } else { const geometry = object.geometry; if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _sphere$3.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld); } return this.intersectsSphere(_sphere$3); } intersectsSprite(sprite) { _sphere$3.center.set(0, 0, 0); _sphere$3.radius = 0.7071067811865476; _sphere$3.applyMatrix4(sprite.matrixWorld); return this.intersectsSphere(_sphere$3); } intersectsSphere(sphere) { const planes = this.planes; const center = sphere.center; const negRadius = -sphere.radius; for (let i = 0; i < 6; i++) { const distance2 = planes[i].distanceToPoint(center); if (distance2 < negRadius) { return false; } } return true; } intersectsBox(box) { const planes = this.planes; for (let i = 0; i < 6; i++) { const plane = planes[i]; _vector$6.x = plane.normal.x > 0 ? box.max.x : box.min.x; _vector$6.y = plane.normal.y > 0 ? box.max.y : box.min.y; _vector$6.z = plane.normal.z > 0 ? box.max.z : box.min.z; if (plane.distanceToPoint(_vector$6) < 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); } }; var LineBasicMaterial2 = class extends Material2 { static get type() { return "LineBasicMaterial"; } constructor(parameters) { super(); this.isLineBasicMaterial = true; this.color = new Color2(16777215); this.map = null; this.linewidth = 1; this.linecap = "round"; this.linejoin = "round"; this.fog = true; this.setValues(parameters); } copy(source) { super.copy(source); this.color.copy(source.color); this.map = source.map; this.linewidth = source.linewidth; this.linecap = source.linecap; this.linejoin = source.linejoin; this.fog = source.fog; return this; } }; var PointsMaterial = class extends Material2 { static get type() { return "PointsMaterial"; } constructor(parameters) { super(); this.isPointsMaterial = true; this.color = new Color2(16777215); this.map = null; this.alphaMap = null; this.size = 1; this.sizeAttenuation = true; this.fog = 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; this.fog = source.fog; return this; } }; var FramebufferTexture = class extends Texture2 { constructor(width, height) { super({ width, height }); this.isFramebufferTexture = true; this.magFilter = NearestFilter2; this.minFilter = NearestFilter2; this.generateMipmaps = false; this.needsUpdate = true; } }; var DepthTexture2 = class extends Texture2 { constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy2, format2 = DepthFormat2) { if (format2 !== DepthFormat2 && format2 !== DepthStencilFormat2) { throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat"); } if (type === void 0 && format2 === DepthFormat2) type = UnsignedIntType2; if (type === void 0 && format2 === DepthStencilFormat2) type = UnsignedInt248Type2; super(null, mapping, wrapS, wrapT, magFilter, minFilter, format2, type, anisotropy2); this.isDepthTexture = true; this.image = { width, height }; this.magFilter = magFilter !== void 0 ? magFilter : NearestFilter2; this.minFilter = minFilter !== void 0 ? minFilter : NearestFilter2; this.flipY = false; this.generateMipmaps = false; this.compareFunction = null; } copy(source) { super.copy(source); this.compareFunction = source.compareFunction; return this; } toJSON(meta) { const data = super.toJSON(meta); if (this.compareFunction !== null) data.compareFunction = this.compareFunction; return data; } }; var SphereGeometry2 = class _SphereGeometry extends BufferGeometry2 { constructor(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI) { super(); this.type = "SphereGeometry"; this.parameters = { radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength }; widthSegments = Math.max(3, Math.floor(widthSegments)); heightSegments = Math.max(2, Math.floor(heightSegments)); const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI); let index5 = 0; const grid = []; const vertex2 = new Vector32(); const normal2 = new Vector32(); const indices = []; const vertices = []; const normals = []; const uvs = []; for (let iy = 0; iy <= heightSegments; iy++) { const verticesRow = []; const v = iy / heightSegments; let uOffset = 0; if (iy === 0 && thetaStart === 0) { uOffset = 0.5 / widthSegments; } else if (iy === heightSegments && thetaEnd === Math.PI) { uOffset = -0.5 / widthSegments; } for (let ix = 0; ix <= widthSegments; ix++) { const u = ix / widthSegments; vertex2.x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); vertex2.y = radius * Math.cos(thetaStart + v * thetaLength); vertex2.z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength); vertices.push(vertex2.x, vertex2.y, vertex2.z); normal2.copy(vertex2).normalize(); normals.push(normal2.x, normal2.y, normal2.z); uvs.push(u + uOffset, 1 - v); verticesRow.push(index5++); } grid.push(verticesRow); } for (let iy = 0; iy < heightSegments; iy++) { for (let ix = 0; ix < widthSegments; ix++) { const a2 = grid[iy][ix + 1]; const b = grid[iy][ix]; const c2 = grid[iy + 1][ix]; const d = grid[iy + 1][ix + 1]; if (iy !== 0 || thetaStart > 0) indices.push(a2, b, d); if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c2, d); } } this.setIndex(indices); this.setAttribute("position", new Float32BufferAttribute2(vertices, 3)); this.setAttribute("normal", new Float32BufferAttribute2(normals, 3)); this.setAttribute("uv", new Float32BufferAttribute2(uvs, 2)); } copy(source) { super.copy(source); this.parameters = Object.assign({}, source.parameters); return this; } static fromJSON(data) { return new _SphereGeometry(data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength); } }; var ShadowMaterial = class extends Material2 { static get type() { return "ShadowMaterial"; } constructor(parameters) { super(); this.isShadowMaterial = true; this.color = new Color2(0); this.transparent = true; this.fog = true; this.setValues(parameters); } copy(source) { super.copy(source); this.color.copy(source.color); this.fog = source.fog; return this; } }; var MeshStandardMaterial = class extends Material2 { static get type() { return "MeshStandardMaterial"; } constructor(parameters) { super(); this.isMeshStandardMaterial = true; this.defines = { "STANDARD": "" }; this.color = new Color2(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 Color2(0); this.emissiveIntensity = 1; this.emissiveMap = null; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap2; this.normalScale = new Vector22(1, 1); this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.roughnessMap = null; this.metalnessMap = null; this.alphaMap = null; this.envMap = null; this.envMapRotation = new Euler2(); this.envMapIntensity = 1; this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = "round"; this.wireframeLinejoin = "round"; this.flatShading = false; this.fog = true; 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.envMapRotation.copy(source.envMapRotation); this.envMapIntensity = source.envMapIntensity; this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; this.flatShading = source.flatShading; this.fog = source.fog; return this; } }; var MeshPhysicalMaterial = class extends MeshStandardMaterial { static get type() { return "MeshPhysicalMaterial"; } constructor(parameters) { super(); this.isMeshPhysicalMaterial = true; this.defines = { "STANDARD": "", "PHYSICAL": "" }; this.anisotropyRotation = 0; this.anisotropyMap = null; this.clearcoatMap = null; this.clearcoatRoughness = 0; this.clearcoatRoughnessMap = null; this.clearcoatNormalScale = new Vector22(1, 1); this.clearcoatNormalMap = null; this.ior = 1.5; Object.defineProperty(this, "reflectivity", { get: function() { return clamp$1(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1); }, set: function(reflectivity) { this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity); } }); this.iridescenceMap = null; this.iridescenceIOR = 1.3; this.iridescenceThicknessRange = [100, 400]; this.iridescenceThicknessMap = null; this.sheenColor = new Color2(0); this.sheenColorMap = null; this.sheenRoughness = 1; this.sheenRoughnessMap = null; this.transmissionMap = null; this.thickness = 0; this.thicknessMap = null; this.attenuationDistance = Infinity; this.attenuationColor = new Color2(1, 1, 1); this.specularIntensity = 1; this.specularIntensityMap = null; this.specularColor = new Color2(1, 1, 1); this.specularColorMap = null; this._anisotropy = 0; this._clearcoat = 0; this._dispersion = 0; this._iridescence = 0; this._sheen = 0; this._transmission = 0; this.setValues(parameters); } get anisotropy() { return this._anisotropy; } set anisotropy(value) { if (this._anisotropy > 0 !== value > 0) { this.version++; } this._anisotropy = value; } get clearcoat() { return this._clearcoat; } set clearcoat(value) { if (this._clearcoat > 0 !== value > 0) { this.version++; } this._clearcoat = value; } get iridescence() { return this._iridescence; } set iridescence(value) { if (this._iridescence > 0 !== value > 0) { this.version++; } this._iridescence = value; } get dispersion() { return this._dispersion; } set dispersion(value) { if (this._dispersion > 0 !== value > 0) { this.version++; } this._dispersion = value; } get sheen() { return this._sheen; } set sheen(value) { if (this._sheen > 0 !== value > 0) { this.version++; } this._sheen = 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.anisotropy = source.anisotropy; this.anisotropyRotation = source.anisotropyRotation; this.anisotropyMap = source.anisotropyMap; 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.dispersion = source.dispersion; this.ior = source.ior; this.iridescence = source.iridescence; this.iridescenceMap = source.iridescenceMap; this.iridescenceIOR = source.iridescenceIOR; this.iridescenceThicknessRange = [...source.iridescenceThicknessRange]; this.iridescenceThicknessMap = source.iridescenceThicknessMap; this.sheen = source.sheen; this.sheenColor.copy(source.sheenColor); this.sheenColorMap = source.sheenColorMap; this.sheenRoughness = source.sheenRoughness; this.sheenRoughnessMap = source.sheenRoughnessMap; this.transmission = source.transmission; this.transmissionMap = source.transmissionMap; this.thickness = source.thickness; this.thicknessMap = source.thicknessMap; this.attenuationDistance = source.attenuationDistance; this.attenuationColor.copy(source.attenuationColor); this.specularIntensity = source.specularIntensity; this.specularIntensityMap = source.specularIntensityMap; this.specularColor.copy(source.specularColor); this.specularColorMap = source.specularColorMap; return this; } }; var MeshPhongMaterial = class extends Material2 { static get type() { return "MeshPhongMaterial"; } constructor(parameters) { super(); this.isMeshPhongMaterial = true; this.color = new Color2(16777215); this.specular = new Color2(1118481); this.shininess = 30; this.map = null; this.lightMap = null; this.lightMapIntensity = 1; this.aoMap = null; this.aoMapIntensity = 1; this.emissive = new Color2(0); this.emissiveIntensity = 1; this.emissiveMap = null; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap2; this.normalScale = new Vector22(1, 1); this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.specularMap = null; this.alphaMap = null; this.envMap = null; this.envMapRotation = new Euler2(); this.combine = MultiplyOperation2; this.reflectivity = 1; this.refractionRatio = 0.98; this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = "round"; this.wireframeLinejoin = "round"; this.flatShading = false; this.fog = true; 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.envMapRotation.copy(source.envMapRotation); 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; this.fog = source.fog; return this; } }; var MeshToonMaterial = class extends Material2 { static get type() { return "MeshToonMaterial"; } constructor(parameters) { super(); this.isMeshToonMaterial = true; this.defines = { "TOON": "" }; this.color = new Color2(16777215); this.map = null; this.gradientMap = null; this.lightMap = null; this.lightMapIntensity = 1; this.aoMap = null; this.aoMapIntensity = 1; this.emissive = new Color2(0); this.emissiveIntensity = 1; this.emissiveMap = null; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap2; this.normalScale = new Vector22(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.fog = true; 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; this.fog = source.fog; return this; } }; var MeshNormalMaterial = class extends Material2 { static get type() { return "MeshNormalMaterial"; } constructor(parameters) { super(); this.isMeshNormalMaterial = true; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap2; this.normalScale = new Vector22(1, 1); this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.wireframe = false; this.wireframeLinewidth = 1; 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; } }; var MeshLambertMaterial2 = class extends Material2 { static get type() { return "MeshLambertMaterial"; } constructor(parameters) { super(); this.isMeshLambertMaterial = true; this.color = new Color2(16777215); this.map = null; this.lightMap = null; this.lightMapIntensity = 1; this.aoMap = null; this.aoMapIntensity = 1; this.emissive = new Color2(0); this.emissiveIntensity = 1; this.emissiveMap = null; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap2; this.normalScale = new Vector22(1, 1); this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.specularMap = null; this.alphaMap = null; this.envMap = null; this.envMapRotation = new Euler2(); this.combine = MultiplyOperation2; this.reflectivity = 1; this.refractionRatio = 0.98; this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = "round"; this.wireframeLinejoin = "round"; this.flatShading = false; this.fog = true; 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.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.envMapRotation.copy(source.envMapRotation); 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; this.fog = source.fog; return this; } }; var MeshMatcapMaterial = class extends Material2 { static get type() { return "MeshMatcapMaterial"; } constructor(parameters) { super(); this.isMeshMatcapMaterial = true; this.defines = { "MATCAP": "" }; this.color = new Color2(16777215); this.matcap = null; this.map = null; this.bumpMap = null; this.bumpScale = 1; this.normalMap = null; this.normalMapType = TangentSpaceNormalMap2; this.normalScale = new Vector22(1, 1); this.displacementMap = null; this.displacementScale = 1; this.displacementBias = 0; this.alphaMap = null; this.flatShading = false; this.fog = true; 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; this.fog = source.fog; return this; } }; var LineDashedMaterial = class extends LineBasicMaterial2 { static get type() { return "LineDashedMaterial"; } constructor(parameters) { super(); this.isLineDashedMaterial = true; 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; } }; function convertArray2(array, type, forceClone) { if (!array || // let 'undefined' and 'null' pass !forceClone && array.constructor === type) return array; if (typeof type.BYTES_PER_ELEMENT === "number") { return new type(array); } return Array.prototype.slice.call(array); } function isTypedArray2(object) { return ArrayBuffer.isView(object) && !(object instanceof DataView); } var Interpolant2 = 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.copySampleValue_(i1 - 1); } 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.copySampleValue_(0); } 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.copySampleValue_(0); } if (t1 === void 0) { i1 = pp.length; this._cachedIndex = i1; return this.copySampleValue_(i1 - 1); } } this._cachedIndex = i1; this.intervalChanged_(i1, t0, t1); } return this.interpolate_(i1, t0, t, t1); } getSettings_() { return this.settings || this.DefaultSettings_; } copySampleValue_(index5) { const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, offset = index5 * stride; for (let i = 0; i !== stride; ++i) { result[i] = values[offset + i]; } return result; } // Template methods for derived classes: interpolate_() { throw new Error("call to abstract method"); } intervalChanged_() { } }; var CubicInterpolant2 = class extends Interpolant2 { 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: ZeroCurvatureEnding2, endingEnd: ZeroCurvatureEnding2 }; } 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 ZeroSlopeEnding2: iPrev = i1; tPrev = 2 * t0 - t1; break; case WrapAroundEnding2: 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 ZeroSlopeEnding2: iNext = i1; tNext = 2 * t1 - t0; break; case WrapAroundEnding2: 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, p = (t - t0) / (t1 - t0), pp = p * p, ppp = pp * p; const sP = -wP * ppp + 2 * wP * pp - wP * p; const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1; const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p; 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 LinearInterpolant2 = class extends Interpolant2 { 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 DiscreteInterpolant2 = class extends Interpolant2 { constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) { super(parameterPositions, sampleValues, sampleSize, resultBuffer); } interpolate_(i1) { return this.copySampleValue_(i1 - 1); } }; var KeyframeTrack2 = 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 = convertArray2(times, this.TimeBufferType); this.values = convertArray2(values, this.ValueBufferType); this.setInterpolation(interpolation || this.DefaultInterpolation); } // Serialization (in static context, because of constructor invocation // and automatic invocation of .toJSON): static toJSON(track) { const trackType = track.constructor; let json; if (trackType.toJSON !== this.toJSON) { json = trackType.toJSON(track); } else { json = { "name": track.name, "times": convertArray2(track.times, Array), "values": convertArray2(track.values, Array) }; const interpolation = track.getInterpolation(); if (interpolation !== track.DefaultInterpolation) { json.interpolation = interpolation; } } json.type = track.ValueTypeName; return json; } InterpolantFactoryMethodDiscrete(result) { return new DiscreteInterpolant2(this.times, this.values, this.getValueSize(), result); } InterpolantFactoryMethodLinear(result) { return new LinearInterpolant2(this.times, this.values, this.getValueSize(), result); } InterpolantFactoryMethodSmooth(result) { return new CubicInterpolant2(this.times, this.values, this.getValueSize(), result); } setInterpolation(interpolation) { let factoryMethod; switch (interpolation) { case InterpolateDiscrete2: factoryMethod = this.InterpolantFactoryMethodDiscrete; break; case InterpolateLinear2: factoryMethod = this.InterpolantFactoryMethodLinear; break; case InterpolateSmooth2: 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 InterpolateDiscrete2; case this.InterpolantFactoryMethodLinear: return InterpolateLinear2; case this.InterpolantFactoryMethodSmooth: return InterpolateSmooth2; } } getValueSize() { return this.values.length / this.times.length; } // move all keyframes either forwards or backwards in time 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 all keyframe times by a factor (useful for frame <-> seconds conversions) scale(timeScale) { if (timeScale !== 1) { const times = this.times; for (let i = 0, n = times.length; i !== n; ++i) { times[i] *= timeScale; } } return this; } // removes keyframes before and after animation without changing any values within the range [startTime, endTime]. // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values 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 = times.slice(from, to); this.values = this.values.slice(from * stride, to * stride); } return this; } // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable 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 (isTypedArray2(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; } // removes equivalent sequential keys as common in morph target sequences // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) optimize() { const times = this.times.slice(), values = this.values.slice(), stride = this.getValueSize(), smoothInterpolation = this.getInterpolation() === InterpolateSmooth2, 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 = times.slice(0, writeIndex); this.values = values.slice(0, writeIndex * stride); } else { this.times = times; this.values = values; } return this; } clone() { const times = this.times.slice(); const values = this.values.slice(); const TypedKeyframeTrack = this.constructor; const track = new TypedKeyframeTrack(this.name, times, values); track.createInterpolant = this.createInterpolant; return track; } }; KeyframeTrack2.prototype.TimeBufferType = Float32Array; KeyframeTrack2.prototype.ValueBufferType = Float32Array; KeyframeTrack2.prototype.DefaultInterpolation = InterpolateLinear2; var BooleanKeyframeTrack2 = class extends KeyframeTrack2 { // No interpolation parameter because only InterpolateDiscrete is valid. constructor(name, times, values) { super(name, times, values); } }; BooleanKeyframeTrack2.prototype.ValueTypeName = "bool"; BooleanKeyframeTrack2.prototype.ValueBufferType = Array; BooleanKeyframeTrack2.prototype.DefaultInterpolation = InterpolateDiscrete2; BooleanKeyframeTrack2.prototype.InterpolantFactoryMethodLinear = void 0; BooleanKeyframeTrack2.prototype.InterpolantFactoryMethodSmooth = void 0; var ColorKeyframeTrack2 = class extends KeyframeTrack2 { }; ColorKeyframeTrack2.prototype.ValueTypeName = "color"; var NumberKeyframeTrack2 = class extends KeyframeTrack2 { }; NumberKeyframeTrack2.prototype.ValueTypeName = "number"; var QuaternionLinearInterpolant2 = class extends Interpolant2 { 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) { Quaternion2.slerpFlat(result, 0, values, offset - stride, values, offset, alpha); } return result; } }; var QuaternionKeyframeTrack2 = class extends KeyframeTrack2 { InterpolantFactoryMethodLinear(result) { return new QuaternionLinearInterpolant2(this.times, this.values, this.getValueSize(), result); } }; QuaternionKeyframeTrack2.prototype.ValueTypeName = "quaternion"; QuaternionKeyframeTrack2.prototype.InterpolantFactoryMethodSmooth = void 0; var StringKeyframeTrack2 = class extends KeyframeTrack2 { // No interpolation parameter because only InterpolateDiscrete is valid. constructor(name, times, values) { super(name, times, values); } }; StringKeyframeTrack2.prototype.ValueTypeName = "string"; StringKeyframeTrack2.prototype.ValueBufferType = Array; StringKeyframeTrack2.prototype.DefaultInterpolation = InterpolateDiscrete2; StringKeyframeTrack2.prototype.InterpolantFactoryMethodLinear = void 0; StringKeyframeTrack2.prototype.InterpolantFactoryMethodSmooth = void 0; var VectorKeyframeTrack2 = class extends KeyframeTrack2 { }; VectorKeyframeTrack2.prototype.ValueTypeName = "vector"; var LoadingManager2 = 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 index5 = handlers.indexOf(regex); if (index5 !== -1) { handlers.splice(index5, 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 DefaultLoadingManager2 = /* @__PURE__ */ new LoadingManager2(); var Loader2 = class { constructor(manager) { this.manager = manager !== void 0 ? manager : DefaultLoadingManager2; this.crossOrigin = "anonymous"; this.withCredentials = false; this.path = ""; this.resourcePath = ""; this.requestHeader = {}; } load() { } loadAsync(url, onProgress) { const scope = this; return new Promise(function(resolve, reject) { scope.load(url, resolve, onProgress, reject); }); } 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; } }; Loader2.DEFAULT_MATERIAL_NAME = "__DEFAULT"; var Light2 = class extends Object3D2 { constructor(color2, intensity = 1) { super(); this.isLight = true; this.type = "Light"; this.color = new Color2(color2); this.intensity = intensity; } dispose() { } copy(source, recursive) { super.copy(source, recursive); 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(); if (this.target !== void 0) data.object.target = this.target.uuid; return data; } }; var HemisphereLight = class extends Light2 { constructor(skyColor, groundColor, intensity) { super(skyColor, intensity); this.isHemisphereLight = true; this.type = "HemisphereLight"; this.position.copy(Object3D2.DEFAULT_UP); this.updateMatrix(); this.groundColor = new Color2(groundColor); } copy(source, recursive) { super.copy(source, recursive); this.groundColor.copy(source.groundColor); return this; } }; var _projScreenMatrix$2 = /* @__PURE__ */ new Matrix42(); var _lightPositionWorld$12 = /* @__PURE__ */ new Vector32(); var _lookTarget$12 = /* @__PURE__ */ new Vector32(); var LightShadow2 = class { constructor(camera3) { this.camera = camera3; this.intensity = 1; this.bias = 0; this.normalBias = 0; this.radius = 1; this.blurSamples = 8; this.mapSize = new Vector22(512, 512); this.map = null; this.mapPass = null; this.matrix = new Matrix42(); this.autoUpdate = true; this.needsUpdate = false; this._frustum = new Frustum2(); this._frameExtents = new Vector22(1, 1); this._viewportCount = 1; this._viewports = [ new Vector42(0, 0, 1, 1) ]; } getViewportCount() { return this._viewportCount; } getFrustum() { return this._frustum; } updateMatrices(light) { const shadowCamera = this.camera; const shadowMatrix = this.matrix; _lightPositionWorld$12.setFromMatrixPosition(light.matrixWorld); shadowCamera.position.copy(_lightPositionWorld$12); _lookTarget$12.setFromMatrixPosition(light.target.matrixWorld); shadowCamera.lookAt(_lookTarget$12); shadowCamera.updateMatrixWorld(); _projScreenMatrix$2.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); this._frustum.setFromProjectionMatrix(_projScreenMatrix$2); 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(_projScreenMatrix$2); } 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.intensity = source.intensity; 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.intensity !== 1) object.intensity = this.intensity; 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 LightShadow2 { constructor() { super(new PerspectiveCamera2(50, 1, 0.5, 500)); this.isSpotLightShadow = true; this.focus = 1; } updateMatrices(light) { const camera3 = this.camera; const fov3 = RAD2DEG2 * 2 * light.angle * this.focus; const aspect3 = this.mapSize.width / this.mapSize.height; const far = light.distance || camera3.far; if (fov3 !== camera3.fov || aspect3 !== camera3.aspect || far !== camera3.far) { camera3.fov = fov3; camera3.aspect = aspect3; camera3.far = far; camera3.updateProjectionMatrix(); } super.updateMatrices(light); } copy(source) { super.copy(source); this.focus = source.focus; return this; } }; var SpotLight = class extends Light2 { constructor(color2, intensity, distance2 = 0, angle = Math.PI / 3, penumbra = 0, decay = 2) { super(color2, intensity); this.isSpotLight = true; this.type = "SpotLight"; this.position.copy(Object3D2.DEFAULT_UP); this.updateMatrix(); this.target = new Object3D2(); this.distance = distance2; this.angle = angle; this.penumbra = penumbra; this.decay = decay; this.map = null; 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, recursive) { super.copy(source, recursive); 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; } }; var _projScreenMatrix$12 = /* @__PURE__ */ new Matrix42(); var _lightPositionWorld = /* @__PURE__ */ new Vector32(); var _lookTarget = /* @__PURE__ */ new Vector32(); var PointLightShadow = class extends LightShadow2 { constructor() { super(new PerspectiveCamera2(90, 1, 0.5, 500)); this.isPointLightShadow = true; this._frameExtents = new Vector22(4, 2); this._viewportCount = 6; this._viewports = [ // These viewports map a cube-map onto a 2D texture with the // following orientation: // // xzXZ // y Y // // X - Positive x direction // x - Negative x direction // Y - Positive y direction // y - Negative y direction // Z - Positive z direction // z - Negative z direction // positive X new Vector42(2, 1, 1, 1), // negative X new Vector42(0, 1, 1, 1), // positive Z new Vector42(3, 1, 1, 1), // negative Z new Vector42(1, 1, 1, 1), // positive Y new Vector42(3, 0, 1, 1), // negative Y new Vector42(1, 0, 1, 1) ]; this._cubeDirections = [ new Vector32(1, 0, 0), new Vector32(-1, 0, 0), new Vector32(0, 0, 1), new Vector32(0, 0, -1), new Vector32(0, 1, 0), new Vector32(0, -1, 0) ]; this._cubeUps = [ new Vector32(0, 1, 0), new Vector32(0, 1, 0), new Vector32(0, 1, 0), new Vector32(0, 1, 0), new Vector32(0, 0, 1), new Vector32(0, 0, -1) ]; } updateMatrices(light, viewportIndex = 0) { const camera3 = this.camera; const shadowMatrix = this.matrix; const far = light.distance || camera3.far; if (far !== camera3.far) { camera3.far = far; camera3.updateProjectionMatrix(); } _lightPositionWorld.setFromMatrixPosition(light.matrixWorld); camera3.position.copy(_lightPositionWorld); _lookTarget.copy(camera3.position); _lookTarget.add(this._cubeDirections[viewportIndex]); camera3.up.copy(this._cubeUps[viewportIndex]); camera3.lookAt(_lookTarget); camera3.updateMatrixWorld(); shadowMatrix.makeTranslation(-_lightPositionWorld.x, -_lightPositionWorld.y, -_lightPositionWorld.z); _projScreenMatrix$12.multiplyMatrices(camera3.projectionMatrix, camera3.matrixWorldInverse); this._frustum.setFromProjectionMatrix(_projScreenMatrix$12); } }; var PointLight = class extends Light2 { constructor(color2, intensity, distance2 = 0, decay = 2) { super(color2, intensity); this.isPointLight = true; this.type = "PointLight"; this.distance = distance2; 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, recursive) { super.copy(source, recursive); this.distance = source.distance; this.decay = source.decay; this.shadow = source.shadow.clone(); return this; } }; var OrthographicCamera2 = class extends Camera2 { constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2e3) { super(); this.isOrthographicCamera = true; 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, x2, y2, 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 = x2; this.view.offsetY = y2; 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.coordinateSystem); 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; } }; var DirectionalLightShadow2 = class extends LightShadow2 { constructor() { super(new OrthographicCamera2(-5, 5, 5, -5, 0.5, 500)); this.isDirectionalLightShadow = true; } }; var DirectionalLight2 = class extends Light2 { constructor(color2, intensity) { super(color2, intensity); this.isDirectionalLight = true; this.type = "DirectionalLight"; this.position.copy(Object3D2.DEFAULT_UP); this.updateMatrix(); this.target = new Object3D2(); this.shadow = new DirectionalLightShadow2(); } dispose() { this.shadow.dispose(); } copy(source) { super.copy(source); this.target = source.target.clone(); this.shadow = source.shadow.clone(); return this; } }; var AmbientLight2 = class extends Light2 { constructor(color2, intensity) { super(color2, intensity); this.isAmbientLight = true; this.type = "AmbientLight"; } }; var RectAreaLight = class extends Light2 { constructor(color2, intensity, width = 10, height = 10) { super(color2, intensity); this.isRectAreaLight = true; 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; } }; var SphericalHarmonics3 = class { constructor() { this.isSphericalHarmonics3 = true; this.coefficients = []; for (let i = 0; i < 9; i++) { this.coefficients.push(new Vector32()); } } 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; } // get the radiance in the direction of the normal // target is a Vector3 getAt(normal2, target) { const x2 = normal2.x, y2 = normal2.y, z2 = normal2.z; const coeff = this.coefficients; target.copy(coeff[0]).multiplyScalar(0.282095); target.addScaledVector(coeff[1], 0.488603 * y2); target.addScaledVector(coeff[2], 0.488603 * z2); target.addScaledVector(coeff[3], 0.488603 * x2); target.addScaledVector(coeff[4], 1.092548 * (x2 * y2)); target.addScaledVector(coeff[5], 1.092548 * (y2 * z2)); target.addScaledVector(coeff[6], 0.315392 * (3 * z2 * z2 - 1)); target.addScaledVector(coeff[7], 1.092548 * (x2 * z2)); target.addScaledVector(coeff[8], 0.546274 * (x2 * x2 - y2 * y2)); return target; } // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal // target is a Vector3 // https://graphics.stanford.edu/papers/envmap/envmap.pdf getIrradianceAt(normal2, target) { const x2 = normal2.x, y2 = normal2.y, z2 = normal2.z; const coeff = this.coefficients; target.copy(coeff[0]).multiplyScalar(0.886227); target.addScaledVector(coeff[1], 2 * 0.511664 * y2); target.addScaledVector(coeff[2], 2 * 0.511664 * z2); target.addScaledVector(coeff[3], 2 * 0.511664 * x2); target.addScaledVector(coeff[4], 2 * 0.429043 * x2 * y2); target.addScaledVector(coeff[5], 2 * 0.429043 * y2 * z2); target.addScaledVector(coeff[6], 0.743125 * z2 * z2 - 0.247708); target.addScaledVector(coeff[7], 2 * 0.429043 * x2 * z2); target.addScaledVector(coeff[8], 0.429043 * (x2 * x2 - y2 * y2)); 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; } // evaluate the basis functions // shBasis is an Array[ 9 ] static getBasisAt(normal2, shBasis) { const x2 = normal2.x, y2 = normal2.y, z2 = normal2.z; shBasis[0] = 0.282095; shBasis[1] = 0.488603 * y2; shBasis[2] = 0.488603 * z2; shBasis[3] = 0.488603 * x2; shBasis[4] = 1.092548 * x2 * y2; shBasis[5] = 1.092548 * y2 * z2; shBasis[6] = 0.315392 * (3 * z2 * z2 - 1); shBasis[7] = 1.092548 * x2 * z2; shBasis[8] = 0.546274 * (x2 * x2 - y2 * y2); } }; var LightProbe = class extends Light2 { constructor(sh = new SphericalHarmonics3(), intensity = 1) { super(void 0, intensity); this.isLightProbe = true; 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; } }; var _RESERVED_CHARS_RE2 = "\\[\\]\\.:\\/"; var _reservedRe2 = new RegExp("[" + _RESERVED_CHARS_RE2 + "]", "g"); var _wordChar2 = "[^" + _RESERVED_CHARS_RE2 + "]"; var _wordCharOrDot2 = "[^" + _RESERVED_CHARS_RE2.replace("\\.", "") + "]"; var _directoryRe2 = /* @__PURE__ */ /((?:WC+[\/:])*)/.source.replace("WC", _wordChar2); var _nodeRe2 = /* @__PURE__ */ /(WCOD+)?/.source.replace("WCOD", _wordCharOrDot2); var _objectRe2 = /* @__PURE__ */ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC", _wordChar2); var _propertyRe2 = /* @__PURE__ */ /\.(WC+)(?:\[(.+)\])?/.source.replace("WC", _wordChar2); var _trackRe2 = new RegExp( "^" + _directoryRe2 + _nodeRe2 + _objectRe2 + _propertyRe2 + "$" ); var _supportedObjectNames2 = ["material", "materials", "bones", "map"]; var Composite2 = class { constructor(targetGroup, path, optionalParsedPath) { const parsedPath = optionalParsedPath || PropertyBinding2.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 PropertyBinding2 = class _PropertyBinding { constructor(rootNode, path, parsedPath) { this.path = path; this.parsedPath = parsedPath || _PropertyBinding.parseTrackName(path); this.node = _PropertyBinding.findNode(rootNode, this.parsedPath.nodeName); this.rootNode = rootNode; this.getValue = this._getValue_unbound; this.setValue = this._setValue_unbound; } static create(root2, path, parsedPath) { if (!(root2 && root2.isAnimationObjectGroup)) { return new _PropertyBinding(root2, path, parsedPath); } else { return new _PropertyBinding.Composite(root2, path, parsedPath); } } /** * Replaces spaces with underscores and removes unsupported characters from * node names, to ensure compatibility with parseTrackName(). * * @param {string} name Node name to be sanitized. * @return {string} */ static sanitizeNodeName(name) { return name.replace(/\s/g, "_").replace(_reservedRe2, ""); } static parseTrackName(trackName) { const matches = _trackRe2.exec(trackName); if (matches === null) { throw new Error("PropertyBinding: Cannot parse trackName: " + trackName); } const results = { // directoryName: matches[ 1 ], // (tschw) currently unused nodeName: matches[2], objectName: matches[3], objectIndex: matches[4], propertyName: matches[5], // required propertyIndex: matches[6] }; const lastDot = results.nodeName && results.nodeName.lastIndexOf("."); if (lastDot !== void 0 && lastDot !== -1) { const objectName = results.nodeName.substring(lastDot + 1); if (_supportedObjectNames2.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(root2, nodeName) { if (nodeName === void 0 || nodeName === "" || nodeName === "." || nodeName === -1 || nodeName === root2.name || nodeName === root2.uuid) { return root2; } if (root2.skeleton) { const bone = root2.skeleton.getBoneByName(nodeName); if (bone !== void 0) { return bone; } } if (root2.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(root2.children); if (subTreeNode) { return subTreeNode; } } return null; } // these are used to "bind" a nonexistent property _getValue_unavailable() { } _setValue_unavailable() { } // Getters _getValue_direct(buffer2, offset) { buffer2[offset] = this.targetObject[this.propertyName]; } _getValue_array(buffer2, offset) { const source = this.resolvedProperty; for (let i = 0, n = source.length; i !== n; ++i) { buffer2[offset++] = source[i]; } } _getValue_arrayElement(buffer2, offset) { buffer2[offset] = this.resolvedProperty[this.propertyIndex]; } _getValue_toArray(buffer2, offset) { this.resolvedProperty.toArray(buffer2, offset); } // Direct _setValue_direct(buffer2, offset) { this.targetObject[this.propertyName] = buffer2[offset]; } _setValue_direct_setNeedsUpdate(buffer2, offset) { this.targetObject[this.propertyName] = buffer2[offset]; this.targetObject.needsUpdate = true; } _setValue_direct_setMatrixWorldNeedsUpdate(buffer2, offset) { this.targetObject[this.propertyName] = buffer2[offset]; this.targetObject.matrixWorldNeedsUpdate = true; } // EntireArray _setValue_array(buffer2, offset) { const dest = this.resolvedProperty; for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer2[offset++]; } } _setValue_array_setNeedsUpdate(buffer2, offset) { const dest = this.resolvedProperty; for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer2[offset++]; } this.targetObject.needsUpdate = true; } _setValue_array_setMatrixWorldNeedsUpdate(buffer2, offset) { const dest = this.resolvedProperty; for (let i = 0, n = dest.length; i !== n; ++i) { dest[i] = buffer2[offset++]; } this.targetObject.matrixWorldNeedsUpdate = true; } // ArrayElement _setValue_arrayElement(buffer2, offset) { this.resolvedProperty[this.propertyIndex] = buffer2[offset]; } _setValue_arrayElement_setNeedsUpdate(buffer2, offset) { this.resolvedProperty[this.propertyIndex] = buffer2[offset]; this.targetObject.needsUpdate = true; } _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer2, offset) { this.resolvedProperty[this.propertyIndex] = buffer2[offset]; this.targetObject.matrixWorldNeedsUpdate = true; } // HasToFromArray _setValue_fromArray(buffer2, offset) { this.resolvedProperty.fromArray(buffer2, offset); } _setValue_fromArray_setNeedsUpdate(buffer2, offset) { this.resolvedProperty.fromArray(buffer2, offset); this.targetObject.needsUpdate = true; } _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer2, offset) { this.resolvedProperty.fromArray(buffer2, 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); } // create getter / setter pair for a property in the scene graph 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.node = targetObject; } this.getValue = this._getValue_unavailable; this.setValue = this._setValue_unavailable; if (!targetObject) { console.warn("THREE.PropertyBinding: No target node found for track: " + this.path + "."); 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; case "map": if ("map" in targetObject) { targetObject = targetObject.map; break; } if (!targetObject.material) { console.error("THREE.PropertyBinding: Can not bind to material as node does not have a material.", this); return; } if (!targetObject.material.map) { console.error("THREE.PropertyBinding: Can not bind to material.map as node.material does not have a map.", this); return; } targetObject = targetObject.material.map; 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.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]; } } 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; } }; PropertyBinding2.Composite = Composite2; PropertyBinding2.prototype.BindingType = { Direct: 0, EntireArray: 1, ArrayElement: 2, HasFromToArray: 3 }; PropertyBinding2.prototype.Versioning = { None: 0, NeedsUpdate: 1, MatrixWorldNeedsUpdate: 2 }; PropertyBinding2.prototype.GetterByBindingType = [ PropertyBinding2.prototype._getValue_direct, PropertyBinding2.prototype._getValue_array, PropertyBinding2.prototype._getValue_arrayElement, PropertyBinding2.prototype._getValue_toArray ]; PropertyBinding2.prototype.SetterByBindingTypeAndVersioning = [ [ // Direct PropertyBinding2.prototype._setValue_direct, PropertyBinding2.prototype._setValue_direct_setNeedsUpdate, PropertyBinding2.prototype._setValue_direct_setMatrixWorldNeedsUpdate ], [ // EntireArray PropertyBinding2.prototype._setValue_array, PropertyBinding2.prototype._setValue_array_setNeedsUpdate, PropertyBinding2.prototype._setValue_array_setMatrixWorldNeedsUpdate ], [ // ArrayElement PropertyBinding2.prototype._setValue_arrayElement, PropertyBinding2.prototype._setValue_arrayElement_setNeedsUpdate, PropertyBinding2.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate ], [ // HasToFromArray PropertyBinding2.prototype._setValue_fromArray, PropertyBinding2.prototype._setValue_fromArray_setNeedsUpdate, PropertyBinding2.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate ] ]; var _controlInterpolantsResultBuffer2 = new Float32Array(1); var InstancedInterleavedBuffer = class extends InterleavedBuffer { constructor(array, stride, meshPerAttribute = 1) { super(array, stride); this.isInstancedInterleavedBuffer = true; 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; } }; var refreshUniforms = [ "alphaMap", "alphaTest", "anisotropy", "anisotropyMap", "anisotropyRotation", "aoMap", "attenuationColor", "attenuationDistance", "bumpMap", "clearcoat", "clearcoatMap", "clearcoatNormalMap", "clearcoatNormalScale", "clearcoatRoughness", "color", "dispersion", "displacementMap", "emissive", "emissiveMap", "envMap", "gradientMap", "ior", "iridescence", "iridescenceIOR", "iridescenceMap", "iridescenceThicknessMap", "lightMap", "map", "matcap", "metalness", "metalnessMap", "normalMap", "normalScale", "opacity", "roughness", "roughnessMap", "sheen", "sheenColor", "sheenColorMap", "sheenRoughnessMap", "shininess", "specular", "specularColor", "specularColorMap", "specularIntensity", "specularIntensityMap", "specularMap", "thickness", "transmission", "transmissionMap" ]; var NodeMaterialObserver = class { constructor(builder) { this.renderObjects = /* @__PURE__ */ new WeakMap(); this.hasNode = this.containsNode(builder); this.hasAnimation = builder.object.isSkinnedMesh === true; this.refreshUniforms = refreshUniforms; this.renderId = 0; } firstInitialization(renderObject) { const hasInitialized = this.renderObjects.has(renderObject); if (hasInitialized === false) { this.getRenderObjectData(renderObject); return true; } return false; } getRenderObjectData(renderObject) { let data = this.renderObjects.get(renderObject); if (data === void 0) { const { geometry, material } = renderObject; data = { material: this.getMaterialData(material), geometry: { attributes: this.getAttributesData(geometry.attributes), indexVersion: geometry.index ? geometry.index.version : null, drawRange: { start: geometry.drawRange.start, count: geometry.drawRange.count } }, worldMatrix: renderObject.object.matrixWorld.clone() }; if (renderObject.object.center) { data.center = renderObject.object.center.clone(); } if (renderObject.object.morphTargetInfluences) { data.morphTargetInfluences = renderObject.object.morphTargetInfluences.slice(); } if (renderObject.bundle !== null) { data.version = renderObject.bundle.version; } if (data.material.transmission > 0) { const { width, height } = renderObject.context; data.bufferWidth = width; data.bufferHeight = height; } this.renderObjects.set(renderObject, data); } return data; } getAttributesData(attributes) { const attributesData = {}; for (const name in attributes) { const attribute2 = attributes[name]; attributesData[name] = { version: attribute2.version }; } return attributesData; } containsNode(builder) { const material = builder.material; for (const property2 in material) { if (material[property2] && material[property2].isNode) return true; } if (builder.renderer.nodes.modelViewMatrix !== null || builder.renderer.nodes.modelNormalViewMatrix !== null) return true; return false; } getMaterialData(material) { const data = {}; for (const property2 of this.refreshUniforms) { const value = material[property2]; if (value === null || value === void 0) continue; if (typeof value === "object" && value.clone !== void 0) { if (value.isTexture === true) { data[property2] = { id: value.id, version: value.version }; } else { data[property2] = value.clone(); } } else { data[property2] = value; } } return data; } equals(renderObject) { const { object, material, geometry } = renderObject; const renderObjectData = this.getRenderObjectData(renderObject); if (renderObjectData.worldMatrix.equals(object.matrixWorld) !== true) { renderObjectData.worldMatrix.copy(object.matrixWorld); return false; } const materialData = renderObjectData.material; for (const property2 in materialData) { const value = materialData[property2]; const mtlValue = material[property2]; if (value.equals !== void 0) { if (value.equals(mtlValue) === false) { value.copy(mtlValue); return false; } } else if (mtlValue.isTexture === true) { if (value.id !== mtlValue.id || value.version !== mtlValue.version) { value.id = mtlValue.id; value.version = mtlValue.version; return false; } } else if (value !== mtlValue) { materialData[property2] = mtlValue; return false; } } if (materialData.transmission > 0) { const { width, height } = renderObject.context; if (renderObjectData.bufferWidth !== width || renderObjectData.bufferHeight !== height) { renderObjectData.bufferWidth = width; renderObjectData.bufferHeight = height; return false; } } const storedGeometryData = renderObjectData.geometry; const attributes = geometry.attributes; const storedAttributes = storedGeometryData.attributes; const storedAttributeNames = Object.keys(storedAttributes); const currentAttributeNames = Object.keys(attributes); if (storedAttributeNames.length !== currentAttributeNames.length) { renderObjectData.geometry.attributes = this.getAttributesData(attributes); return false; } for (const name of storedAttributeNames) { const storedAttributeData = storedAttributes[name]; const attribute2 = attributes[name]; if (attribute2 === void 0) { delete storedAttributes[name]; return false; } if (storedAttributeData.version !== attribute2.version) { storedAttributeData.version = attribute2.version; return false; } } const index5 = geometry.index; const storedIndexVersion = storedGeometryData.indexVersion; const currentIndexVersion = index5 ? index5.version : null; if (storedIndexVersion !== currentIndexVersion) { storedGeometryData.indexVersion = currentIndexVersion; return false; } if (storedGeometryData.drawRange.start !== geometry.drawRange.start || storedGeometryData.drawRange.count !== geometry.drawRange.count) { storedGeometryData.drawRange.start = geometry.drawRange.start; storedGeometryData.drawRange.count = geometry.drawRange.count; return false; } if (renderObjectData.morphTargetInfluences) { let morphChanged = false; for (let i = 0; i < renderObjectData.morphTargetInfluences.length; i++) { if (renderObjectData.morphTargetInfluences[i] !== object.morphTargetInfluences[i]) { morphChanged = true; } } if (morphChanged) return true; } if (renderObjectData.center) { if (renderObjectData.center.equals(object.center) === false) { renderObjectData.center.copy(object.center); return true; } } if (renderObject.bundle !== null) { renderObjectData.version = renderObject.bundle.version; } return true; } needsRefresh(renderObject, nodeFrame) { if (this.hasNode || this.hasAnimation || this.firstInitialization(renderObject)) return true; const { renderId } = nodeFrame; if (this.renderId !== renderId) { this.renderId = renderId; return true; } const isStatic = renderObject.object.static === true; const isBundle = renderObject.bundle !== null && renderObject.bundle.static === true && this.getRenderObjectData(renderObject).version === renderObject.bundle.version; if (isStatic || isBundle) return false; const notEqual2 = this.equals(renderObject) !== true; return notEqual2; } }; function cyrb53(value, seed = 0) { let h12 = 3735928559 ^ seed, h2 = 1103547991 ^ seed; if (value instanceof Array) { for (let i = 0, val; i < value.length; i++) { val = value[i]; h12 = Math.imul(h12 ^ val, 2654435761); h2 = Math.imul(h2 ^ val, 1597334677); } } else { for (let i = 0, ch; i < value.length; i++) { ch = value.charCodeAt(i); h12 = Math.imul(h12 ^ ch, 2654435761); h2 = Math.imul(h2 ^ ch, 1597334677); } } h12 = Math.imul(h12 ^ h12 >>> 16, 2246822507); h12 ^= Math.imul(h2 ^ h2 >>> 13, 3266489909); h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507); h2 ^= Math.imul(h12 ^ h12 >>> 13, 3266489909); return 4294967296 * (2097151 & h2) + (h12 >>> 0); } var hashString = (str) => cyrb53(str); var hashArray = (array) => cyrb53(array); var hash$1 = (...params) => cyrb53(params); function getCacheKey$1(object, force = false) { const values = []; if (object.isNode === true) { values.push(object.id); object = object.getSelf(); } for (const { property: property2, childNode } of getNodeChildren(object)) { values.push(values, cyrb53(property2.slice(0, -4)), childNode.getCacheKey(force)); } return cyrb53(values); } function* getNodeChildren(node, toJSON = false) { for (const property2 in node) { if (property2.startsWith("_") === true) continue; const object = node[property2]; if (Array.isArray(object) === true) { for (let i = 0; i < object.length; i++) { const child = object[i]; if (child && (child.isNode === true || toJSON && typeof child.toJSON === "function")) { yield { property: property2, index: i, childNode: child }; } } } else if (object && object.isNode === true) { yield { property: property2, childNode: object }; } else if (typeof object === "object") { for (const subProperty in object) { const child = object[subProperty]; if (child && (child.isNode === true || toJSON && typeof child.toJSON === "function")) { yield { property: property2, index: subProperty, childNode: child }; } } } } } function getValueType(value) { if (value === void 0 || value === null) return null; const typeOf = typeof value; if (value.isNode === true) { return "node"; } else if (typeOf === "number") { return "float"; } else if (typeOf === "boolean") { return "bool"; } else if (typeOf === "string") { return "string"; } else if (typeOf === "function") { return "shader"; } else if (value.isVector2 === true) { return "vec2"; } else if (value.isVector3 === true) { return "vec3"; } else if (value.isVector4 === true) { return "vec4"; } else if (value.isMatrix3 === true) { return "mat3"; } else if (value.isMatrix4 === true) { return "mat4"; } else if (value.isColor === true) { return "color"; } else if (value instanceof ArrayBuffer) { return "ArrayBuffer"; } return null; } function getValueFromType(type, ...params) { const last4 = type ? type.slice(-4) : void 0; if (params.length === 1) { if (last4 === "vec2") params = [params[0], params[0]]; else if (last4 === "vec3") params = [params[0], params[0], params[0]]; else if (last4 === "vec4") params = [params[0], params[0], params[0], params[0]]; } if (type === "color") { return new Color2(...params); } else if (last4 === "vec2") { return new Vector22(...params); } else if (last4 === "vec3") { return new Vector32(...params); } else if (last4 === "vec4") { return new Vector42(...params); } else if (last4 === "mat3") { return new Matrix32(...params); } else if (last4 === "mat4") { return new Matrix42(...params); } else if (type === "bool") { return params[0] || false; } else if (type === "float" || type === "int" || type === "uint") { return params[0] || 0; } else if (type === "string") { return params[0] || ""; } else if (type === "ArrayBuffer") { return base64ToArrayBuffer(params[0]); } return null; } function arrayBufferToBase64(arrayBuffer) { let chars = ""; const array = new Uint8Array(arrayBuffer); for (let i = 0; i < array.length; i++) { chars += String.fromCharCode(array[i]); } return btoa(chars); } function base64ToArrayBuffer(base64) { return Uint8Array.from(atob(base64), (c2) => c2.charCodeAt(0)).buffer; } var NodeShaderStage = { VERTEX: "vertex", FRAGMENT: "fragment" }; var NodeUpdateType = { NONE: "none", FRAME: "frame", RENDER: "render", OBJECT: "object" }; var defaultShaderStages = ["fragment", "vertex"]; var defaultBuildStages = ["setup", "analyze", "generate"]; var shaderStages = [...defaultShaderStages, "compute"]; var vectorComponents = ["x", "y", "z", "w"]; var _nodeId = 0; var Node = class extends EventDispatcher2 { static get type() { return "Node"; } constructor(nodeType = null) { super(); this.nodeType = nodeType; this.updateType = NodeUpdateType.NONE; this.updateBeforeType = NodeUpdateType.NONE; this.updateAfterType = NodeUpdateType.NONE; this.uuid = MathUtils2.generateUUID(); this.version = 0; this._cacheKey = null; this._cacheKeyVersion = 0; this.global = false; this.isNode = true; Object.defineProperty(this, "id", { value: _nodeId++ }); } set needsUpdate(value) { if (value === true) { this.version++; } } get type() { return this.constructor.type; } onUpdate(callback, updateType) { this.updateType = updateType; this.update = callback.bind(this.getSelf()); return this; } onFrameUpdate(callback) { return this.onUpdate(callback, NodeUpdateType.FRAME); } onRenderUpdate(callback) { return this.onUpdate(callback, NodeUpdateType.RENDER); } onObjectUpdate(callback) { return this.onUpdate(callback, NodeUpdateType.OBJECT); } onReference(callback) { this.updateReference = callback.bind(this.getSelf()); return this; } getSelf() { return this.self || this; } updateReference() { return this; } isGlobal() { return this.global; } *getChildren() { for (const { childNode } of getNodeChildren(this)) { yield childNode; } } dispose() { this.dispatchEvent({ type: "dispose" }); } traverse(callback) { callback(this); for (const childNode of this.getChildren()) { childNode.traverse(callback); } } getCacheKey(force = false) { force = force || this.version !== this._cacheKeyVersion; if (force === true || this._cacheKey === null) { this._cacheKey = getCacheKey$1(this, force); this._cacheKeyVersion = this.version; } return this._cacheKey; } getScope() { return this; } getHash() { return this.uuid; } getUpdateType() { return this.updateType; } getUpdateBeforeType() { return this.updateBeforeType; } getUpdateAfterType() { return this.updateAfterType; } getElementType(builder) { const type = this.getNodeType(builder); const elementType = builder.getElementType(type); return elementType; } getNodeType(builder) { const nodeProperties = builder.getNodeProperties(this); if (nodeProperties.outputNode) { return nodeProperties.outputNode.getNodeType(builder); } return this.nodeType; } getShared(builder) { const hash = this.getHash(builder); const nodeFromHash = builder.getNodeFromHash(hash); return nodeFromHash || this; } setup(builder) { const nodeProperties = builder.getNodeProperties(this); let index5 = 0; for (const childNode of this.getChildren()) { nodeProperties["node" + index5++] = childNode; } return null; } analyze(builder) { const usageCount = builder.increaseUsage(this); if (usageCount === 1) { const nodeProperties = builder.getNodeProperties(this); for (const childNode of Object.values(nodeProperties)) { if (childNode && childNode.isNode === true) { childNode.build(builder); } } } } generate(builder, output2) { const { outputNode } = builder.getNodeProperties(this); if (outputNode && outputNode.isNode === true) { return outputNode.build(builder, output2); } } updateBefore() { console.warn("Abstract function."); } updateAfter() { console.warn("Abstract function."); } update() { console.warn("Abstract function."); } build(builder, output2 = null) { const refNode = this.getShared(builder); if (this !== refNode) { return refNode.build(builder, output2); } builder.addNode(this); builder.addChain(this); let result = null; const buildStage = builder.getBuildStage(); if (buildStage === "setup") { this.updateReference(builder); const properties = builder.getNodeProperties(this); if (properties.initialized !== true) { const stackNodesBeforeSetup = builder.stack.nodes.length; properties.initialized = true; properties.outputNode = this.setup(builder); if (properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeSetup) ; for (const childNode of Object.values(properties)) { if (childNode && childNode.isNode === true) { childNode.build(builder); } } } } else if (buildStage === "analyze") { this.analyze(builder); } else if (buildStage === "generate") { const isGenerateOnce = this.generate.length === 1; if (isGenerateOnce) { const type = this.getNodeType(builder); const nodeData = builder.getDataFromNode(this); result = nodeData.snippet; if (result === void 0) { result = this.generate(builder) || ""; nodeData.snippet = result; } else if (nodeData.flowCodes !== void 0 && builder.context.nodeBlock !== void 0) { builder.addFlowCodeHierarchy(this, builder.context.nodeBlock); } result = builder.format(result, type, output2); } else { result = this.generate(builder, output2) || ""; } } builder.removeChain(this); builder.addSequentialNode(this); return result; } getSerializeChildren() { return getNodeChildren(this); } serialize(json) { const nodeChildren = this.getSerializeChildren(); const inputNodes = {}; for (const { property: property2, index: index5, childNode } of nodeChildren) { if (index5 !== void 0) { if (inputNodes[property2] === void 0) { inputNodes[property2] = Number.isInteger(index5) ? [] : {}; } inputNodes[property2][index5] = childNode.toJSON(json.meta).uuid; } else { inputNodes[property2] = childNode.toJSON(json.meta).uuid; } } if (Object.keys(inputNodes).length > 0) { json.inputNodes = inputNodes; } } deserialize(json) { if (json.inputNodes !== void 0) { const nodes = json.meta.nodes; for (const property2 in json.inputNodes) { if (Array.isArray(json.inputNodes[property2])) { const inputArray = []; for (const uuid of json.inputNodes[property2]) { inputArray.push(nodes[uuid]); } this[property2] = inputArray; } else if (typeof json.inputNodes[property2] === "object") { const inputObject = {}; for (const subProperty in json.inputNodes[property2]) { const uuid = json.inputNodes[property2][subProperty]; inputObject[subProperty] = nodes[uuid]; } this[property2] = inputObject; } else { const uuid = json.inputNodes[property2]; this[property2] = nodes[uuid]; } } } } toJSON(meta) { const { uuid, type } = this; const isRoot = meta === void 0 || typeof meta === "string"; if (isRoot) { meta = { textures: {}, images: {}, nodes: {} }; } let data = meta.nodes[uuid]; if (data === void 0) { data = { uuid, type, meta, metadata: { version: 4.6, type: "Node", generator: "Node.toJSON" } }; if (isRoot !== true) meta.nodes[data.uuid] = data; this.serialize(data); delete data.meta; } function extractFromCache(cache2) { const values = []; for (const key in cache2) { const data2 = cache2[key]; delete data2.metadata; values.push(data2); } return values; } if (isRoot) { const textures = extractFromCache(meta.textures); const images = extractFromCache(meta.images); const nodes = extractFromCache(meta.nodes); if (textures.length > 0) data.textures = textures; if (images.length > 0) data.images = images; if (nodes.length > 0) data.nodes = nodes; } return data; } }; var ArrayElementNode = class extends Node { static get type() { return "ArrayElementNode"; } // @TODO: If extending from TempNode it breaks webgpu_compute constructor(node, indexNode) { super(); this.node = node; this.indexNode = indexNode; this.isArrayElementNode = true; } getNodeType(builder) { return this.node.getElementType(builder); } generate(builder) { const nodeSnippet = this.node.build(builder); const indexSnippet = this.indexNode.build(builder, "uint"); return `${nodeSnippet}[ ${indexSnippet} ]`; } }; var ConvertNode = class extends Node { static get type() { return "ConvertNode"; } constructor(node, convertTo) { super(); this.node = node; this.convertTo = convertTo; } getNodeType(builder) { const requestType = this.node.getNodeType(builder); let convertTo = null; for (const overloadingType of this.convertTo.split("|")) { if (convertTo === null || builder.getTypeLength(requestType) === builder.getTypeLength(overloadingType)) { convertTo = overloadingType; } } return convertTo; } serialize(data) { super.serialize(data); data.convertTo = this.convertTo; } deserialize(data) { super.deserialize(data); this.convertTo = data.convertTo; } generate(builder, output2) { const node = this.node; const type = this.getNodeType(builder); const snippet = node.build(builder, type); return builder.format(snippet, type, output2); } }; var TempNode = class extends Node { static get type() { return "TempNode"; } constructor(type) { super(type); this.isTempNode = true; } hasDependencies(builder) { return builder.getDataFromNode(this).usageCount > 1; } build(builder, output2) { const buildStage = builder.getBuildStage(); if (buildStage === "generate") { const type = builder.getVectorType(this.getNodeType(builder, output2)); const nodeData = builder.getDataFromNode(this); if (nodeData.propertyName !== void 0) { return builder.format(nodeData.propertyName, type, output2); } else if (type !== "void" && output2 !== "void" && this.hasDependencies(builder)) { const snippet = super.build(builder, type); const nodeVar = builder.getVarFromNode(this, null, type); const propertyName = builder.getPropertyName(nodeVar); builder.addLineFlowCode(`${propertyName} = ${snippet}`, this); nodeData.snippet = snippet; nodeData.propertyName = propertyName; return builder.format(nodeData.propertyName, type, output2); } } return super.build(builder, output2); } }; var JoinNode = class extends TempNode { static get type() { return "JoinNode"; } constructor(nodes = [], nodeType = null) { super(nodeType); this.nodes = nodes; } getNodeType(builder) { if (this.nodeType !== null) { return builder.getVectorType(this.nodeType); } return builder.getTypeFromLength(this.nodes.reduce((count, cur) => count + builder.getTypeLength(cur.getNodeType(builder)), 0)); } generate(builder, output2) { const type = this.getNodeType(builder); const nodes = this.nodes; const primitiveType = builder.getComponentType(type); const snippetValues = []; for (const input of nodes) { let inputSnippet = input.build(builder); const inputPrimitiveType = builder.getComponentType(input.getNodeType(builder)); if (inputPrimitiveType !== primitiveType) { inputSnippet = builder.format(inputSnippet, inputPrimitiveType, primitiveType); } snippetValues.push(inputSnippet); } const snippet = `${builder.getType(type)}( ${snippetValues.join(", ")} )`; return builder.format(snippet, type, output2); } }; var stringVectorComponents = vectorComponents.join(""); var SplitNode = class extends Node { static get type() { return "SplitNode"; } constructor(node, components = "x") { super(); this.node = node; this.components = components; this.isSplitNode = true; } getVectorLength() { let vectorLength = this.components.length; for (const c2 of this.components) { vectorLength = Math.max(vectorComponents.indexOf(c2) + 1, vectorLength); } return vectorLength; } getComponentType(builder) { return builder.getComponentType(this.node.getNodeType(builder)); } getNodeType(builder) { return builder.getTypeFromLength(this.components.length, this.getComponentType(builder)); } generate(builder, output2) { const node = this.node; const nodeTypeLength = builder.getTypeLength(node.getNodeType(builder)); let snippet = null; if (nodeTypeLength > 1) { let type = null; const componentsLength = this.getVectorLength(); if (componentsLength >= nodeTypeLength) { type = builder.getTypeFromLength(this.getVectorLength(), this.getComponentType(builder)); } const nodeSnippet = node.build(builder, type); if (this.components.length === nodeTypeLength && this.components === stringVectorComponents.slice(0, this.components.length)) { snippet = builder.format(nodeSnippet, type, output2); } else { snippet = builder.format(`${nodeSnippet}.${this.components}`, this.getNodeType(builder), output2); } } else { snippet = node.build(builder, output2); } return snippet; } serialize(data) { super.serialize(data); data.components = this.components; } deserialize(data) { super.deserialize(data); this.components = data.components; } }; var SetNode = class extends TempNode { static get type() { return "SetNode"; } constructor(sourceNode, components, targetNode) { super(); this.sourceNode = sourceNode; this.components = components; this.targetNode = targetNode; } getNodeType(builder) { return this.sourceNode.getNodeType(builder); } generate(builder) { const { sourceNode, components, targetNode } = this; const sourceType = this.getNodeType(builder); const targetType = builder.getTypeFromLength(components.length, targetNode.getNodeType(builder)); const targetSnippet = targetNode.build(builder, targetType); const sourceSnippet = sourceNode.build(builder, sourceType); const length2 = builder.getTypeLength(sourceType); const snippetValues = []; for (let i = 0; i < length2; i++) { const component = vectorComponents[i]; if (component === components[0]) { snippetValues.push(targetSnippet); i += components.length - 1; } else { snippetValues.push(sourceSnippet + "." + component); } } return `${builder.getType(sourceType)}( ${snippetValues.join(", ")} )`; } }; var FlipNode = class extends TempNode { static get type() { return "FlipNode"; } constructor(sourceNode, components) { super(); this.sourceNode = sourceNode; this.components = components; } getNodeType(builder) { return this.sourceNode.getNodeType(builder); } generate(builder) { const { components, sourceNode } = this; const sourceType = this.getNodeType(builder); const sourceSnippet = sourceNode.build(builder); const sourceCache = builder.getVarFromNode(this); const sourceProperty = builder.getPropertyName(sourceCache); builder.addLineFlowCode(sourceProperty + " = " + sourceSnippet, this); const length2 = builder.getTypeLength(sourceType); const snippetValues = []; let componentIndex = 0; for (let i = 0; i < length2; i++) { const component = vectorComponents[i]; if (component === components[componentIndex]) { snippetValues.push("1.0 - " + (sourceProperty + "." + component)); componentIndex++; } else { snippetValues.push(sourceProperty + "." + component); } } return `${builder.getType(sourceType)}( ${snippetValues.join(", ")} )`; } }; var InputNode = class extends Node { static get type() { return "InputNode"; } constructor(value, nodeType = null) { super(nodeType); this.isInputNode = true; this.value = value; this.precision = null; } getNodeType() { if (this.nodeType === null) { return getValueType(this.value); } return this.nodeType; } getInputType(builder) { return this.getNodeType(builder); } setPrecision(precision) { this.precision = precision; return this; } serialize(data) { super.serialize(data); data.value = this.value; if (this.value && this.value.toArray) data.value = this.value.toArray(); data.valueType = getValueType(this.value); data.nodeType = this.nodeType; if (data.valueType === "ArrayBuffer") data.value = arrayBufferToBase64(data.value); data.precision = this.precision; } deserialize(data) { super.deserialize(data); this.nodeType = data.nodeType; this.value = Array.isArray(data.value) ? getValueFromType(data.valueType, ...data.value) : data.value; this.precision = data.precision || null; if (this.value && this.value.fromArray) this.value = this.value.fromArray(data.value); } generate() { console.warn("Abstract function."); } }; var ConstNode = class extends InputNode { static get type() { return "ConstNode"; } constructor(value, nodeType = null) { super(value, nodeType); this.isConstNode = true; } generateConst(builder) { return builder.generateConst(this.getNodeType(builder), this.value); } generate(builder, output2) { const type = this.getNodeType(builder); return builder.format(this.generateConst(builder), type, output2); } }; var currentStack = null; var NodeElements = /* @__PURE__ */ new Map(); function addMethodChaining(name, nodeElement) { if (NodeElements.has(name)) { console.warn(`Redefinition of method chaining ${name}`); return; } if (typeof nodeElement !== "function") throw new Error(`Node element ${name} is not a function`); NodeElements.set(name, nodeElement); } var parseSwizzle = (props) => props.replace(/r|s/g, "x").replace(/g|t/g, "y").replace(/b|p/g, "z").replace(/a|q/g, "w"); var parseSwizzleAndSort = (props) => parseSwizzle(props).split("").sort().join(""); var shaderNodeHandler = { setup(NodeClosure, params) { const inputs = params.shift(); return NodeClosure(nodeObjects(inputs), ...params); }, get(node, prop, nodeObj) { if (typeof prop === "string" && node[prop] === void 0) { if (node.isStackNode !== true && prop === "assign") { return (...params) => { currentStack.assign(nodeObj, ...params); return nodeObj; }; } else if (NodeElements.has(prop)) { const nodeElement = NodeElements.get(prop); return node.isStackNode ? (...params) => nodeObj.add(nodeElement(...params)) : (...params) => nodeElement(nodeObj, ...params); } else if (prop === "self") { return node; } else if (prop.endsWith("Assign") && NodeElements.has(prop.slice(0, prop.length - "Assign".length))) { const nodeElement = NodeElements.get(prop.slice(0, prop.length - "Assign".length)); return node.isStackNode ? (...params) => nodeObj.assign(params[0], nodeElement(...params)) : (...params) => nodeObj.assign(nodeElement(nodeObj, ...params)); } else if (/^[xyzwrgbastpq]{1,4}$/.test(prop) === true) { prop = parseSwizzle(prop); return nodeObject(new SplitNode(nodeObj, prop)); } else if (/^set[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { prop = parseSwizzleAndSort(prop.slice(3).toLowerCase()); return (value) => nodeObject(new SetNode(node, prop, value)); } else if (/^flip[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { prop = parseSwizzleAndSort(prop.slice(4).toLowerCase()); return () => nodeObject(new FlipNode(nodeObject(node), prop)); } else if (prop === "width" || prop === "height" || prop === "depth") { if (prop === "width") prop = "x"; else if (prop === "height") prop = "y"; else if (prop === "depth") prop = "z"; return nodeObject(new SplitNode(node, prop)); } else if (/^\d+$/.test(prop) === true) { return nodeObject(new ArrayElementNode(nodeObj, new ConstNode(Number(prop), "uint"))); } } return Reflect.get(node, prop, nodeObj); }, set(node, prop, value, nodeObj) { if (typeof prop === "string" && node[prop] === void 0) { if (/^[xyzwrgbastpq]{1,4}$/.test(prop) === true || prop === "width" || prop === "height" || prop === "depth" || /^\d+$/.test(prop) === true) { nodeObj[prop].assign(value); return true; } } return Reflect.set(node, prop, value, nodeObj); } }; var nodeObjectsCacheMap = /* @__PURE__ */ new WeakMap(); var nodeBuilderFunctionsCacheMap = /* @__PURE__ */ new WeakMap(); var ShaderNodeObject = function(obj, altType = null) { const type = getValueType(obj); if (type === "node") { let nodeObject2 = nodeObjectsCacheMap.get(obj); if (nodeObject2 === void 0) { nodeObject2 = new Proxy(obj, shaderNodeHandler); nodeObjectsCacheMap.set(obj, nodeObject2); nodeObjectsCacheMap.set(nodeObject2, nodeObject2); } return nodeObject2; } else if (altType === null && (type === "float" || type === "boolean") || type && type !== "shader" && type !== "string") { return nodeObject(getConstNode(obj, altType)); } else if (type === "shader") { return Fn(obj); } return obj; }; var ShaderNodeObjects = function(objects, altType = null) { for (const name in objects) { objects[name] = nodeObject(objects[name], altType); } return objects; }; var ShaderNodeArray = function(array, altType = null) { const len = array.length; for (let i = 0; i < len; i++) { array[i] = nodeObject(array[i], altType); } return array; }; var ShaderNodeProxy = function(NodeClass, scope = null, factor = null, settings = null) { const assignNode = (node) => nodeObject(settings !== null ? Object.assign(node, settings) : node); if (scope === null) { return (...params) => { return assignNode(new NodeClass(...nodeArray(params))); }; } else if (factor !== null) { factor = nodeObject(factor); return (...params) => { return assignNode(new NodeClass(scope, ...nodeArray(params), factor)); }; } else { return (...params) => { return assignNode(new NodeClass(scope, ...nodeArray(params))); }; } }; var ShaderNodeImmutable = function(NodeClass, ...params) { return nodeObject(new NodeClass(...nodeArray(params))); }; var ShaderCallNodeInternal = class extends Node { constructor(shaderNode, inputNodes) { super(); this.shaderNode = shaderNode; this.inputNodes = inputNodes; } getNodeType(builder) { return this.shaderNode.nodeType || this.getOutputNode(builder).getNodeType(builder); } call(builder) { const { shaderNode, inputNodes } = this; const properties = builder.getNodeProperties(shaderNode); if (properties.onceOutput) return properties.onceOutput; let result = null; if (shaderNode.layout) { let functionNodesCacheMap = nodeBuilderFunctionsCacheMap.get(builder.constructor); if (functionNodesCacheMap === void 0) { functionNodesCacheMap = /* @__PURE__ */ new WeakMap(); nodeBuilderFunctionsCacheMap.set(builder.constructor, functionNodesCacheMap); } let functionNode = functionNodesCacheMap.get(shaderNode); if (functionNode === void 0) { functionNode = nodeObject(builder.buildFunctionNode(shaderNode)); functionNodesCacheMap.set(shaderNode, functionNode); } if (builder.currentFunctionNode !== null) { builder.currentFunctionNode.includes.push(functionNode); } result = nodeObject(functionNode.call(inputNodes)); } else { const jsFunc = shaderNode.jsFunc; const outputNode = inputNodes !== null ? jsFunc(inputNodes, builder) : jsFunc(builder); result = nodeObject(outputNode); } if (shaderNode.once) { properties.onceOutput = result; } return result; } getOutputNode(builder) { const properties = builder.getNodeProperties(this); if (properties.outputNode === null) { properties.outputNode = this.setupOutput(builder); } return properties.outputNode; } setup(builder) { return this.getOutputNode(builder); } setupOutput(builder) { builder.addStack(); builder.stack.outputNode = this.call(builder); return builder.removeStack(); } generate(builder, output2) { const outputNode = this.getOutputNode(builder); return outputNode.build(builder, output2); } }; var ShaderNodeInternal = class extends Node { constructor(jsFunc, nodeType) { super(nodeType); this.jsFunc = jsFunc; this.layout = null; this.global = true; this.once = false; } setLayout(layout) { this.layout = layout; return this; } call(inputs = null) { nodeObjects(inputs); return nodeObject(new ShaderCallNodeInternal(this, inputs)); } setup() { return this.call(); } }; var bools = [false, true]; var uints = [0, 1, 2, 3]; var ints = [-1, -2]; var floats = [0.5, 1.5, 1 / 3, 1e-6, 1e6, Math.PI, Math.PI * 2, 1 / Math.PI, 2 / Math.PI, 1 / (Math.PI * 2), Math.PI / 2]; var boolsCacheMap = /* @__PURE__ */ new Map(); for (const bool2 of bools) boolsCacheMap.set(bool2, new ConstNode(bool2)); var uintsCacheMap = /* @__PURE__ */ new Map(); for (const uint2 of uints) uintsCacheMap.set(uint2, new ConstNode(uint2, "uint")); var intsCacheMap = new Map([...uintsCacheMap].map((el) => new ConstNode(el.value, "int"))); for (const int2 of ints) intsCacheMap.set(int2, new ConstNode(int2, "int")); var floatsCacheMap = new Map([...intsCacheMap].map((el) => new ConstNode(el.value))); for (const float2 of floats) floatsCacheMap.set(float2, new ConstNode(float2)); for (const float2 of floats) floatsCacheMap.set(-float2, new ConstNode(-float2)); var cacheMaps = { bool: boolsCacheMap, uint: uintsCacheMap, ints: intsCacheMap, float: floatsCacheMap }; var constNodesCacheMap = new Map([...boolsCacheMap, ...floatsCacheMap]); var getConstNode = (value, type) => { if (constNodesCacheMap.has(value)) { return constNodesCacheMap.get(value); } else if (value.isNode === true) { return value; } else { return new ConstNode(value, type); } }; var safeGetNodeType = (node) => { try { return node.getNodeType(); } catch (_) { return void 0; } }; var ConvertType = function(type, cacheMap = null) { return (...params) => { if (params.length === 0 || !["bool", "float", "int", "uint"].includes(type) && params.every((param) => typeof param !== "object")) { params = [getValueFromType(type, ...params)]; } if (params.length === 1 && cacheMap !== null && cacheMap.has(params[0])) { return nodeObject(cacheMap.get(params[0])); } if (params.length === 1) { const node = getConstNode(params[0], type); if (safeGetNodeType(node) === type) return nodeObject(node); return nodeObject(new ConvertNode(node, type)); } const nodes = params.map((param) => getConstNode(param)); return nodeObject(new JoinNode(nodes, type)); }; }; var defined = (v) => typeof v === "object" && v !== null ? v.value : v; var getConstNodeType = (value) => value !== void 0 && value !== null ? value.nodeType || value.convertTo || (typeof value === "string" ? value : null) : null; function ShaderNode(jsFunc, nodeType) { return new Proxy(new ShaderNodeInternal(jsFunc, nodeType), shaderNodeHandler); } var nodeObject = (val, altType = null) => ( /* new */ ShaderNodeObject(val, altType) ); var nodeObjects = (val, altType = null) => new ShaderNodeObjects(val, altType); var nodeArray = (val, altType = null) => new ShaderNodeArray(val, altType); var nodeProxy = (...params) => new ShaderNodeProxy(...params); var nodeImmutable = (...params) => new ShaderNodeImmutable(...params); var Fn = (jsFunc, nodeType) => { const shaderNode = new ShaderNode(jsFunc, nodeType); const fn = (...params) => { let inputs; nodeObjects(params); if (params[0] && params[0].isNode) { inputs = [...params]; } else { inputs = params[0]; } return shaderNode.call(inputs); }; fn.shaderNode = shaderNode; fn.setLayout = (layout) => { shaderNode.setLayout(layout); return fn; }; fn.once = () => { shaderNode.once = true; return fn; }; return fn; }; addMethodChaining("toGlobal", (node) => { node.global = true; return node; }); var setCurrentStack = (stack2) => { currentStack = stack2; }; var getCurrentStack = () => currentStack; var If = (...params) => currentStack.If(...params); function append(node) { if (currentStack) currentStack.add(node); return node; } addMethodChaining("append", append); var color = new ConvertType("color"); var float = new ConvertType("float", cacheMaps.float); var int = new ConvertType("int", cacheMaps.ints); var uint = new ConvertType("uint", cacheMaps.uint); var bool = new ConvertType("bool", cacheMaps.bool); var vec2 = new ConvertType("vec2"); var ivec2 = new ConvertType("ivec2"); var uvec2 = new ConvertType("uvec2"); var bvec2 = new ConvertType("bvec2"); var vec3 = new ConvertType("vec3"); var ivec3 = new ConvertType("ivec3"); var uvec3 = new ConvertType("uvec3"); var bvec3 = new ConvertType("bvec3"); var vec4 = new ConvertType("vec4"); var ivec4 = new ConvertType("ivec4"); var uvec4 = new ConvertType("uvec4"); var bvec4 = new ConvertType("bvec4"); var mat2 = new ConvertType("mat2"); var mat3 = new ConvertType("mat3"); var mat4 = new ConvertType("mat4"); addMethodChaining("toColor", color); addMethodChaining("toFloat", float); addMethodChaining("toInt", int); addMethodChaining("toUint", uint); addMethodChaining("toBool", bool); addMethodChaining("toVec2", vec2); addMethodChaining("toIVec2", ivec2); addMethodChaining("toUVec2", uvec2); addMethodChaining("toBVec2", bvec2); addMethodChaining("toVec3", vec3); addMethodChaining("toIVec3", ivec3); addMethodChaining("toUVec3", uvec3); addMethodChaining("toBVec3", bvec3); addMethodChaining("toVec4", vec4); addMethodChaining("toIVec4", ivec4); addMethodChaining("toUVec4", uvec4); addMethodChaining("toBVec4", bvec4); addMethodChaining("toMat2", mat2); addMethodChaining("toMat3", mat3); addMethodChaining("toMat4", mat4); var element = /* @__PURE__ */ nodeProxy(ArrayElementNode); var convert = (node, types) => nodeObject(new ConvertNode(nodeObject(node), types)); addMethodChaining("element", element); addMethodChaining("convert", convert); var UniformGroupNode = class extends Node { static get type() { return "UniformGroupNode"; } constructor(name, shared = false, order = 1) { super("string"); this.name = name; this.version = 0; this.shared = shared; this.order = order; this.isUniformGroup = true; } set needsUpdate(value) { if (value === true) this.version++; } serialize(data) { super.serialize(data); data.name = this.name; data.version = this.version; data.shared = this.shared; } deserialize(data) { super.deserialize(data); this.name = data.name; this.version = data.version; this.shared = data.shared; } }; var uniformGroup = (name) => new UniformGroupNode(name); var sharedUniformGroup = (name, order = 0) => new UniformGroupNode(name, true, order); var frameGroup = /* @__PURE__ */ sharedUniformGroup("frame"); var renderGroup = /* @__PURE__ */ sharedUniformGroup("render"); var objectGroup = /* @__PURE__ */ uniformGroup("object"); var UniformNode = class extends InputNode { static get type() { return "UniformNode"; } constructor(value, nodeType = null) { super(value, nodeType); this.isUniformNode = true; this.name = ""; this.groupNode = objectGroup; } label(name) { this.name = name; return this; } setGroup(group) { this.groupNode = group; return this; } getGroup() { return this.groupNode; } getUniformHash(builder) { return this.getHash(builder); } onUpdate(callback, updateType) { const self2 = this.getSelf(); callback = callback.bind(self2); return super.onUpdate((frame2) => { const value = callback(frame2, self2); if (value !== void 0) { this.value = value; } }, updateType); } generate(builder, output2) { const type = this.getNodeType(builder); const hash = this.getUniformHash(builder); let sharedNode = builder.getNodeFromHash(hash); if (sharedNode === void 0) { builder.setHashNode(this, hash); sharedNode = this; } const sharedNodeType = sharedNode.getInputType(builder); const nodeUniform = builder.getUniformFromNode(sharedNode, sharedNodeType, builder.shaderStage, this.name || builder.context.label); const propertyName = builder.getPropertyName(nodeUniform); if (builder.context.label !== void 0) delete builder.context.label; return builder.format(propertyName, type, output2); } }; var uniform = (arg1, arg2) => { const nodeType = getConstNodeType(arg2 || arg1); const value = arg1 && arg1.isNode === true ? arg1.node && arg1.node.value || arg1.value : arg1; return nodeObject(new UniformNode(value, nodeType)); }; var PropertyNode = class extends Node { static get type() { return "PropertyNode"; } constructor(nodeType, name = null, varying2 = false) { super(nodeType); this.name = name; this.varying = varying2; this.isPropertyNode = true; } getHash(builder) { return this.name || super.getHash(builder); } isGlobal() { return true; } generate(builder) { let nodeVar; if (this.varying === true) { nodeVar = builder.getVaryingFromNode(this, this.name); nodeVar.needsInterpolation = true; } else { nodeVar = builder.getVarFromNode(this, this.name); } return builder.getPropertyName(nodeVar); } }; var property = (type, name) => nodeObject(new PropertyNode(type, name)); var varyingProperty = (type, name) => nodeObject(new PropertyNode(type, name, true)); var diffuseColor = /* @__PURE__ */ nodeImmutable(PropertyNode, "vec4", "DiffuseColor"); var emissive = /* @__PURE__ */ nodeImmutable(PropertyNode, "vec3", "EmissiveColor"); var roughness = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "Roughness"); var metalness = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "Metalness"); var clearcoat = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "Clearcoat"); var clearcoatRoughness = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "ClearcoatRoughness"); var sheen = /* @__PURE__ */ nodeImmutable(PropertyNode, "vec3", "Sheen"); var sheenRoughness = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "SheenRoughness"); var iridescence = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "Iridescence"); var iridescenceIOR = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "IridescenceIOR"); var iridescenceThickness = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "IridescenceThickness"); var alphaT = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "AlphaT"); var anisotropy = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "Anisotropy"); var anisotropyT = /* @__PURE__ */ nodeImmutable(PropertyNode, "vec3", "AnisotropyT"); var anisotropyB = /* @__PURE__ */ nodeImmutable(PropertyNode, "vec3", "AnisotropyB"); var specularColor = /* @__PURE__ */ nodeImmutable(PropertyNode, "color", "SpecularColor"); var specularF90 = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "SpecularF90"); var shininess = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "Shininess"); var output = /* @__PURE__ */ nodeImmutable(PropertyNode, "vec4", "Output"); var dashSize = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "dashSize"); var gapSize = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "gapSize"); var ior = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "IOR"); var transmission = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "Transmission"); var thickness = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "Thickness"); var attenuationDistance = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "AttenuationDistance"); var attenuationColor = /* @__PURE__ */ nodeImmutable(PropertyNode, "color", "AttenuationColor"); var dispersion = /* @__PURE__ */ nodeImmutable(PropertyNode, "float", "Dispersion"); var AssignNode = class extends TempNode { static get type() { return "AssignNode"; } constructor(targetNode, sourceNode) { super(); this.targetNode = targetNode; this.sourceNode = sourceNode; } hasDependencies() { return false; } getNodeType(builder, output2) { return output2 !== "void" ? this.targetNode.getNodeType(builder) : "void"; } needsSplitAssign(builder) { const { targetNode } = this; if (builder.isAvailable("swizzleAssign") === false && targetNode.isSplitNode && targetNode.components.length > 1) { const targetLength = builder.getTypeLength(targetNode.node.getNodeType(builder)); const assignDiferentVector = vectorComponents.join("").slice(0, targetLength) !== targetNode.components; return assignDiferentVector; } return false; } generate(builder, output2) { const { targetNode, sourceNode } = this; const needsSplitAssign = this.needsSplitAssign(builder); const targetType = targetNode.getNodeType(builder); const target = targetNode.context({ assign: true }).build(builder); const source = sourceNode.build(builder, targetType); const sourceType = sourceNode.getNodeType(builder); const nodeData = builder.getDataFromNode(this); let snippet; if (nodeData.initialized === true) { if (output2 !== "void") { snippet = target; } } else if (needsSplitAssign) { const sourceVar = builder.getVarFromNode(this, null, targetType); const sourceProperty = builder.getPropertyName(sourceVar); builder.addLineFlowCode(`${sourceProperty} = ${source}`, this); const targetRoot = targetNode.node.context({ assign: true }).build(builder); for (let i = 0; i < targetNode.components.length; i++) { const component = targetNode.components[i]; builder.addLineFlowCode(`${targetRoot}.${component} = ${sourceProperty}[ ${i} ]`, this); } if (output2 !== "void") { snippet = target; } } else { snippet = `${target} = ${source}`; if (output2 === "void" || sourceType === "void") { builder.addLineFlowCode(snippet, this); if (output2 !== "void") { snippet = target; } } } nodeData.initialized = true; return builder.format(snippet, targetType, output2); } }; var assign = /* @__PURE__ */ nodeProxy(AssignNode); addMethodChaining("assign", assign); var FunctionCallNode = class extends TempNode { static get type() { return "FunctionCallNode"; } constructor(functionNode = null, parameters = {}) { super(); this.functionNode = functionNode; this.parameters = parameters; } setParameters(parameters) { this.parameters = parameters; return this; } getParameters() { return this.parameters; } getNodeType(builder) { return this.functionNode.getNodeType(builder); } generate(builder) { const params = []; const functionNode = this.functionNode; const inputs = functionNode.getInputs(builder); const parameters = this.parameters; const generateInput = (node, inputNode) => { const type = inputNode.type; const pointer = type === "pointer"; let output2; if (pointer) output2 = "&" + node.build(builder); else output2 = node.build(builder, type); return output2; }; if (Array.isArray(parameters)) { for (let i = 0; i < parameters.length; i++) { params.push(generateInput(parameters[i], inputs[i])); } } else { for (const inputNode of inputs) { const node = parameters[inputNode.name]; if (node !== void 0) { params.push(generateInput(node, inputNode)); } else { throw new Error(`FunctionCallNode: Input '${inputNode.name}' not found in FunctionNode.`); } } } const functionName = functionNode.build(builder, "property"); return `${functionName}( ${params.join(", ")} )`; } }; var call = (func, ...params) => { params = params.length > 1 || params[0] && params[0].isNode === true ? nodeArray(params) : nodeObjects(params[0]); return nodeObject(new FunctionCallNode(nodeObject(func), params)); }; addMethodChaining("call", call); var OperatorNode = class _OperatorNode extends TempNode { static get type() { return "OperatorNode"; } constructor(op, aNode, bNode, ...params) { super(); if (params.length > 0) { let finalOp = new _OperatorNode(op, aNode, bNode); for (let i = 0; i < params.length - 1; i++) { finalOp = new _OperatorNode(op, finalOp, params[i]); } aNode = finalOp; bNode = params[params.length - 1]; } this.op = op; this.aNode = aNode; this.bNode = bNode; } getNodeType(builder, output2) { const op = this.op; const aNode = this.aNode; const bNode = this.bNode; const typeA = aNode.getNodeType(builder); const typeB = typeof bNode !== "undefined" ? bNode.getNodeType(builder) : null; if (typeA === "void" || typeB === "void") { return "void"; } else if (op === "%") { return typeA; } else if (op === "~" || op === "&" || op === "|" || op === "^" || op === ">>" || op === "<<") { return builder.getIntegerType(typeA); } else if (op === "!" || op === "==" || op === "&&" || op === "||" || op === "^^") { return "bool"; } else if (op === "<" || op === ">" || op === "<=" || op === ">=") { const typeLength = output2 ? builder.getTypeLength(output2) : Math.max(builder.getTypeLength(typeA), builder.getTypeLength(typeB)); return typeLength > 1 ? `bvec${typeLength}` : "bool"; } else { if (typeA === "float" && builder.isMatrix(typeB)) { return typeB; } else if (builder.isMatrix(typeA) && builder.isVector(typeB)) { return builder.getVectorFromMatrix(typeA); } else if (builder.isVector(typeA) && builder.isMatrix(typeB)) { return builder.getVectorFromMatrix(typeB); } else if (builder.getTypeLength(typeB) > builder.getTypeLength(typeA)) { return typeB; } return typeA; } } generate(builder, output2) { const op = this.op; const aNode = this.aNode; const bNode = this.bNode; const type = this.getNodeType(builder, output2); let typeA = null; let typeB = null; if (type !== "void") { typeA = aNode.getNodeType(builder); typeB = typeof bNode !== "undefined" ? bNode.getNodeType(builder) : null; if (op === "<" || op === ">" || op === "<=" || op === ">=" || op === "==") { if (builder.isVector(typeA)) { typeB = typeA; } else if (typeA !== typeB) { typeA = typeB = "float"; } } else if (op === ">>" || op === "<<") { typeA = type; typeB = builder.changeComponentType(typeB, "uint"); } else if (builder.isMatrix(typeA) && builder.isVector(typeB)) { typeB = builder.getVectorFromMatrix(typeA); } else if (builder.isVector(typeA) && builder.isMatrix(typeB)) { typeA = builder.getVectorFromMatrix(typeB); } else { typeA = typeB = type; } } else { typeA = typeB = type; } const a2 = aNode.build(builder, typeA); const b = typeof bNode !== "undefined" ? bNode.build(builder, typeB) : null; const outputLength = builder.getTypeLength(output2); const fnOpSnippet = builder.getFunctionOperator(op); if (output2 !== "void") { if (op === "<" && outputLength > 1) { if (builder.useComparisonMethod) { return builder.format(`${builder.getMethod("lessThan", output2)}( ${a2}, ${b} )`, type, output2); } else { return builder.format(`( ${a2} < ${b} )`, type, output2); } } else if (op === "<=" && outputLength > 1) { if (builder.useComparisonMethod) { return builder.format(`${builder.getMethod("lessThanEqual", output2)}( ${a2}, ${b} )`, type, output2); } else { return builder.format(`( ${a2} <= ${b} )`, type, output2); } } else if (op === ">" && outputLength > 1) { if (builder.useComparisonMethod) { return builder.format(`${builder.getMethod("greaterThan", output2)}( ${a2}, ${b} )`, type, output2); } else { return builder.format(`( ${a2} > ${b} )`, type, output2); } } else if (op === ">=" && outputLength > 1) { if (builder.useComparisonMethod) { return builder.format(`${builder.getMethod("greaterThanEqual", output2)}( ${a2}, ${b} )`, type, output2); } else { return builder.format(`( ${a2} >= ${b} )`, type, output2); } } else if (op === "!" || op === "~") { return builder.format(`(${op}${a2})`, typeA, output2); } else if (fnOpSnippet) { return builder.format(`${fnOpSnippet}( ${a2}, ${b} )`, type, output2); } else { return builder.format(`( ${a2} ${op} ${b} )`, type, output2); } } else if (typeA !== "void") { if (fnOpSnippet) { return builder.format(`${fnOpSnippet}( ${a2}, ${b} )`, type, output2); } else { return builder.format(`${a2} ${op} ${b}`, type, output2); } } } serialize(data) { super.serialize(data); data.op = this.op; } deserialize(data) { super.deserialize(data); this.op = data.op; } }; var add4 = /* @__PURE__ */ nodeProxy(OperatorNode, "+"); var sub = /* @__PURE__ */ nodeProxy(OperatorNode, "-"); var mul = /* @__PURE__ */ nodeProxy(OperatorNode, "*"); var div = /* @__PURE__ */ nodeProxy(OperatorNode, "/"); var modInt = /* @__PURE__ */ nodeProxy(OperatorNode, "%"); var equal = /* @__PURE__ */ nodeProxy(OperatorNode, "=="); var notEqual = /* @__PURE__ */ nodeProxy(OperatorNode, "!="); var lessThan = /* @__PURE__ */ nodeProxy(OperatorNode, "<"); var greaterThan = /* @__PURE__ */ nodeProxy(OperatorNode, ">"); var lessThanEqual = /* @__PURE__ */ nodeProxy(OperatorNode, "<="); var greaterThanEqual = /* @__PURE__ */ nodeProxy(OperatorNode, ">="); var and = /* @__PURE__ */ nodeProxy(OperatorNode, "&&"); var or = /* @__PURE__ */ nodeProxy(OperatorNode, "||"); var not = /* @__PURE__ */ nodeProxy(OperatorNode, "!"); var xor = /* @__PURE__ */ nodeProxy(OperatorNode, "^^"); var bitAnd = /* @__PURE__ */ nodeProxy(OperatorNode, "&"); var bitNot = /* @__PURE__ */ nodeProxy(OperatorNode, "~"); var bitOr = /* @__PURE__ */ nodeProxy(OperatorNode, "|"); var bitXor = /* @__PURE__ */ nodeProxy(OperatorNode, "^"); var shiftLeft = /* @__PURE__ */ nodeProxy(OperatorNode, "<<"); var shiftRight = /* @__PURE__ */ nodeProxy(OperatorNode, ">>"); addMethodChaining("add", add4); addMethodChaining("sub", sub); addMethodChaining("mul", mul); addMethodChaining("div", div); addMethodChaining("modInt", modInt); addMethodChaining("equal", equal); addMethodChaining("notEqual", notEqual); addMethodChaining("lessThan", lessThan); addMethodChaining("greaterThan", greaterThan); addMethodChaining("lessThanEqual", lessThanEqual); addMethodChaining("greaterThanEqual", greaterThanEqual); addMethodChaining("and", and); addMethodChaining("or", or); addMethodChaining("not", not); addMethodChaining("xor", xor); addMethodChaining("bitAnd", bitAnd); addMethodChaining("bitNot", bitNot); addMethodChaining("bitOr", bitOr); addMethodChaining("bitXor", bitXor); addMethodChaining("shiftLeft", shiftLeft); addMethodChaining("shiftRight", shiftRight); var remainder = (...params) => { console.warn("TSL.OperatorNode: .remainder() has been renamed to .modInt()."); return modInt(...params); }; addMethodChaining("remainder", remainder); var MathNode = class _MathNode extends TempNode { static get type() { return "MathNode"; } constructor(method, aNode, bNode = null, cNode = null) { super(); this.method = method; this.aNode = aNode; this.bNode = bNode; this.cNode = cNode; } getInputType(builder) { const aType = this.aNode.getNodeType(builder); const bType = this.bNode ? this.bNode.getNodeType(builder) : null; const cType = this.cNode ? this.cNode.getNodeType(builder) : null; const aLen = builder.isMatrix(aType) ? 0 : builder.getTypeLength(aType); const bLen = builder.isMatrix(bType) ? 0 : builder.getTypeLength(bType); const cLen = builder.isMatrix(cType) ? 0 : builder.getTypeLength(cType); if (aLen > bLen && aLen > cLen) { return aType; } else if (bLen > cLen) { return bType; } else if (cLen > aLen) { return cType; } return aType; } getNodeType(builder) { const method = this.method; if (method === _MathNode.LENGTH || method === _MathNode.DISTANCE || method === _MathNode.DOT) { return "float"; } else if (method === _MathNode.CROSS) { return "vec3"; } else if (method === _MathNode.ALL) { return "bool"; } else if (method === _MathNode.EQUALS) { return builder.changeComponentType(this.aNode.getNodeType(builder), "bool"); } else if (method === _MathNode.MOD) { return this.aNode.getNodeType(builder); } else { return this.getInputType(builder); } } generate(builder, output2) { const method = this.method; const type = this.getNodeType(builder); const inputType = this.getInputType(builder); const a2 = this.aNode; const b = this.bNode; const c2 = this.cNode; const isWebGL = builder.renderer.isWebGLRenderer === true; if (method === _MathNode.TRANSFORM_DIRECTION) { let tA = a2; let tB = b; if (builder.isMatrix(tA.getNodeType(builder))) { tB = vec4(vec3(tB), 0); } else { tA = vec4(vec3(tA), 0); } const mulNode = mul(tA, tB).xyz; return normalize2(mulNode).build(builder, output2); } else if (method === _MathNode.NEGATE) { return builder.format("( - " + a2.build(builder, inputType) + " )", type, output2); } else if (method === _MathNode.ONE_MINUS) { return sub(1, a2).build(builder, output2); } else if (method === _MathNode.RECIPROCAL) { return div(1, a2).build(builder, output2); } else if (method === _MathNode.DIFFERENCE) { return abs(sub(a2, b)).build(builder, output2); } else { const params = []; if (method === _MathNode.CROSS || method === _MathNode.MOD) { params.push( a2.build(builder, type), b.build(builder, type) ); } else if (isWebGL && method === _MathNode.STEP) { params.push( a2.build(builder, builder.getTypeLength(a2.getNodeType(builder)) === 1 ? "float" : inputType), b.build(builder, inputType) ); } else if (isWebGL && (method === _MathNode.MIN || method === _MathNode.MAX) || method === _MathNode.MOD) { params.push( a2.build(builder, inputType), b.build(builder, builder.getTypeLength(b.getNodeType(builder)) === 1 ? "float" : inputType) ); } else if (method === _MathNode.REFRACT) { params.push( a2.build(builder, inputType), b.build(builder, inputType), c2.build(builder, "float") ); } else if (method === _MathNode.MIX) { params.push( a2.build(builder, inputType), b.build(builder, inputType), c2.build(builder, builder.getTypeLength(c2.getNodeType(builder)) === 1 ? "float" : inputType) ); } else { params.push(a2.build(builder, inputType)); if (b !== null) params.push(b.build(builder, inputType)); if (c2 !== null) params.push(c2.build(builder, inputType)); } return builder.format(`${builder.getMethod(method, type)}( ${params.join(", ")} )`, type, output2); } } serialize(data) { super.serialize(data); data.method = this.method; } deserialize(data) { super.deserialize(data); this.method = data.method; } }; MathNode.ALL = "all"; MathNode.ANY = "any"; MathNode.EQUALS = "equals"; MathNode.RADIANS = "radians"; MathNode.DEGREES = "degrees"; MathNode.EXP = "exp"; MathNode.EXP2 = "exp2"; MathNode.LOG = "log"; MathNode.LOG2 = "log2"; MathNode.SQRT = "sqrt"; MathNode.INVERSE_SQRT = "inversesqrt"; MathNode.FLOOR = "floor"; MathNode.CEIL = "ceil"; MathNode.NORMALIZE = "normalize"; MathNode.FRACT = "fract"; MathNode.SIN = "sin"; MathNode.COS = "cos"; MathNode.TAN = "tan"; MathNode.ASIN = "asin"; MathNode.ACOS = "acos"; MathNode.ATAN = "atan"; MathNode.ABS = "abs"; MathNode.SIGN = "sign"; MathNode.LENGTH = "length"; MathNode.NEGATE = "negate"; MathNode.ONE_MINUS = "oneMinus"; MathNode.DFDX = "dFdx"; MathNode.DFDY = "dFdy"; MathNode.ROUND = "round"; MathNode.RECIPROCAL = "reciprocal"; MathNode.TRUNC = "trunc"; MathNode.FWIDTH = "fwidth"; MathNode.BITCAST = "bitcast"; MathNode.TRANSPOSE = "transpose"; MathNode.ATAN2 = "atan2"; MathNode.MIN = "min"; MathNode.MAX = "max"; MathNode.MOD = "mod"; MathNode.STEP = "step"; MathNode.REFLECT = "reflect"; MathNode.DISTANCE = "distance"; MathNode.DIFFERENCE = "difference"; MathNode.DOT = "dot"; MathNode.CROSS = "cross"; MathNode.POW = "pow"; MathNode.TRANSFORM_DIRECTION = "transformDirection"; MathNode.MIX = "mix"; MathNode.CLAMP = "clamp"; MathNode.REFRACT = "refract"; MathNode.SMOOTHSTEP = "smoothstep"; MathNode.FACEFORWARD = "faceforward"; var EPSILON = /* @__PURE__ */ float(1e-6); var PI = /* @__PURE__ */ float(Math.PI); var PI2 = /* @__PURE__ */ float(Math.PI * 2); var all = /* @__PURE__ */ nodeProxy(MathNode, MathNode.ALL); var any = /* @__PURE__ */ nodeProxy(MathNode, MathNode.ANY); var equals = /* @__PURE__ */ nodeProxy(MathNode, MathNode.EQUALS); var radians = /* @__PURE__ */ nodeProxy(MathNode, MathNode.RADIANS); var degrees = /* @__PURE__ */ nodeProxy(MathNode, MathNode.DEGREES); var exp = /* @__PURE__ */ nodeProxy(MathNode, MathNode.EXP); var exp2 = /* @__PURE__ */ nodeProxy(MathNode, MathNode.EXP2); var log = /* @__PURE__ */ nodeProxy(MathNode, MathNode.LOG); var log2 = /* @__PURE__ */ nodeProxy(MathNode, MathNode.LOG2); var sqrt = /* @__PURE__ */ nodeProxy(MathNode, MathNode.SQRT); var inverseSqrt = /* @__PURE__ */ nodeProxy(MathNode, MathNode.INVERSE_SQRT); var floor = /* @__PURE__ */ nodeProxy(MathNode, MathNode.FLOOR); var ceil = /* @__PURE__ */ nodeProxy(MathNode, MathNode.CEIL); var normalize2 = /* @__PURE__ */ nodeProxy(MathNode, MathNode.NORMALIZE); var fract = /* @__PURE__ */ nodeProxy(MathNode, MathNode.FRACT); var sin = /* @__PURE__ */ nodeProxy(MathNode, MathNode.SIN); var cos = /* @__PURE__ */ nodeProxy(MathNode, MathNode.COS); var tan = /* @__PURE__ */ nodeProxy(MathNode, MathNode.TAN); var asin = /* @__PURE__ */ nodeProxy(MathNode, MathNode.ASIN); var acos = /* @__PURE__ */ nodeProxy(MathNode, MathNode.ACOS); var atan = /* @__PURE__ */ nodeProxy(MathNode, MathNode.ATAN); var abs = /* @__PURE__ */ nodeProxy(MathNode, MathNode.ABS); var sign = /* @__PURE__ */ nodeProxy(MathNode, MathNode.SIGN); var length = /* @__PURE__ */ nodeProxy(MathNode, MathNode.LENGTH); var negate = /* @__PURE__ */ nodeProxy(MathNode, MathNode.NEGATE); var oneMinus = /* @__PURE__ */ nodeProxy(MathNode, MathNode.ONE_MINUS); var dFdx = /* @__PURE__ */ nodeProxy(MathNode, MathNode.DFDX); var dFdy = /* @__PURE__ */ nodeProxy(MathNode, MathNode.DFDY); var round = /* @__PURE__ */ nodeProxy(MathNode, MathNode.ROUND); var reciprocal = /* @__PURE__ */ nodeProxy(MathNode, MathNode.RECIPROCAL); var trunc = /* @__PURE__ */ nodeProxy(MathNode, MathNode.TRUNC); var fwidth = /* @__PURE__ */ nodeProxy(MathNode, MathNode.FWIDTH); var bitcast = /* @__PURE__ */ nodeProxy(MathNode, MathNode.BITCAST); var transpose = /* @__PURE__ */ nodeProxy(MathNode, MathNode.TRANSPOSE); var atan2 = /* @__PURE__ */ nodeProxy(MathNode, MathNode.ATAN2); var min$1 = /* @__PURE__ */ nodeProxy(MathNode, MathNode.MIN); var max$1 = /* @__PURE__ */ nodeProxy(MathNode, MathNode.MAX); var mod = /* @__PURE__ */ nodeProxy(MathNode, MathNode.MOD); var step = /* @__PURE__ */ nodeProxy(MathNode, MathNode.STEP); var reflect = /* @__PURE__ */ nodeProxy(MathNode, MathNode.REFLECT); var distance = /* @__PURE__ */ nodeProxy(MathNode, MathNode.DISTANCE); var difference = /* @__PURE__ */ nodeProxy(MathNode, MathNode.DIFFERENCE); var dot = /* @__PURE__ */ nodeProxy(MathNode, MathNode.DOT); var cross = /* @__PURE__ */ nodeProxy(MathNode, MathNode.CROSS); var pow = /* @__PURE__ */ nodeProxy(MathNode, MathNode.POW); var pow2 = /* @__PURE__ */ nodeProxy(MathNode, MathNode.POW, 2); var pow3 = /* @__PURE__ */ nodeProxy(MathNode, MathNode.POW, 3); var pow4 = /* @__PURE__ */ nodeProxy(MathNode, MathNode.POW, 4); var transformDirection = /* @__PURE__ */ nodeProxy(MathNode, MathNode.TRANSFORM_DIRECTION); var cbrt = (a2) => mul(sign(a2), pow(abs(a2), 1 / 3)); var lengthSq = (a2) => dot(a2, a2); var mix = /* @__PURE__ */ nodeProxy(MathNode, MathNode.MIX); var clamp2 = (value, low = 0, high = 1) => nodeObject(new MathNode(MathNode.CLAMP, nodeObject(value), nodeObject(low), nodeObject(high))); var saturate2 = (value) => clamp2(value); var refract = /* @__PURE__ */ nodeProxy(MathNode, MathNode.REFRACT); var smoothstep2 = /* @__PURE__ */ nodeProxy(MathNode, MathNode.SMOOTHSTEP); var faceForward = /* @__PURE__ */ nodeProxy(MathNode, MathNode.FACEFORWARD); var rand = /* @__PURE__ */ Fn(([uv2]) => { const a2 = 12.9898, b = 78.233, c2 = 43758.5453; const dt = dot(uv2.xy, vec2(a2, b)), sn = mod(dt, PI); return fract(sin(sn).mul(c2)); }); var mixElement = (t, e1, e2) => mix(e1, e2, t); var smoothstepElement = (x2, low, high) => smoothstep2(low, high, x2); addMethodChaining("all", all); addMethodChaining("any", any); addMethodChaining("equals", equals); addMethodChaining("radians", radians); addMethodChaining("degrees", degrees); addMethodChaining("exp", exp); addMethodChaining("exp2", exp2); addMethodChaining("log", log); addMethodChaining("log2", log2); addMethodChaining("sqrt", sqrt); addMethodChaining("inverseSqrt", inverseSqrt); addMethodChaining("floor", floor); addMethodChaining("ceil", ceil); addMethodChaining("normalize", normalize2); addMethodChaining("fract", fract); addMethodChaining("sin", sin); addMethodChaining("cos", cos); addMethodChaining("tan", tan); addMethodChaining("asin", asin); addMethodChaining("acos", acos); addMethodChaining("atan", atan); addMethodChaining("abs", abs); addMethodChaining("sign", sign); addMethodChaining("length", length); addMethodChaining("lengthSq", lengthSq); addMethodChaining("negate", negate); addMethodChaining("oneMinus", oneMinus); addMethodChaining("dFdx", dFdx); addMethodChaining("dFdy", dFdy); addMethodChaining("round", round); addMethodChaining("reciprocal", reciprocal); addMethodChaining("trunc", trunc); addMethodChaining("fwidth", fwidth); addMethodChaining("atan2", atan2); addMethodChaining("min", min$1); addMethodChaining("max", max$1); addMethodChaining("mod", mod); addMethodChaining("step", step); addMethodChaining("reflect", reflect); addMethodChaining("distance", distance); addMethodChaining("dot", dot); addMethodChaining("cross", cross); addMethodChaining("pow", pow); addMethodChaining("pow2", pow2); addMethodChaining("pow3", pow3); addMethodChaining("pow4", pow4); addMethodChaining("transformDirection", transformDirection); addMethodChaining("mix", mixElement); addMethodChaining("clamp", clamp2); addMethodChaining("refract", refract); addMethodChaining("smoothstep", smoothstepElement); addMethodChaining("faceForward", faceForward); addMethodChaining("difference", difference); addMethodChaining("saturate", saturate2); addMethodChaining("cbrt", cbrt); addMethodChaining("transpose", transpose); addMethodChaining("rand", rand); var ConditionalNode = class extends Node { static get type() { return "ConditionalNode"; } constructor(condNode, ifNode, elseNode = null) { super(); this.condNode = condNode; this.ifNode = ifNode; this.elseNode = elseNode; } getNodeType(builder) { const ifType = this.ifNode.getNodeType(builder); if (this.elseNode !== null) { const elseType = this.elseNode.getNodeType(builder); if (builder.getTypeLength(elseType) > builder.getTypeLength(ifType)) { return elseType; } } return ifType; } setup(builder) { const condNode = this.condNode.cache(); const ifNode = this.ifNode.cache(); const elseNode = this.elseNode ? this.elseNode.cache() : null; const currentNodeBlock = builder.context.nodeBlock; builder.getDataFromNode(ifNode).parentNodeBlock = currentNodeBlock; if (elseNode !== null) builder.getDataFromNode(elseNode).parentNodeBlock = currentNodeBlock; const properties = builder.getNodeProperties(this); properties.condNode = condNode; properties.ifNode = ifNode.context({ nodeBlock: ifNode }); properties.elseNode = elseNode ? elseNode.context({ nodeBlock: elseNode }) : null; } generate(builder, output2) { const type = this.getNodeType(builder); const nodeData = builder.getDataFromNode(this); if (nodeData.nodeProperty !== void 0) { return nodeData.nodeProperty; } const { condNode, ifNode, elseNode } = builder.getNodeProperties(this); const needsOutput = output2 !== "void"; const nodeProperty = needsOutput ? property(type).build(builder) : ""; nodeData.nodeProperty = nodeProperty; const nodeSnippet = condNode.build(builder, "bool"); builder.addFlowCode(` ${builder.tab}if ( ${nodeSnippet} ) { `).addFlowTab(); let ifSnippet = ifNode.build(builder, type); if (ifSnippet) { if (needsOutput) { ifSnippet = nodeProperty + " = " + ifSnippet + ";"; } else { ifSnippet = "return " + ifSnippet + ";"; } } builder.removeFlowTab().addFlowCode(builder.tab + " " + ifSnippet + "\n\n" + builder.tab + "}"); if (elseNode !== null) { builder.addFlowCode(" else {\n\n").addFlowTab(); let elseSnippet = elseNode.build(builder, type); if (elseSnippet) { if (needsOutput) { elseSnippet = nodeProperty + " = " + elseSnippet + ";"; } else { elseSnippet = "return " + elseSnippet + ";"; } } builder.removeFlowTab().addFlowCode(builder.tab + " " + elseSnippet + "\n\n" + builder.tab + "}\n\n"); } else { builder.addFlowCode("\n\n"); } return builder.format(nodeProperty, type, output2); } }; var select = /* @__PURE__ */ nodeProxy(ConditionalNode); addMethodChaining("select", select); var cond = (...params) => { console.warn("TSL.ConditionalNode: cond() has been renamed to select()."); return select(...params); }; addMethodChaining("cond", cond); var ContextNode = class extends Node { static get type() { return "ContextNode"; } constructor(node, value = {}) { super(); this.isContextNode = true; this.node = node; this.value = value; } getScope() { return this.node.getScope(); } getNodeType(builder) { return this.node.getNodeType(builder); } analyze(builder) { this.node.build(builder); } setup(builder) { const previousContext = builder.getContext(); builder.setContext({ ...builder.context, ...this.value }); const node = this.node.build(builder); builder.setContext(previousContext); return node; } generate(builder, output2) { const previousContext = builder.getContext(); builder.setContext({ ...builder.context, ...this.value }); const snippet = this.node.build(builder, output2); builder.setContext(previousContext); return snippet; } }; var context = /* @__PURE__ */ nodeProxy(ContextNode); var label = (node, name) => context(node, { label: name }); addMethodChaining("context", context); addMethodChaining("label", label); var VarNode = class extends Node { static get type() { return "VarNode"; } constructor(node, name = null) { super(); this.node = node; this.name = name; this.global = true; this.isVarNode = true; } getHash(builder) { return this.name || super.getHash(builder); } getNodeType(builder) { return this.node.getNodeType(builder); } generate(builder) { const { node, name } = this; const nodeVar = builder.getVarFromNode(this, name, builder.getVectorType(this.getNodeType(builder))); const propertyName = builder.getPropertyName(nodeVar); const snippet = node.build(builder, nodeVar.type); builder.addLineFlowCode(`${propertyName} = ${snippet}`, this); return propertyName; } }; var createVar = /* @__PURE__ */ nodeProxy(VarNode); addMethodChaining("toVar", (...params) => createVar(...params).append()); var temp = (node) => { console.warn('TSL: "temp" is deprecated. Use ".toVar()" instead.'); return createVar(node); }; addMethodChaining("temp", temp); var VaryingNode = class extends Node { static get type() { return "VaryingNode"; } constructor(node, name = null) { super(); this.node = node; this.name = name; this.isVaryingNode = true; } isGlobal() { return true; } getHash(builder) { return this.name || super.getHash(builder); } getNodeType(builder) { return this.node.getNodeType(builder); } setupVarying(builder) { const properties = builder.getNodeProperties(this); let varying2 = properties.varying; if (varying2 === void 0) { const name = this.name; const type = this.getNodeType(builder); properties.varying = varying2 = builder.getVaryingFromNode(this, name, type); properties.node = this.node; } varying2.needsInterpolation || (varying2.needsInterpolation = builder.shaderStage === "fragment"); return varying2; } setup(builder) { this.setupVarying(builder); } analyze(builder) { this.setupVarying(builder); return this.node.analyze(builder); } generate(builder) { const properties = builder.getNodeProperties(this); const varying2 = this.setupVarying(builder); if (properties.propertyName === void 0) { const type = this.getNodeType(builder); const propertyName = builder.getPropertyName(varying2, NodeShaderStage.VERTEX); builder.flowNodeFromShaderStage(NodeShaderStage.VERTEX, this.node, type, propertyName); properties.propertyName = propertyName; } return builder.getPropertyName(varying2); } }; var varying = /* @__PURE__ */ nodeProxy(VaryingNode); addMethodChaining("varying", varying); var sRGBTransferEOTF = /* @__PURE__ */ Fn(([color2]) => { const a2 = color2.mul(0.9478672986).add(0.0521327014).pow(2.4); const b = color2.mul(0.0773993808); const factor = color2.lessThanEqual(0.04045); const rgbResult = mix(a2, b, factor); return rgbResult; }).setLayout({ name: "sRGBTransferEOTF", type: "vec3", inputs: [ { name: "color", type: "vec3" } ] }); var sRGBTransferOETF = /* @__PURE__ */ Fn(([color2]) => { const a2 = color2.pow(0.41666).mul(1.055).sub(0.055); const b = color2.mul(12.92); const factor = color2.lessThanEqual(31308e-7); const rgbResult = mix(a2, b, factor); return rgbResult; }).setLayout({ name: "sRGBTransferOETF", type: "vec3", inputs: [ { name: "color", type: "vec3" } ] }); var WORKING_COLOR_SPACE = "WorkingColorSpace"; var OUTPUT_COLOR_SPACE = "OutputColorSpace"; var ColorSpaceNode = class extends TempNode { static get type() { return "ColorSpaceNode"; } constructor(colorNode, source, target) { super("vec4"); this.colorNode = colorNode; this.source = source; this.target = target; } resolveColorSpace(builder, colorSpace) { if (colorSpace === WORKING_COLOR_SPACE) { return ColorManagement2.workingColorSpace; } else if (colorSpace === OUTPUT_COLOR_SPACE) { return builder.context.outputColorSpace || builder.renderer.outputColorSpace; } return colorSpace; } setup(builder) { const { colorNode } = this; const source = this.resolveColorSpace(builder, this.source); const target = this.resolveColorSpace(builder, this.target); let outputNode = colorNode; if (ColorManagement2.enabled === false || source === target || !source || !target) { return outputNode; } if (ColorManagement2.getTransfer(source) === SRGBTransfer2) { outputNode = vec4(sRGBTransferEOTF(outputNode.rgb), outputNode.a); } if (ColorManagement2.getPrimaries(source) !== ColorManagement2.getPrimaries(target)) { outputNode = vec4( mat3(ColorManagement2._getMatrix(new Matrix32(), source, target)).mul(outputNode.rgb), outputNode.a ); } if (ColorManagement2.getTransfer(target) === SRGBTransfer2) { outputNode = vec4(sRGBTransferOETF(outputNode.rgb), outputNode.a); } return outputNode; } }; var toOutputColorSpace = (node) => nodeObject(new ColorSpaceNode(nodeObject(node), WORKING_COLOR_SPACE, OUTPUT_COLOR_SPACE)); var toWorkingColorSpace = (node) => nodeObject(new ColorSpaceNode(nodeObject(node), OUTPUT_COLOR_SPACE, WORKING_COLOR_SPACE)); var workingToColorSpace = (node, colorSpace) => nodeObject(new ColorSpaceNode(nodeObject(node), WORKING_COLOR_SPACE, colorSpace)); var colorSpaceToWorking = (node, colorSpace) => nodeObject(new ColorSpaceNode(nodeObject(node), colorSpace, WORKING_COLOR_SPACE)); addMethodChaining("toOutputColorSpace", toOutputColorSpace); addMethodChaining("toWorkingColorSpace", toWorkingColorSpace); addMethodChaining("workingToColorSpace", workingToColorSpace); addMethodChaining("colorSpaceToWorking", colorSpaceToWorking); var ReferenceElementNode$1 = class ReferenceElementNode extends ArrayElementNode { static get type() { return "ReferenceElementNode"; } constructor(referenceNode, indexNode) { super(referenceNode, indexNode); this.referenceNode = referenceNode; this.isReferenceElementNode = true; } getNodeType() { return this.referenceNode.uniformType; } generate(builder) { const snippet = super.generate(builder); const arrayType = this.referenceNode.getNodeType(); const elementType = this.getNodeType(); return builder.format(snippet, arrayType, elementType); } }; var ReferenceBaseNode = class extends Node { static get type() { return "ReferenceBaseNode"; } constructor(property2, uniformType, object = null, count = null) { super(); this.property = property2; this.uniformType = uniformType; this.object = object; this.count = count; this.properties = property2.split("."); this.reference = object; this.node = null; this.group = null; this.updateType = NodeUpdateType.OBJECT; } setGroup(group) { this.group = group; return this; } element(indexNode) { return nodeObject(new ReferenceElementNode$1(this, nodeObject(indexNode))); } setNodeType(uniformType) { const node = uniform(null, uniformType).getSelf(); if (this.group !== null) { node.setGroup(this.group); } this.node = node; } getNodeType(builder) { if (this.node === null) { this.updateReference(builder); this.updateValue(); } return this.node.getNodeType(builder); } getValueFromReference(object = this.reference) { const { properties } = this; let value = object[properties[0]]; for (let i = 1; i < properties.length; i++) { value = value[properties[i]]; } return value; } updateReference(state) { this.reference = this.object !== null ? this.object : state.object; return this.reference; } setup() { this.updateValue(); return this.node; } update() { this.updateValue(); } updateValue() { if (this.node === null) this.setNodeType(this.uniformType); const value = this.getValueFromReference(); if (Array.isArray(value)) { this.node.array = value; } else { this.node.value = value; } } }; var reference$1 = (name, type, object) => nodeObject(new ReferenceBaseNode(name, type, object)); var RendererReferenceNode = class extends ReferenceBaseNode { static get type() { return "RendererReferenceNode"; } constructor(property2, inputType, renderer3 = null) { super(property2, inputType, renderer3); this.renderer = renderer3; this.setGroup(renderGroup); } updateReference(state) { this.reference = this.renderer !== null ? this.renderer : state.renderer; return this.reference; } }; var rendererReference = (name, type, renderer3) => nodeObject(new RendererReferenceNode(name, type, renderer3)); var ToneMappingNode = class extends TempNode { static get type() { return "ToneMappingNode"; } constructor(toneMapping2, exposureNode = toneMappingExposure, colorNode = null) { super("vec3"); this.toneMapping = toneMapping2; this.exposureNode = exposureNode; this.colorNode = colorNode; } getCacheKey() { return hash$1(super.getCacheKey(), this.toneMapping); } setup(builder) { const colorNode = this.colorNode || builder.context.color; const toneMapping2 = this.toneMapping; if (toneMapping2 === NoToneMapping2) return colorNode; let outputNode = null; const toneMappingFn = builder.renderer.library.getToneMappingFunction(toneMapping2); if (toneMappingFn !== null) { outputNode = vec4(toneMappingFn(colorNode.rgb, this.exposureNode), colorNode.a); } else { console.error("ToneMappingNode: Unsupported Tone Mapping configuration.", toneMapping2); outputNode = colorNode; } return outputNode; } }; var toneMapping = (mapping, exposure, color2) => nodeObject(new ToneMappingNode(mapping, nodeObject(exposure), nodeObject(color2))); var toneMappingExposure = /* @__PURE__ */ rendererReference("toneMappingExposure", "float"); addMethodChaining("toneMapping", (color2, mapping, exposure) => toneMapping(mapping, exposure, color2)); var BufferAttributeNode = class extends InputNode { static get type() { return "BufferAttributeNode"; } constructor(value, bufferType = null, bufferStride = 0, bufferOffset = 0) { super(value, bufferType); this.isBufferNode = true; this.bufferType = bufferType; this.bufferStride = bufferStride; this.bufferOffset = bufferOffset; this.usage = StaticDrawUsage2; this.instanced = false; this.attribute = null; this.global = true; if (value && value.isBufferAttribute === true) { this.attribute = value; this.usage = value.usage; this.instanced = value.isInstancedBufferAttribute; } } getHash(builder) { if (this.bufferStride === 0 && this.bufferOffset === 0) { let bufferData = builder.globalCache.getData(this.value); if (bufferData === void 0) { bufferData = { node: this }; builder.globalCache.setData(this.value, bufferData); } return bufferData.node.uuid; } return this.uuid; } getNodeType(builder) { if (this.bufferType === null) { this.bufferType = builder.getTypeFromAttribute(this.attribute); } return this.bufferType; } setup(builder) { if (this.attribute !== null) return; const type = this.getNodeType(builder); const array = this.value; const itemSize = builder.getTypeLength(type); const stride = this.bufferStride || itemSize; const offset = this.bufferOffset; const buffer2 = array.isInterleavedBuffer === true ? array : new InterleavedBuffer(array, stride); const bufferAttribute2 = new InterleavedBufferAttribute(buffer2, itemSize, offset); buffer2.setUsage(this.usage); this.attribute = bufferAttribute2; this.attribute.isInstancedBufferAttribute = this.instanced; } generate(builder) { const nodeType = this.getNodeType(builder); const nodeAttribute = builder.getBufferAttributeFromNode(this, nodeType); const propertyName = builder.getPropertyName(nodeAttribute); let output2 = null; if (builder.shaderStage === "vertex" || builder.shaderStage === "compute") { this.name = propertyName; output2 = propertyName; } else { const nodeVarying = varying(this); output2 = nodeVarying.build(builder, nodeType); } return output2; } getInputType() { return "bufferAttribute"; } setUsage(value) { this.usage = value; if (this.attribute && this.attribute.isBufferAttribute === true) { this.attribute.usage = value; } return this; } setInstanced(value) { this.instanced = value; return this; } }; var bufferAttribute = (array, type, stride, offset) => nodeObject(new BufferAttributeNode(array, type, stride, offset)); var dynamicBufferAttribute = (array, type, stride, offset) => bufferAttribute(array, type, stride, offset).setUsage(DynamicDrawUsage); var instancedBufferAttribute = (array, type, stride, offset) => bufferAttribute(array, type, stride, offset).setInstanced(true); var instancedDynamicBufferAttribute = (array, type, stride, offset) => dynamicBufferAttribute(array, type, stride, offset).setInstanced(true); addMethodChaining("toAttribute", (bufferNode) => bufferAttribute(bufferNode.value)); var ComputeNode = class extends Node { static get type() { return "ComputeNode"; } constructor(computeNode, count, workgroupSize = [64]) { super("void"); this.isComputeNode = true; this.computeNode = computeNode; this.count = count; this.workgroupSize = workgroupSize; this.dispatchCount = 0; this.version = 1; this.updateBeforeType = NodeUpdateType.OBJECT; this.onInitFunction = null; this.updateDispatchCount(); } dispose() { this.dispatchEvent({ type: "dispose" }); } set needsUpdate(value) { if (value === true) this.version++; } updateDispatchCount() { const { count, workgroupSize } = this; let size = workgroupSize[0]; for (let i = 1; i < workgroupSize.length; i++) size *= workgroupSize[i]; this.dispatchCount = Math.ceil(count / size); } onInit(callback) { this.onInitFunction = callback; return this; } updateBefore({ renderer: renderer3 }) { renderer3.compute(this); } generate(builder) { const { shaderStage } = builder; if (shaderStage === "compute") { const snippet = this.computeNode.build(builder, "void"); if (snippet !== "") { builder.addLineFlowCode(snippet, this); } } } }; var compute = (node, count, workgroupSize) => nodeObject(new ComputeNode(nodeObject(node), count, workgroupSize)); addMethodChaining("compute", compute); var CacheNode = class extends Node { static get type() { return "CacheNode"; } constructor(node, parent = true) { super(); this.node = node; this.parent = parent; this.isCacheNode = true; } getNodeType(builder) { return this.node.getNodeType(builder); } build(builder, ...params) { const previousCache = builder.getCache(); const cache2 = builder.getCacheFromNode(this, this.parent); builder.setCache(cache2); const data = this.node.build(builder, ...params); builder.setCache(previousCache); return data; } }; var cache = (node, ...params) => nodeObject(new CacheNode(nodeObject(node), ...params)); addMethodChaining("cache", cache); var BypassNode = class extends Node { static get type() { return "BypassNode"; } constructor(returnNode, callNode) { super(); this.isBypassNode = true; this.outputNode = returnNode; this.callNode = callNode; } getNodeType(builder) { return this.outputNode.getNodeType(builder); } generate(builder) { const snippet = this.callNode.build(builder, "void"); if (snippet !== "") { builder.addLineFlowCode(snippet, this); } return this.outputNode.build(builder); } }; var bypass = /* @__PURE__ */ nodeProxy(BypassNode); addMethodChaining("bypass", bypass); var RemapNode = class extends Node { static get type() { return "RemapNode"; } constructor(node, inLowNode, inHighNode, outLowNode = float(0), outHighNode = float(1)) { super(); this.node = node; this.inLowNode = inLowNode; this.inHighNode = inHighNode; this.outLowNode = outLowNode; this.outHighNode = outHighNode; this.doClamp = true; } setup() { const { node, inLowNode, inHighNode, outLowNode, outHighNode, doClamp } = this; let t = node.sub(inLowNode).div(inHighNode.sub(inLowNode)); if (doClamp === true) t = t.clamp(); return t.mul(outHighNode.sub(outLowNode)).add(outLowNode); } }; var remap = /* @__PURE__ */ nodeProxy(RemapNode, null, null, { doClamp: false }); var remapClamp = /* @__PURE__ */ nodeProxy(RemapNode); addMethodChaining("remap", remap); addMethodChaining("remapClamp", remapClamp); var ExpressionNode = class extends Node { static get type() { return "ExpressionNode"; } constructor(snippet = "", nodeType = "void") { super(nodeType); this.snippet = snippet; } generate(builder, output2) { const type = this.getNodeType(builder); const snippet = this.snippet; if (type === "void") { builder.addLineFlowCode(snippet, this); } else { return builder.format(`( ${snippet} )`, type, output2); } } }; var expression = /* @__PURE__ */ nodeProxy(ExpressionNode); var Discard = (conditional) => (conditional ? select(conditional, expression("discard")) : expression("discard")).append(); addMethodChaining("discard", Discard); var RenderOutputNode = class extends TempNode { static get type() { return "RenderOutputNode"; } constructor(colorNode, toneMapping2, outputColorSpace) { super("vec4"); this.colorNode = colorNode; this.toneMapping = toneMapping2; this.outputColorSpace = outputColorSpace; this.isRenderOutput = true; } setup({ context: context2 }) { let outputNode = this.colorNode || context2.color; const toneMapping2 = (this.toneMapping !== null ? this.toneMapping : context2.toneMapping) || NoToneMapping2; const outputColorSpace = (this.outputColorSpace !== null ? this.outputColorSpace : context2.outputColorSpace) || NoColorSpace2; if (toneMapping2 !== NoToneMapping2) { outputNode = outputNode.toneMapping(toneMapping2); } if (outputColorSpace !== NoColorSpace2 && outputColorSpace !== ColorManagement2.workingColorSpace) { outputNode = outputNode.workingToColorSpace(outputColorSpace); } return outputNode; } }; var renderOutput = (color2, toneMapping2 = null, outputColorSpace = null) => nodeObject(new RenderOutputNode(nodeObject(color2), toneMapping2, outputColorSpace)); addMethodChaining("renderOutput", renderOutput); var AttributeNode = class extends Node { static get type() { return "AttributeNode"; } constructor(attributeName, nodeType = null) { super(nodeType); this.global = true; this._attributeName = attributeName; } getHash(builder) { return this.getAttributeName(builder); } getNodeType(builder) { let nodeType = this.nodeType; if (nodeType === null) { const attributeName = this.getAttributeName(builder); if (builder.hasGeometryAttribute(attributeName)) { const attribute2 = builder.geometry.getAttribute(attributeName); nodeType = builder.getTypeFromAttribute(attribute2); } else { nodeType = "float"; } } return nodeType; } setAttributeName(attributeName) { this._attributeName = attributeName; return this; } getAttributeName() { return this._attributeName; } generate(builder) { const attributeName = this.getAttributeName(builder); const nodeType = this.getNodeType(builder); const geometryAttribute = builder.hasGeometryAttribute(attributeName); if (geometryAttribute === true) { const attribute2 = builder.geometry.getAttribute(attributeName); const attributeType = builder.getTypeFromAttribute(attribute2); const nodeAttribute = builder.getAttribute(attributeName, attributeType); if (builder.shaderStage === "vertex") { return builder.format(nodeAttribute.name, attributeType, nodeType); } else { const nodeVarying = varying(this); return nodeVarying.build(builder, nodeType); } } else { console.warn(`AttributeNode: Vertex attribute "${attributeName}" not found on geometry.`); return builder.generateConst(nodeType); } } serialize(data) { super.serialize(data); data.global = this.global; data._attributeName = this._attributeName; } deserialize(data) { super.deserialize(data); this.global = data.global; this._attributeName = data._attributeName; } }; var attribute = (name, nodeType) => nodeObject(new AttributeNode(name, nodeType)); var uv = (index5) => attribute("uv" + (index5 > 0 ? index5 : ""), "vec2"); var TextureSizeNode = class extends Node { static get type() { return "TextureSizeNode"; } constructor(textureNode, levelNode = null) { super("uvec2"); this.isTextureSizeNode = true; this.textureNode = textureNode; this.levelNode = levelNode; } generate(builder, output2) { const textureProperty = this.textureNode.build(builder, "property"); const level = this.levelNode === null ? "0" : this.levelNode.build(builder, "int"); return builder.format(`${builder.getMethod("textureDimensions")}( ${textureProperty}, ${level} )`, this.getNodeType(builder), output2); } }; var textureSize = /* @__PURE__ */ nodeProxy(TextureSizeNode); var MaxMipLevelNode = class extends UniformNode { static get type() { return "MaxMipLevelNode"; } constructor(textureNode) { super(0); this._textureNode = textureNode; this.updateType = NodeUpdateType.FRAME; } get textureNode() { return this._textureNode; } get texture() { return this._textureNode.value; } update() { const texture2 = this.texture; const images = texture2.images; const image = images && images.length > 0 ? images[0] && images[0].image || images[0] : texture2.image; if (image && image.width !== void 0) { const { width, height } = image; this.value = Math.log2(Math.max(width, height)); } } }; var maxMipLevel = /* @__PURE__ */ nodeProxy(MaxMipLevelNode); var TextureNode = class extends UniformNode { static get type() { return "TextureNode"; } constructor(value, uvNode = null, levelNode = null, biasNode = null) { super(value); this.isTextureNode = true; this.uvNode = uvNode; this.levelNode = levelNode; this.biasNode = biasNode; this.compareNode = null; this.depthNode = null; this.gradNode = null; this.sampler = true; this.updateMatrix = false; this.updateType = NodeUpdateType.NONE; this.referenceNode = null; this._value = value; this._matrixUniform = null; this.setUpdateMatrix(uvNode === null); } set value(value) { if (this.referenceNode) { this.referenceNode.value = value; } else { this._value = value; } } get value() { return this.referenceNode ? this.referenceNode.value : this._value; } getUniformHash() { return this.value.uuid; } getNodeType() { if (this.value.isDepthTexture === true) return "float"; if (this.value.type === UnsignedIntType2) { return "uvec4"; } else if (this.value.type === IntType2) { return "ivec4"; } return "vec4"; } getInputType() { return "texture"; } getDefaultUV() { return uv(this.value.channel); } updateReference() { return this.value; } getTransformedUV(uvNode) { if (this._matrixUniform === null) this._matrixUniform = uniform(this.value.matrix); return this._matrixUniform.mul(vec3(uvNode, 1)).xy; } setUpdateMatrix(value) { this.updateMatrix = value; this.updateType = value ? NodeUpdateType.FRAME : NodeUpdateType.NONE; return this; } setupUV(builder, uvNode) { const texture2 = this.value; if (builder.isFlipY() && (texture2.isRenderTargetTexture === true || texture2.isFramebufferTexture === true || texture2.isDepthTexture === true)) { if (this.sampler) { uvNode = uvNode.flipY(); } else { uvNode = uvNode.setY(int(textureSize(this, this.levelNode).y).sub(uvNode.y).sub(1)); } } return uvNode; } setup(builder) { const properties = builder.getNodeProperties(this); properties.referenceNode = this.referenceNode; let uvNode = this.uvNode; if ((uvNode === null || builder.context.forceUVContext === true) && builder.context.getUV) { uvNode = builder.context.getUV(this); } if (!uvNode) uvNode = this.getDefaultUV(); if (this.updateMatrix === true) { uvNode = this.getTransformedUV(uvNode); } uvNode = this.setupUV(builder, uvNode); let levelNode = this.levelNode; if (levelNode === null && builder.context.getTextureLevel) { levelNode = builder.context.getTextureLevel(this); } properties.uvNode = uvNode; properties.levelNode = levelNode; properties.biasNode = this.biasNode; properties.compareNode = this.compareNode; properties.gradNode = this.gradNode; properties.depthNode = this.depthNode; } generateUV(builder, uvNode) { return uvNode.build(builder, this.sampler === true ? "vec2" : "ivec2"); } generateSnippet(builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet) { const texture2 = this.value; let snippet; if (levelSnippet) { snippet = builder.generateTextureLevel(texture2, textureProperty, uvSnippet, levelSnippet, depthSnippet); } else if (biasSnippet) { snippet = builder.generateTextureBias(texture2, textureProperty, uvSnippet, biasSnippet, depthSnippet); } else if (gradSnippet) { snippet = builder.generateTextureGrad(texture2, textureProperty, uvSnippet, gradSnippet, depthSnippet); } else if (compareSnippet) { snippet = builder.generateTextureCompare(texture2, textureProperty, uvSnippet, compareSnippet, depthSnippet); } else if (this.sampler === false) { snippet = builder.generateTextureLoad(texture2, textureProperty, uvSnippet, depthSnippet); } else { snippet = builder.generateTexture(texture2, textureProperty, uvSnippet, depthSnippet); } return snippet; } generate(builder, output2) { const properties = builder.getNodeProperties(this); const texture2 = this.value; if (!texture2 || texture2.isTexture !== true) { throw new Error("TextureNode: Need a three.js texture."); } const textureProperty = super.generate(builder, "property"); if (output2 === "sampler") { return textureProperty + "_sampler"; } else if (builder.isReference(output2)) { return textureProperty; } else { const nodeData = builder.getDataFromNode(this); let propertyName = nodeData.propertyName; if (propertyName === void 0) { const { uvNode, levelNode, biasNode, compareNode, depthNode, gradNode } = properties; const uvSnippet = this.generateUV(builder, uvNode); const levelSnippet = levelNode ? levelNode.build(builder, "float") : null; const biasSnippet = biasNode ? biasNode.build(builder, "float") : null; const depthSnippet = depthNode ? depthNode.build(builder, "int") : null; const compareSnippet = compareNode ? compareNode.build(builder, "float") : null; const gradSnippet = gradNode ? [gradNode[0].build(builder, "vec2"), gradNode[1].build(builder, "vec2")] : null; const nodeVar = builder.getVarFromNode(this); propertyName = builder.getPropertyName(nodeVar); const snippet2 = this.generateSnippet(builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet); builder.addLineFlowCode(`${propertyName} = ${snippet2}`, this); nodeData.snippet = snippet2; nodeData.propertyName = propertyName; } let snippet = propertyName; const nodeType = this.getNodeType(builder); if (builder.needsToWorkingColorSpace(texture2)) { snippet = colorSpaceToWorking(expression(snippet, nodeType), texture2.colorSpace).setup(builder).build(builder, nodeType); } return builder.format(snippet, nodeType, output2); } } setSampler(value) { this.sampler = value; return this; } getSampler() { return this.sampler; } // @TODO: Move to TSL uv(uvNode) { const textureNode = this.clone(); textureNode.uvNode = nodeObject(uvNode); textureNode.referenceNode = this.getSelf(); return nodeObject(textureNode); } blur(amountNode) { const textureNode = this.clone(); textureNode.biasNode = nodeObject(amountNode).mul(maxMipLevel(textureNode)); textureNode.referenceNode = this.getSelf(); return nodeObject(textureNode); } level(levelNode) { const textureNode = this.clone(); textureNode.levelNode = nodeObject(levelNode); textureNode.referenceNode = this.getSelf(); return nodeObject(textureNode); } size(levelNode) { return textureSize(this, levelNode); } bias(biasNode) { const textureNode = this.clone(); textureNode.biasNode = nodeObject(biasNode); textureNode.referenceNode = this.getSelf(); return nodeObject(textureNode); } compare(compareNode) { const textureNode = this.clone(); textureNode.compareNode = nodeObject(compareNode); textureNode.referenceNode = this.getSelf(); return nodeObject(textureNode); } grad(gradNodeX, gradNodeY) { const textureNode = this.clone(); textureNode.gradNode = [nodeObject(gradNodeX), nodeObject(gradNodeY)]; textureNode.referenceNode = this.getSelf(); return nodeObject(textureNode); } depth(depthNode) { const textureNode = this.clone(); textureNode.depthNode = nodeObject(depthNode); textureNode.referenceNode = this.getSelf(); return nodeObject(textureNode); } // -- serialize(data) { super.serialize(data); data.value = this.value.toJSON(data.meta).uuid; data.sampler = this.sampler; data.updateMatrix = this.updateMatrix; data.updateType = this.updateType; } deserialize(data) { super.deserialize(data); this.value = data.meta.textures[data.value]; this.sampler = data.sampler; this.updateMatrix = data.updateMatrix; this.updateType = data.updateType; } update() { const texture2 = this.value; const matrixUniform = this._matrixUniform; if (matrixUniform !== null) matrixUniform.value = texture2.matrix; if (texture2.matrixAutoUpdate === true) { texture2.updateMatrix(); } } clone() { const newNode = new this.constructor(this.value, this.uvNode, this.levelNode, this.biasNode); newNode.sampler = this.sampler; return newNode; } }; var texture = /* @__PURE__ */ nodeProxy(TextureNode); var textureLoad = (...params) => texture(...params).setSampler(false); var cameraNear = /* @__PURE__ */ uniform("float").label("cameraNear").setGroup(renderGroup).onRenderUpdate(({ camera: camera3 }) => camera3.near); var cameraFar = /* @__PURE__ */ uniform("float").label("cameraFar").setGroup(renderGroup).onRenderUpdate(({ camera: camera3 }) => camera3.far); var cameraProjectionMatrix = /* @__PURE__ */ uniform("mat4").label("cameraProjectionMatrix").setGroup(renderGroup).onRenderUpdate(({ camera: camera3 }) => camera3.projectionMatrix); var cameraViewMatrix = /* @__PURE__ */ uniform("mat4").label("cameraViewMatrix").setGroup(renderGroup).onRenderUpdate(({ camera: camera3 }) => camera3.matrixWorldInverse); var cameraPosition = /* @__PURE__ */ uniform(new Vector32()).label("cameraPosition").setGroup(renderGroup).onRenderUpdate(({ camera: camera3 }, self2) => self2.value.setFromMatrixPosition(camera3.matrixWorld)); var Object3DNode = class _Object3DNode extends Node { static get type() { return "Object3DNode"; } constructor(scope, object3d = null) { super(); this.scope = scope; this.object3d = object3d; this.updateType = NodeUpdateType.OBJECT; this._uniformNode = new UniformNode(null); } getNodeType() { const scope = this.scope; if (scope === _Object3DNode.WORLD_MATRIX) { return "mat4"; } else if (scope === _Object3DNode.POSITION || scope === _Object3DNode.VIEW_POSITION || scope === _Object3DNode.DIRECTION || scope === _Object3DNode.SCALE) { return "vec3"; } } update(frame2) { const object = this.object3d; const uniformNode = this._uniformNode; const scope = this.scope; if (scope === _Object3DNode.WORLD_MATRIX) { uniformNode.value = object.matrixWorld; } else if (scope === _Object3DNode.POSITION) { uniformNode.value = uniformNode.value || new Vector32(); uniformNode.value.setFromMatrixPosition(object.matrixWorld); } else if (scope === _Object3DNode.SCALE) { uniformNode.value = uniformNode.value || new Vector32(); uniformNode.value.setFromMatrixScale(object.matrixWorld); } else if (scope === _Object3DNode.DIRECTION) { uniformNode.value = uniformNode.value || new Vector32(); object.getWorldDirection(uniformNode.value); } else if (scope === _Object3DNode.VIEW_POSITION) { const camera3 = frame2.camera; uniformNode.value = uniformNode.value || new Vector32(); uniformNode.value.setFromMatrixPosition(object.matrixWorld); uniformNode.value.applyMatrix4(camera3.matrixWorldInverse); } } generate(builder) { const scope = this.scope; if (scope === _Object3DNode.WORLD_MATRIX) { this._uniformNode.nodeType = "mat4"; } else if (scope === _Object3DNode.POSITION || scope === _Object3DNode.VIEW_POSITION || scope === _Object3DNode.DIRECTION || scope === _Object3DNode.SCALE) { this._uniformNode.nodeType = "vec3"; } return this._uniformNode.build(builder); } serialize(data) { super.serialize(data); data.scope = this.scope; } deserialize(data) { super.deserialize(data); this.scope = data.scope; } }; Object3DNode.WORLD_MATRIX = "worldMatrix"; Object3DNode.POSITION = "position"; Object3DNode.SCALE = "scale"; Object3DNode.VIEW_POSITION = "viewPosition"; Object3DNode.DIRECTION = "direction"; var objectDirection = /* @__PURE__ */ nodeProxy(Object3DNode, Object3DNode.DIRECTION); var objectWorldMatrix = /* @__PURE__ */ nodeProxy(Object3DNode, Object3DNode.WORLD_MATRIX); var objectPosition = /* @__PURE__ */ nodeProxy(Object3DNode, Object3DNode.POSITION); var objectScale = /* @__PURE__ */ nodeProxy(Object3DNode, Object3DNode.SCALE); var objectViewPosition = /* @__PURE__ */ nodeProxy(Object3DNode, Object3DNode.VIEW_POSITION); var ModelNode = class extends Object3DNode { static get type() { return "ModelNode"; } constructor(scope) { super(scope); } update(frame2) { this.object3d = frame2.object; super.update(frame2); } }; var modelDirection = /* @__PURE__ */ nodeImmutable(ModelNode, ModelNode.DIRECTION); var modelWorldMatrix = /* @__PURE__ */ nodeImmutable(ModelNode, ModelNode.WORLD_MATRIX); var modelPosition = /* @__PURE__ */ nodeImmutable(ModelNode, ModelNode.POSITION); var modelScale = /* @__PURE__ */ nodeImmutable(ModelNode, ModelNode.SCALE); var modelViewPosition = /* @__PURE__ */ nodeImmutable(ModelNode, ModelNode.VIEW_POSITION); var modelNormalMatrix = /* @__PURE__ */ uniform(new Matrix32()).onObjectUpdate(({ object }, self2) => self2.value.getNormalMatrix(object.matrixWorld)); var modelViewMatrix = /* @__PURE__ */ cameraViewMatrix.mul(modelWorldMatrix).toVar("modelViewMatrix"); var positionGeometry = /* @__PURE__ */ attribute("position", "vec3"); var positionLocal = /* @__PURE__ */ positionGeometry.varying("positionLocal"); var positionPrevious = /* @__PURE__ */ positionGeometry.varying("positionPrevious"); var positionWorld = /* @__PURE__ */ modelWorldMatrix.mul(positionLocal).xyz.varying("v_positionWorld"); var positionWorldDirection = /* @__PURE__ */ positionLocal.transformDirection(modelWorldMatrix).varying("v_positionWorldDirection").normalize().toVar("positionWorldDirection"); var positionView = /* @__PURE__ */ modelViewMatrix.mul(positionLocal).xyz.varying("v_positionView"); var positionViewDirection = /* @__PURE__ */ positionView.negate().varying("v_positionViewDirection").normalize().toVar("positionViewDirection"); var FrontFacingNode = class extends Node { static get type() { return "FrontFacingNode"; } constructor() { super("bool"); this.isFrontFacingNode = true; } generate(builder) { const { renderer: renderer3, material } = builder; if (renderer3.coordinateSystem === WebGLCoordinateSystem2) { if (material.side === BackSide2) { return "false"; } } return builder.getFrontFacing(); } }; var frontFacing = /* @__PURE__ */ nodeImmutable(FrontFacingNode); var faceDirection = /* @__PURE__ */ float(frontFacing).mul(2).sub(1); var normalGeometry = /* @__PURE__ */ attribute("normal", "vec3"); var normalLocal = /* @__PURE__ */ Fn((builder) => { if (builder.geometry.hasAttribute("normal") === false) { console.warn('TSL.NormalNode: Vertex attribute "normal" not found on geometry.'); return vec3(0, 1, 0); } return normalGeometry; }, "vec3").once()().toVar("normalLocal"); var normalFlat = /* @__PURE__ */ positionView.dFdx().cross(positionView.dFdy()).normalize().toVar("normalFlat"); var normalView = /* @__PURE__ */ Fn((builder) => { let node; if (builder.material.flatShading === true) { node = normalFlat; } else { node = varying(transformNormalToView(normalLocal), "v_normalView").normalize(); } return node; }, "vec3").once()().toVar("normalView"); var normalWorld = /* @__PURE__ */ varying(normalView.transformDirection(cameraViewMatrix), "v_normalWorld").normalize().toVar("normalWorld"); var transformedNormalView = /* @__PURE__ */ Fn((builder) => { return builder.context.setupNormal(); }, "vec3").once()().mul(faceDirection).toVar("transformedNormalView"); var transformedNormalWorld = /* @__PURE__ */ transformedNormalView.transformDirection(cameraViewMatrix).toVar("transformedNormalWorld"); var transformedClearcoatNormalView = /* @__PURE__ */ Fn((builder) => { return builder.context.setupClearcoatNormal(); }, "vec3").once()().mul(faceDirection).toVar("transformedClearcoatNormalView"); var transformNormal = /* @__PURE__ */ Fn(([normal2, matrix = modelWorldMatrix]) => { const m2 = mat3(matrix); const transformedNormal = normal2.div(vec3(m2[0].dot(m2[0]), m2[1].dot(m2[1]), m2[2].dot(m2[2]))); return m2.mul(transformedNormal).xyz; }); var transformNormalToView = /* @__PURE__ */ Fn(([normal2], builder) => { const modelNormalViewMatrix = builder.renderer.nodes.modelNormalViewMatrix; if (modelNormalViewMatrix !== null) { return modelNormalViewMatrix.transformDirection(normal2); } const transformedNormal = modelNormalMatrix.mul(normal2); return cameraViewMatrix.transformDirection(transformedNormal); }); var materialRefractionRatio = /* @__PURE__ */ uniform(0).onReference(({ material }) => material).onRenderUpdate(({ material }) => material.refractionRatio); var reflectView = /* @__PURE__ */ positionViewDirection.negate().reflect(transformedNormalView); var refractView = /* @__PURE__ */ positionViewDirection.negate().refract(transformedNormalView, materialRefractionRatio); var reflectVector = /* @__PURE__ */ reflectView.transformDirection(cameraViewMatrix).toVar("reflectVector"); var refractVector = /* @__PURE__ */ refractView.transformDirection(cameraViewMatrix).toVar("reflectVector"); var CubeTextureNode = class extends TextureNode { static get type() { return "CubeTextureNode"; } constructor(value, uvNode = null, levelNode = null, biasNode = null) { super(value, uvNode, levelNode, biasNode); this.isCubeTextureNode = true; } getInputType() { return "cubeTexture"; } getDefaultUV() { const texture2 = this.value; if (texture2.mapping === CubeReflectionMapping2) { return reflectVector; } else if (texture2.mapping === CubeRefractionMapping2) { return refractVector; } else { console.error('THREE.CubeTextureNode: Mapping "%s" not supported.', texture2.mapping); return vec3(0, 0, 0); } } setUpdateMatrix() { } // Ignore .updateMatrix for CubeTextureNode setupUV(builder, uvNode) { const texture2 = this.value; if (builder.renderer.coordinateSystem === WebGPUCoordinateSystem2 || !texture2.isRenderTargetTexture) { return vec3(uvNode.x.negate(), uvNode.yz); } else { return uvNode; } } generateUV(builder, cubeUV) { return cubeUV.build(builder, "vec3"); } }; var cubeTexture = /* @__PURE__ */ nodeProxy(CubeTextureNode); var BufferNode = class extends UniformNode { static get type() { return "BufferNode"; } constructor(value, bufferType, bufferCount = 0) { super(value, bufferType); this.isBufferNode = true; this.bufferType = bufferType; this.bufferCount = bufferCount; } getElementType(builder) { return this.getNodeType(builder); } getInputType() { return "buffer"; } }; var buffer = (value, type, count) => nodeObject(new BufferNode(value, type, count)); var UniformArrayElementNode = class extends ArrayElementNode { static get type() { return "UniformArrayElementNode"; } constructor(arrayBuffer, indexNode) { super(arrayBuffer, indexNode); this.isArrayBufferElementNode = true; } generate(builder) { const snippet = super.generate(builder); const type = this.getNodeType(); return builder.format(snippet, "vec4", type); } }; var UniformArrayNode = class extends BufferNode { static get type() { return "UniformArrayNode"; } constructor(value, elementType = null) { super(null, "vec4"); this.array = value; this.elementType = elementType; this._elementType = null; this._elementLength = 0; this.updateType = NodeUpdateType.RENDER; this.isArrayBufferNode = true; } getElementType() { return this.elementType || this._elementType; } getElementLength() { return this._elementLength; } update() { const { array, value } = this; const elementLength = this.getElementLength(); const elementType = this.getElementType(); if (elementLength === 1) { for (let i = 0; i < array.length; i++) { const index5 = i * 4; value[index5] = array[i]; } } else if (elementType === "color") { for (let i = 0; i < array.length; i++) { const index5 = i * 4; const vector = array[i]; value[index5] = vector.r; value[index5 + 1] = vector.g; value[index5 + 2] = vector.b || 0; } } else { for (let i = 0; i < array.length; i++) { const index5 = i * 4; const vector = array[i]; value[index5] = vector.x; value[index5 + 1] = vector.y; value[index5 + 2] = vector.z || 0; value[index5 + 3] = vector.w || 0; } } } setup(builder) { const length2 = this.array.length; this._elementType = this.elementType === null ? getValueType(this.array[0]) : this.elementType; this._elementLength = builder.getTypeLength(this._elementType); let arrayType = Float32Array; if (this._elementType.charAt(0) === "i") arrayType = Int32Array; else if (this._elementType.charAt(0) === "u") arrayType = Uint32Array; this.value = new arrayType(length2 * 4); this.bufferCount = length2; this.bufferType = builder.changeComponentType("vec4", builder.getComponentType(this._elementType)); return super.setup(builder); } element(indexNode) { return nodeObject(new UniformArrayElementNode(this, nodeObject(indexNode))); } }; var uniformArray = (values, nodeType) => nodeObject(new UniformArrayNode(values, nodeType)); var ReferenceElementNode2 = class extends ArrayElementNode { static get type() { return "ReferenceElementNode"; } constructor(referenceNode, indexNode) { super(referenceNode, indexNode); this.referenceNode = referenceNode; this.isReferenceElementNode = true; } getNodeType() { return this.referenceNode.uniformType; } generate(builder) { const snippet = super.generate(builder); const arrayType = this.referenceNode.getNodeType(); const elementType = this.getNodeType(); return builder.format(snippet, arrayType, elementType); } }; var ReferenceNode = class extends Node { static get type() { return "ReferenceNode"; } constructor(property2, uniformType, object = null, count = null) { super(); this.property = property2; this.uniformType = uniformType; this.object = object; this.count = count; this.properties = property2.split("."); this.reference = object; this.node = null; this.group = null; this.name = null; this.updateType = NodeUpdateType.OBJECT; } element(indexNode) { return nodeObject(new ReferenceElementNode2(this, nodeObject(indexNode))); } setGroup(group) { this.group = group; return this; } label(name) { this.name = name; return this; } setNodeType(uniformType) { let node = null; if (this.count !== null) { node = buffer(null, uniformType, this.count); } else if (Array.isArray(this.getValueFromReference())) { node = uniformArray(null, uniformType); } else if (uniformType === "texture") { node = texture(null); } else if (uniformType === "cubeTexture") { node = cubeTexture(null); } else { node = uniform(null, uniformType); } if (this.group !== null) { node.setGroup(this.group); } if (this.name !== null) node.label(this.name); this.node = node.getSelf(); } getNodeType(builder) { if (this.node === null) { this.updateReference(builder); this.updateValue(); } return this.node.getNodeType(builder); } getValueFromReference(object = this.reference) { const { properties } = this; let value = object[properties[0]]; for (let i = 1; i < properties.length; i++) { value = value[properties[i]]; } return value; } updateReference(state) { this.reference = this.object !== null ? this.object : state.object; return this.reference; } setup() { this.updateValue(); return this.node; } update() { this.updateValue(); } updateValue() { if (this.node === null) this.setNodeType(this.uniformType); const value = this.getValueFromReference(); if (Array.isArray(value)) { this.node.array = value; } else { this.node.value = value; } } }; var reference = (name, type, object) => nodeObject(new ReferenceNode(name, type, object)); var referenceBuffer = (name, type, count, object) => nodeObject(new ReferenceNode(name, type, object, count)); var MaterialReferenceNode = class extends ReferenceNode { static get type() { return "MaterialReferenceNode"; } constructor(property2, inputType, material = null) { super(property2, inputType, material); this.material = material; this.isMaterialReferenceNode = true; } /*setNodeType( node ) { super.setNodeType( node ); this.node.groupNode = renderGroup; }*/ updateReference(state) { this.reference = this.material !== null ? this.material : state.material; return this.reference; } }; var materialReference = (name, type, material) => nodeObject(new MaterialReferenceNode(name, type, material)); var tangentGeometry = /* @__PURE__ */ Fn((builder) => { if (builder.geometry.hasAttribute("tangent") === false) { builder.geometry.computeTangents(); } return attribute("tangent", "vec4"); })(); var tangentLocal = /* @__PURE__ */ tangentGeometry.xyz.toVar("tangentLocal"); var tangentView = /* @__PURE__ */ modelViewMatrix.mul(vec4(tangentLocal, 0)).xyz.varying("v_tangentView").normalize().toVar("tangentView"); var getBitangent = (crossNormalTangent) => crossNormalTangent.mul(tangentGeometry.w).xyz; var bitangentView = /* @__PURE__ */ varying(getBitangent(normalView.cross(tangentView)), "v_bitangentView").normalize().toVar("bitangentView"); var TBNViewMatrix = /* @__PURE__ */ mat3(tangentView, bitangentView, normalView); var transformedBentNormalView = /* @__PURE__ */ (() => { let bentNormal = anisotropyB.cross(positionViewDirection); bentNormal = bentNormal.cross(anisotropyB).normalize(); bentNormal = mix(bentNormal, transformedNormalView, anisotropy.mul(roughness.oneMinus()).oneMinus().pow2().pow2()).normalize(); return bentNormal; })(); var perturbNormal2Arb = /* @__PURE__ */ Fn((inputs) => { const { eye_pos, surf_norm, mapN, uv: uv2 } = inputs; const q0 = eye_pos.dFdx(); const q1 = eye_pos.dFdy(); const st0 = uv2.dFdx(); const st1 = uv2.dFdy(); const N = surf_norm; const q1perp = q1.cross(N); const q0perp = N.cross(q0); const T = q1perp.mul(st0.x).add(q0perp.mul(st1.x)); const B = q1perp.mul(st0.y).add(q0perp.mul(st1.y)); const det = T.dot(T).max(B.dot(B)); const scale = faceDirection.mul(det.inverseSqrt()); return add4(T.mul(mapN.x, scale), B.mul(mapN.y, scale), N.mul(mapN.z)).normalize(); }); var NormalMapNode = class extends TempNode { static get type() { return "NormalMapNode"; } constructor(node, scaleNode = null) { super("vec3"); this.node = node; this.scaleNode = scaleNode; this.normalMapType = TangentSpaceNormalMap2; } setup(builder) { const { normalMapType, scaleNode } = this; let normalMap2 = this.node.mul(2).sub(1); if (scaleNode !== null) { normalMap2 = vec3(normalMap2.xy.mul(scaleNode), normalMap2.z); } let outputNode = null; if (normalMapType === ObjectSpaceNormalMap2) { outputNode = transformNormalToView(normalMap2); } else if (normalMapType === TangentSpaceNormalMap2) { const tangent = builder.hasGeometryAttribute("tangent"); if (tangent === true) { outputNode = TBNViewMatrix.mul(normalMap2).normalize(); } else { outputNode = perturbNormal2Arb({ eye_pos: positionView, surf_norm: normalView, mapN: normalMap2, uv: uv() }); } } return outputNode; } }; var normalMap = /* @__PURE__ */ nodeProxy(NormalMapNode); var dHdxy_fwd = Fn(({ textureNode, bumpScale }) => { const sampleTexture = (callback) => textureNode.cache().context({ getUV: (texNode) => callback(texNode.uvNode || uv()), forceUVContext: true }); const Hll = float(sampleTexture((uvNode) => uvNode)); return vec2( float(sampleTexture((uvNode) => uvNode.add(uvNode.dFdx()))).sub(Hll), float(sampleTexture((uvNode) => uvNode.add(uvNode.dFdy()))).sub(Hll) ).mul(bumpScale); }); var perturbNormalArb = Fn((inputs) => { const { surf_pos, surf_norm, dHdxy } = inputs; const vSigmaX = surf_pos.dFdx().normalize(); const vSigmaY = surf_pos.dFdy().normalize(); const vN = surf_norm; const R1 = vSigmaY.cross(vN); const R2 = vN.cross(vSigmaX); const fDet = vSigmaX.dot(R1).mul(faceDirection); const vGrad = fDet.sign().mul(dHdxy.x.mul(R1).add(dHdxy.y.mul(R2))); return fDet.abs().mul(surf_norm).sub(vGrad).normalize(); }); var BumpMapNode = class extends TempNode { static get type() { return "BumpMapNode"; } constructor(textureNode, scaleNode = null) { super("vec3"); this.textureNode = textureNode; this.scaleNode = scaleNode; } setup() { const bumpScale = this.scaleNode !== null ? this.scaleNode : 1; const dHdxy = dHdxy_fwd({ textureNode: this.textureNode, bumpScale }); return perturbNormalArb({ surf_pos: positionView, surf_norm: normalView, dHdxy }); } }; var bumpMap = /* @__PURE__ */ nodeProxy(BumpMapNode); var _propertyCache = /* @__PURE__ */ new Map(); var MaterialNode = class _MaterialNode extends Node { static get type() { return "MaterialNode"; } constructor(scope) { super(); this.scope = scope; } getCache(property2, type) { let node = _propertyCache.get(property2); if (node === void 0) { node = materialReference(property2, type); _propertyCache.set(property2, node); } return node; } getFloat(property2) { return this.getCache(property2, "float"); } getColor(property2) { return this.getCache(property2, "color"); } getTexture(property2) { return this.getCache(property2 === "map" ? "map" : property2 + "Map", "texture"); } setup(builder) { const material = builder.context.material; const scope = this.scope; let node = null; if (scope === _MaterialNode.COLOR) { const colorNode = material.color !== void 0 ? this.getColor(scope) : vec3(); if (material.map && material.map.isTexture === true) { node = colorNode.mul(this.getTexture("map")); } else { node = colorNode; } } else if (scope === _MaterialNode.OPACITY) { const opacityNode = this.getFloat(scope); if (material.alphaMap && material.alphaMap.isTexture === true) { node = opacityNode.mul(this.getTexture("alpha")); } else { node = opacityNode; } } else if (scope === _MaterialNode.SPECULAR_STRENGTH) { if (material.specularMap && material.specularMap.isTexture === true) { node = this.getTexture("specular").r; } else { node = float(1); } } else if (scope === _MaterialNode.SPECULAR_INTENSITY) { const specularIntensity = this.getFloat(scope); if (material.specularMap) { node = specularIntensity.mul(this.getTexture(scope).a); } else { node = specularIntensity; } } else if (scope === _MaterialNode.SPECULAR_COLOR) { const specularColorNode = this.getColor(scope); if (material.specularColorMap && material.specularColorMap.isTexture === true) { node = specularColorNode.mul(this.getTexture(scope).rgb); } else { node = specularColorNode; } } else if (scope === _MaterialNode.ROUGHNESS) { const roughnessNode = this.getFloat(scope); if (material.roughnessMap && material.roughnessMap.isTexture === true) { node = roughnessNode.mul(this.getTexture(scope).g); } else { node = roughnessNode; } } else if (scope === _MaterialNode.METALNESS) { const metalnessNode = this.getFloat(scope); if (material.metalnessMap && material.metalnessMap.isTexture === true) { node = metalnessNode.mul(this.getTexture(scope).b); } else { node = metalnessNode; } } else if (scope === _MaterialNode.EMISSIVE) { const emissiveIntensityNode = this.getFloat("emissiveIntensity"); const emissiveNode = this.getColor(scope).mul(emissiveIntensityNode); if (material.emissiveMap && material.emissiveMap.isTexture === true) { node = emissiveNode.mul(this.getTexture(scope)); } else { node = emissiveNode; } } else if (scope === _MaterialNode.NORMAL) { if (material.normalMap) { node = normalMap(this.getTexture("normal"), this.getCache("normalScale", "vec2")); node.normalMapType = material.normalMapType; } else if (material.bumpMap) { node = bumpMap(this.getTexture("bump").r, this.getFloat("bumpScale")); } else { node = normalView; } } else if (scope === _MaterialNode.CLEARCOAT) { const clearcoatNode = this.getFloat(scope); if (material.clearcoatMap && material.clearcoatMap.isTexture === true) { node = clearcoatNode.mul(this.getTexture(scope).r); } else { node = clearcoatNode; } } else if (scope === _MaterialNode.CLEARCOAT_ROUGHNESS) { const clearcoatRoughnessNode = this.getFloat(scope); if (material.clearcoatRoughnessMap && material.clearcoatRoughnessMap.isTexture === true) { node = clearcoatRoughnessNode.mul(this.getTexture(scope).r); } else { node = clearcoatRoughnessNode; } } else if (scope === _MaterialNode.CLEARCOAT_NORMAL) { if (material.clearcoatNormalMap) { node = normalMap(this.getTexture(scope), this.getCache(scope + "Scale", "vec2")); } else { node = normalView; } } else if (scope === _MaterialNode.SHEEN) { const sheenNode = this.getColor("sheenColor").mul(this.getFloat("sheen")); if (material.sheenColorMap && material.sheenColorMap.isTexture === true) { node = sheenNode.mul(this.getTexture("sheenColor").rgb); } else { node = sheenNode; } } else if (scope === _MaterialNode.SHEEN_ROUGHNESS) { const sheenRoughnessNode = this.getFloat(scope); if (material.sheenRoughnessMap && material.sheenRoughnessMap.isTexture === true) { node = sheenRoughnessNode.mul(this.getTexture(scope).a); } else { node = sheenRoughnessNode; } node = node.clamp(0.07, 1); } else if (scope === _MaterialNode.ANISOTROPY) { if (material.anisotropyMap && material.anisotropyMap.isTexture === true) { const anisotropyPolar = this.getTexture(scope); const anisotropyMat = mat2(materialAnisotropyVector.x, materialAnisotropyVector.y, materialAnisotropyVector.y.negate(), materialAnisotropyVector.x); node = anisotropyMat.mul(anisotropyPolar.rg.mul(2).sub(vec2(1)).normalize().mul(anisotropyPolar.b)); } else { node = materialAnisotropyVector; } } else if (scope === _MaterialNode.IRIDESCENCE_THICKNESS) { const iridescenceThicknessMaximum = reference("1", "float", material.iridescenceThicknessRange); if (material.iridescenceThicknessMap) { const iridescenceThicknessMinimum = reference("0", "float", material.iridescenceThicknessRange); node = iridescenceThicknessMaximum.sub(iridescenceThicknessMinimum).mul(this.getTexture(scope).g).add(iridescenceThicknessMinimum); } else { node = iridescenceThicknessMaximum; } } else if (scope === _MaterialNode.TRANSMISSION) { const transmissionNode = this.getFloat(scope); if (material.transmissionMap) { node = transmissionNode.mul(this.getTexture(scope).r); } else { node = transmissionNode; } } else if (scope === _MaterialNode.THICKNESS) { const thicknessNode = this.getFloat(scope); if (material.thicknessMap) { node = thicknessNode.mul(this.getTexture(scope).g); } else { node = thicknessNode; } } else if (scope === _MaterialNode.IOR) { node = this.getFloat(scope); } else if (scope === _MaterialNode.LIGHT_MAP) { node = this.getTexture(scope).rgb.mul(this.getFloat("lightMapIntensity")); } else if (scope === _MaterialNode.AO_MAP) { node = this.getTexture(scope).r.sub(1).mul(this.getFloat("aoMapIntensity")).add(1); } else { const outputType = this.getNodeType(builder); node = this.getCache(scope, outputType); } return node; } }; MaterialNode.ALPHA_TEST = "alphaTest"; MaterialNode.COLOR = "color"; MaterialNode.OPACITY = "opacity"; MaterialNode.SHININESS = "shininess"; MaterialNode.SPECULAR = "specular"; MaterialNode.SPECULAR_STRENGTH = "specularStrength"; MaterialNode.SPECULAR_INTENSITY = "specularIntensity"; MaterialNode.SPECULAR_COLOR = "specularColor"; MaterialNode.REFLECTIVITY = "reflectivity"; MaterialNode.ROUGHNESS = "roughness"; MaterialNode.METALNESS = "metalness"; MaterialNode.NORMAL = "normal"; MaterialNode.CLEARCOAT = "clearcoat"; MaterialNode.CLEARCOAT_ROUGHNESS = "clearcoatRoughness"; MaterialNode.CLEARCOAT_NORMAL = "clearcoatNormal"; MaterialNode.EMISSIVE = "emissive"; MaterialNode.ROTATION = "rotation"; MaterialNode.SHEEN = "sheen"; MaterialNode.SHEEN_ROUGHNESS = "sheenRoughness"; MaterialNode.ANISOTROPY = "anisotropy"; MaterialNode.IRIDESCENCE = "iridescence"; MaterialNode.IRIDESCENCE_IOR = "iridescenceIOR"; MaterialNode.IRIDESCENCE_THICKNESS = "iridescenceThickness"; MaterialNode.IOR = "ior"; MaterialNode.TRANSMISSION = "transmission"; MaterialNode.THICKNESS = "thickness"; MaterialNode.ATTENUATION_DISTANCE = "attenuationDistance"; MaterialNode.ATTENUATION_COLOR = "attenuationColor"; MaterialNode.LINE_SCALE = "scale"; MaterialNode.LINE_DASH_SIZE = "dashSize"; MaterialNode.LINE_GAP_SIZE = "gapSize"; MaterialNode.LINE_WIDTH = "linewidth"; MaterialNode.LINE_DASH_OFFSET = "dashOffset"; MaterialNode.POINT_WIDTH = "pointWidth"; MaterialNode.DISPERSION = "dispersion"; MaterialNode.LIGHT_MAP = "light"; MaterialNode.AO_MAP = "ao"; var materialAlphaTest = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.ALPHA_TEST); var materialColor = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.COLOR); var materialShininess = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.SHININESS); var materialEmissive = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.EMISSIVE); var materialOpacity = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.OPACITY); var materialSpecular = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.SPECULAR); var materialSpecularIntensity = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.SPECULAR_INTENSITY); var materialSpecularColor = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.SPECULAR_COLOR); var materialSpecularStrength = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.SPECULAR_STRENGTH); var materialReflectivity = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.REFLECTIVITY); var materialRoughness = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.ROUGHNESS); var materialMetalness = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.METALNESS); var materialNormal = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.NORMAL).context({ getUV: null }); var materialClearcoat = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.CLEARCOAT); var materialClearcoatRoughness = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.CLEARCOAT_ROUGHNESS); var materialClearcoatNormal = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.CLEARCOAT_NORMAL).context({ getUV: null }); var materialRotation = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.ROTATION); var materialSheen = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.SHEEN); var materialSheenRoughness = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.SHEEN_ROUGHNESS); var materialAnisotropy = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.ANISOTROPY); var materialIridescence = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.IRIDESCENCE); var materialIridescenceIOR = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.IRIDESCENCE_IOR); var materialIridescenceThickness = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.IRIDESCENCE_THICKNESS); var materialTransmission = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.TRANSMISSION); var materialThickness = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.THICKNESS); var materialIOR = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.IOR); var materialAttenuationDistance = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.ATTENUATION_DISTANCE); var materialAttenuationColor = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.ATTENUATION_COLOR); var materialLineScale = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.LINE_SCALE); var materialLineDashSize = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.LINE_DASH_SIZE); var materialLineGapSize = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.LINE_GAP_SIZE); var materialLineWidth = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.LINE_WIDTH); var materialLineDashOffset = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.LINE_DASH_OFFSET); var materialPointWidth = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.POINT_WIDTH); var materialDispersion = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.DISPERSION); var materialLightMap = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.LIGHT_MAP); var materialAOMap = /* @__PURE__ */ nodeImmutable(MaterialNode, MaterialNode.AO_MAP); var materialAnisotropyVector = /* @__PURE__ */ uniform(new Vector22()).onReference(function(frame2) { return frame2.material; }).onRenderUpdate(function({ material }) { this.value.set(material.anisotropy * Math.cos(material.anisotropyRotation), material.anisotropy * Math.sin(material.anisotropyRotation)); }); var ModelViewProjectionNode = class extends TempNode { static get type() { return "ModelViewProjectionNode"; } constructor(positionNode = null) { super("vec4"); this.positionNode = positionNode; } setup(builder) { if (builder.shaderStage === "fragment") { return varying(builder.context.mvp); } const position = this.positionNode || positionLocal; const viewMatrix = builder.renderer.nodes.modelViewMatrix || modelViewMatrix; return cameraProjectionMatrix.mul(viewMatrix).mul(position); } }; var modelViewProjection = /* @__PURE__ */ nodeProxy(ModelViewProjectionNode); var IndexNode = class _IndexNode extends Node { static get type() { return "IndexNode"; } constructor(scope) { super("uint"); this.scope = scope; this.isInstanceIndexNode = true; } generate(builder) { const nodeType = this.getNodeType(builder); const scope = this.scope; let propertyName; if (scope === _IndexNode.VERTEX) { propertyName = builder.getVertexIndex(); } else if (scope === _IndexNode.INSTANCE) { propertyName = builder.getInstanceIndex(); } else if (scope === _IndexNode.DRAW) { propertyName = builder.getDrawIndex(); } else if (scope === _IndexNode.INVOCATION_LOCAL) { propertyName = builder.getInvocationLocalIndex(); } else if (scope === _IndexNode.INVOCATION_SUBGROUP) { propertyName = builder.getInvocationSubgroupIndex(); } else if (scope === _IndexNode.SUBGROUP) { propertyName = builder.getSubgroupIndex(); } else { throw new Error("THREE.IndexNode: Unknown scope: " + scope); } let output2; if (builder.shaderStage === "vertex" || builder.shaderStage === "compute") { output2 = propertyName; } else { const nodeVarying = varying(this); output2 = nodeVarying.build(builder, nodeType); } return output2; } }; IndexNode.VERTEX = "vertex"; IndexNode.INSTANCE = "instance"; IndexNode.SUBGROUP = "subgroup"; IndexNode.INVOCATION_LOCAL = "invocationLocal"; IndexNode.INVOCATION_SUBGROUP = "invocationSubgroup"; IndexNode.DRAW = "draw"; var vertexIndex = /* @__PURE__ */ nodeImmutable(IndexNode, IndexNode.VERTEX); var instanceIndex = /* @__PURE__ */ nodeImmutable(IndexNode, IndexNode.INSTANCE); var subgroupIndex = /* @__PURE__ */ nodeImmutable(IndexNode, IndexNode.SUBGROUP); var invocationSubgroupIndex = /* @__PURE__ */ nodeImmutable(IndexNode, IndexNode.INVOCATION_SUBGROUP); var invocationLocalIndex = /* @__PURE__ */ nodeImmutable(IndexNode, IndexNode.INVOCATION_LOCAL); var drawIndex = /* @__PURE__ */ nodeImmutable(IndexNode, IndexNode.DRAW); var InstanceNode = class extends Node { static get type() { return "InstanceNode"; } constructor(instanceMesh) { super("void"); this.instanceMesh = instanceMesh; this.instanceMatrixNode = null; this.instanceColorNode = null; this.updateType = NodeUpdateType.FRAME; this.buffer = null; this.bufferColor = null; } setup(builder) { let instanceMatrixNode = this.instanceMatrixNode; let instanceColorNode = this.instanceColorNode; const instanceMesh = this.instanceMesh; if (instanceMatrixNode === null) { const instanceAttribute = instanceMesh.instanceMatrix; if (instanceMesh.count <= 1e3) { instanceMatrixNode = buffer(instanceAttribute.array, "mat4", Math.max(instanceMesh.count, 1)).element(instanceIndex); } else { const buffer2 = new InstancedInterleavedBuffer(instanceAttribute.array, 16, 1); this.buffer = buffer2; const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute; const instanceBuffers = [ // F.Signature -> bufferAttribute( array, type, stride, offset ) bufferFn(buffer2, "vec4", 16, 0), bufferFn(buffer2, "vec4", 16, 4), bufferFn(buffer2, "vec4", 16, 8), bufferFn(buffer2, "vec4", 16, 12) ]; instanceMatrixNode = mat4(...instanceBuffers); } this.instanceMatrixNode = instanceMatrixNode; } const instanceColorAttribute = instanceMesh.instanceColor; if (instanceColorAttribute && instanceColorNode === null) { const buffer2 = new InstancedBufferAttribute(instanceColorAttribute.array, 3); const bufferFn = instanceColorAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute; this.bufferColor = buffer2; instanceColorNode = vec3(bufferFn(buffer2, "vec3", 3, 0)); this.instanceColorNode = instanceColorNode; } const instancePosition = instanceMatrixNode.mul(positionLocal).xyz; positionLocal.assign(instancePosition); if (builder.hasGeometryAttribute("normal")) { const instanceNormal = transformNormal(normalLocal, instanceMatrixNode); normalLocal.assign(instanceNormal); } if (this.instanceColorNode !== null) { varyingProperty("vec3", "vInstanceColor").assign(this.instanceColorNode); } } update() { if (this.instanceMesh.instanceMatrix.usage !== DynamicDrawUsage && this.buffer != null && this.instanceMesh.instanceMatrix.version !== this.buffer.version) { this.buffer.version = this.instanceMesh.instanceMatrix.version; } if (this.instanceMesh.instanceColor && this.instanceMesh.instanceColor.usage !== DynamicDrawUsage && this.bufferColor != null && this.instanceMesh.instanceColor.version !== this.bufferColor.version) { this.bufferColor.version = this.instanceMesh.instanceColor.version; } } }; var instance = /* @__PURE__ */ nodeProxy(InstanceNode); var BatchNode = class extends Node { static get type() { return "BatchNode"; } constructor(batchMesh) { super("void"); this.batchMesh = batchMesh; this.batchingIdNode = null; } setup(builder) { if (this.batchingIdNode === null) { if (builder.getDrawIndex() === null) { this.batchingIdNode = instanceIndex; } else { this.batchingIdNode = drawIndex; } } const getIndirectIndex = Fn(([id2]) => { const size2 = textureSize(textureLoad(this.batchMesh._indirectTexture), 0); const x3 = int(id2).modInt(int(size2)); const y3 = int(id2).div(int(size2)); return textureLoad(this.batchMesh._indirectTexture, ivec2(x3, y3)).x; }).setLayout({ name: "getIndirectIndex", type: "uint", inputs: [ { name: "id", type: "int" } ] }); const indirectId = getIndirectIndex(int(this.batchingIdNode)); const matricesTexture = this.batchMesh._matricesTexture; const size = textureSize(textureLoad(matricesTexture), 0); const j = float(indirectId).mul(4).toInt().toVar(); const x2 = j.modInt(size); const y2 = j.div(int(size)); const batchingMatrix = mat4( textureLoad(matricesTexture, ivec2(x2, y2)), textureLoad(matricesTexture, ivec2(x2.add(1), y2)), textureLoad(matricesTexture, ivec2(x2.add(2), y2)), textureLoad(matricesTexture, ivec2(x2.add(3), y2)) ); const colorsTexture = this.batchMesh._colorsTexture; if (colorsTexture !== null) { const getBatchingColor = Fn(([id2]) => { const size2 = textureSize(textureLoad(colorsTexture), 0).x; const j2 = id2; const x3 = j2.modInt(size2); const y3 = j2.div(size2); return textureLoad(colorsTexture, ivec2(x3, y3)).rgb; }).setLayout({ name: "getBatchingColor", type: "vec3", inputs: [ { name: "id", type: "int" } ] }); const color2 = getBatchingColor(indirectId); varyingProperty("vec3", "vBatchColor").assign(color2); } const bm = mat3(batchingMatrix); positionLocal.assign(batchingMatrix.mul(positionLocal)); const transformedNormal = normalLocal.div(vec3(bm[0].dot(bm[0]), bm[1].dot(bm[1]), bm[2].dot(bm[2]))); const batchingNormal = bm.mul(transformedNormal).xyz; normalLocal.assign(batchingNormal); if (builder.hasGeometryAttribute("tangent")) { tangentLocal.mulAssign(bm); } } }; var batch = /* @__PURE__ */ nodeProxy(BatchNode); var _frameId = /* @__PURE__ */ new WeakMap(); var SkinningNode = class extends Node { static get type() { return "SkinningNode"; } constructor(skinnedMesh, useReference = false) { super("void"); this.skinnedMesh = skinnedMesh; this.useReference = useReference; this.updateType = NodeUpdateType.OBJECT; this.skinIndexNode = attribute("skinIndex", "uvec4"); this.skinWeightNode = attribute("skinWeight", "vec4"); let bindMatrixNode, bindMatrixInverseNode, boneMatricesNode; if (useReference) { bindMatrixNode = reference("bindMatrix", "mat4"); bindMatrixInverseNode = reference("bindMatrixInverse", "mat4"); boneMatricesNode = referenceBuffer("skeleton.boneMatrices", "mat4", skinnedMesh.skeleton.bones.length); } else { bindMatrixNode = uniform(skinnedMesh.bindMatrix, "mat4"); bindMatrixInverseNode = uniform(skinnedMesh.bindMatrixInverse, "mat4"); boneMatricesNode = buffer(skinnedMesh.skeleton.boneMatrices, "mat4", skinnedMesh.skeleton.bones.length); } this.bindMatrixNode = bindMatrixNode; this.bindMatrixInverseNode = bindMatrixInverseNode; this.boneMatricesNode = boneMatricesNode; this.previousBoneMatricesNode = null; } getSkinnedPosition(boneMatrices = this.boneMatricesNode, position = positionLocal) { const { skinIndexNode, skinWeightNode, bindMatrixNode, bindMatrixInverseNode } = this; const boneMatX = boneMatrices.element(skinIndexNode.x); const boneMatY = boneMatrices.element(skinIndexNode.y); const boneMatZ = boneMatrices.element(skinIndexNode.z); const boneMatW = boneMatrices.element(skinIndexNode.w); const skinVertex = bindMatrixNode.mul(position); const skinned = add4( boneMatX.mul(skinWeightNode.x).mul(skinVertex), boneMatY.mul(skinWeightNode.y).mul(skinVertex), boneMatZ.mul(skinWeightNode.z).mul(skinVertex), boneMatW.mul(skinWeightNode.w).mul(skinVertex) ); return bindMatrixInverseNode.mul(skinned).xyz; } getSkinnedNormal(boneMatrices = this.boneMatricesNode, normal2 = normalLocal) { const { skinIndexNode, skinWeightNode, bindMatrixNode, bindMatrixInverseNode } = this; const boneMatX = boneMatrices.element(skinIndexNode.x); const boneMatY = boneMatrices.element(skinIndexNode.y); const boneMatZ = boneMatrices.element(skinIndexNode.z); const boneMatW = boneMatrices.element(skinIndexNode.w); let skinMatrix = add4( skinWeightNode.x.mul(boneMatX), skinWeightNode.y.mul(boneMatY), skinWeightNode.z.mul(boneMatZ), skinWeightNode.w.mul(boneMatW) ); skinMatrix = bindMatrixInverseNode.mul(skinMatrix).mul(bindMatrixNode); return skinMatrix.transformDirection(normal2).xyz; } getPreviousSkinnedPosition(builder) { const skinnedMesh = builder.object; if (this.previousBoneMatricesNode === null) { skinnedMesh.skeleton.previousBoneMatrices = new Float32Array(skinnedMesh.skeleton.boneMatrices); this.previousBoneMatricesNode = referenceBuffer("skeleton.previousBoneMatrices", "mat4", skinnedMesh.skeleton.bones.length); } return this.getSkinnedPosition(this.previousBoneMatricesNode, positionPrevious); } needsPreviousBoneMatrices(builder) { const mrt = builder.renderer.getMRT(); return mrt && mrt.has("velocity"); } setup(builder) { if (this.needsPreviousBoneMatrices(builder)) { positionPrevious.assign(this.getPreviousSkinnedPosition(builder)); } const skinPosition = this.getSkinnedPosition(); positionLocal.assign(skinPosition); if (builder.hasGeometryAttribute("normal")) { const skinNormal = this.getSkinnedNormal(); normalLocal.assign(skinNormal); if (builder.hasGeometryAttribute("tangent")) { tangentLocal.assign(skinNormal); } } } generate(builder, output2) { if (output2 !== "void") { return positionLocal.build(builder, output2); } } update(frame2) { const object = this.useReference ? frame2.object : this.skinnedMesh; const skeleton = object.skeleton; if (_frameId.get(skeleton) === frame2.frameId) return; _frameId.set(skeleton, frame2.frameId); if (this.previousBoneMatricesNode !== null) skeleton.previousBoneMatrices.set(skeleton.boneMatrices); skeleton.update(); } }; var skinningReference = (skinnedMesh) => nodeObject(new SkinningNode(skinnedMesh, true)); var LoopNode = class extends Node { static get type() { return "LoopNode"; } constructor(params = []) { super(); this.params = params; } getVarName(index5) { return String.fromCharCode("i".charCodeAt() + index5); } getProperties(builder) { const properties = builder.getNodeProperties(this); if (properties.stackNode !== void 0) return properties; const inputs = {}; for (let i = 0, l = this.params.length - 1; i < l; i++) { const param = this.params[i]; const name = param.isNode !== true && param.name || this.getVarName(i); const type = param.isNode !== true && param.type || "int"; inputs[name] = expression(name, type); } const stack2 = builder.addStack(); properties.returnsNode = this.params[this.params.length - 1](inputs, stack2, builder); properties.stackNode = stack2; builder.removeStack(); return properties; } getNodeType(builder) { const { returnsNode } = this.getProperties(builder); return returnsNode ? returnsNode.getNodeType(builder) : "void"; } setup(builder) { this.getProperties(builder); } generate(builder) { const properties = this.getProperties(builder); const params = this.params; const stackNode = properties.stackNode; for (let i = 0, l = params.length - 1; i < l; i++) { const param = params[i]; let start = null, end = null, name = null, type = null, condition = null, update4 = null; if (param.isNode) { type = "int"; name = this.getVarName(i); start = "0"; end = param.build(builder, type); condition = "<"; } else { type = param.type || "int"; name = param.name || this.getVarName(i); start = param.start; end = param.end; condition = param.condition; update4 = param.update; if (typeof start === "number") start = builder.generateConst(type, start); else if (start && start.isNode) start = start.build(builder, type); if (typeof end === "number") end = builder.generateConst(type, end); else if (end && end.isNode) end = end.build(builder, type); if (start !== void 0 && end === void 0) { start = start + " - 1"; end = "0"; condition = ">="; } else if (end !== void 0 && start === void 0) { start = "0"; condition = "<"; } if (condition === void 0) { if (Number(start) > Number(end)) { condition = ">="; } else { condition = "<"; } } } const internalParam = { start, end, condition }; const startSnippet = internalParam.start; const endSnippet = internalParam.end; let declarationSnippet = ""; let conditionalSnippet = ""; let updateSnippet = ""; if (!update4) { if (type === "int" || type === "uint") { if (condition.includes("<")) update4 = "++"; else update4 = "--"; } else { if (condition.includes("<")) update4 = "+= 1."; else update4 = "-= 1."; } } declarationSnippet += builder.getVar(type, name) + " = " + startSnippet; conditionalSnippet += name + " " + condition + " " + endSnippet; updateSnippet += name + " " + update4; const forSnippet = `for ( ${declarationSnippet}; ${conditionalSnippet}; ${updateSnippet} )`; builder.addFlowCode((i === 0 ? "\n" : "") + builder.tab + forSnippet + " {\n\n").addFlowTab(); } const stackSnippet = stackNode.build(builder, "void"); const returnsSnippet = properties.returnsNode ? properties.returnsNode.build(builder) : ""; builder.removeFlowTab().addFlowCode("\n" + builder.tab + stackSnippet); for (let i = 0, l = this.params.length - 1; i < l; i++) { builder.addFlowCode((i === 0 ? "" : builder.tab) + "}\n\n").removeFlowTab(); } builder.addFlowTab(); return returnsSnippet; } }; var Loop = (...params) => nodeObject(new LoopNode(nodeArray(params, "int"))).append(); var Break = () => expression("break").append(); var _morphTextures = /* @__PURE__ */ new WeakMap(); var _morphVec4 = /* @__PURE__ */ new Vector42(); var getMorph = /* @__PURE__ */ Fn(({ bufferMap, influence, stride, width, depth: depth2, offset }) => { const texelIndex = int(vertexIndex).mul(stride).add(offset); const y2 = texelIndex.div(width); const x2 = texelIndex.sub(y2.mul(width)); const bufferAttrib = textureLoad(bufferMap, ivec2(x2, y2)).depth(depth2); return bufferAttrib.mul(influence); }); function getEntry(geometry) { const hasMorphPosition = geometry.morphAttributes.position !== void 0; const hasMorphNormals = geometry.morphAttributes.normal !== void 0; const hasMorphColors = geometry.morphAttributes.color !== void 0; const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; const morphTargetsCount = morphAttribute !== void 0 ? morphAttribute.length : 0; let entry = _morphTextures.get(geometry); if (entry === void 0 || entry.count !== morphTargetsCount) { let disposeTexture = function() { bufferTexture.dispose(); _morphTextures.delete(geometry); geometry.removeEventListener("dispose", disposeTexture); }; if (entry !== void 0) entry.texture.dispose(); const morphTargets = geometry.morphAttributes.position || []; const morphNormals = geometry.morphAttributes.normal || []; const morphColors = geometry.morphAttributes.color || []; let vertexDataCount = 0; if (hasMorphPosition === true) vertexDataCount = 1; if (hasMorphNormals === true) vertexDataCount = 2; if (hasMorphColors === true) vertexDataCount = 3; let width = geometry.attributes.position.count * vertexDataCount; let height = 1; const maxTextureSize = 4096; if (width > maxTextureSize) { height = Math.ceil(width / maxTextureSize); width = maxTextureSize; } const buffer2 = new Float32Array(width * height * 4 * morphTargetsCount); const bufferTexture = new DataArrayTexture2(buffer2, width, height, morphTargetsCount); bufferTexture.type = FloatType2; bufferTexture.needsUpdate = true; const vertexDataStride = vertexDataCount * 4; for (let i = 0; i < morphTargetsCount; i++) { const morphTarget = morphTargets[i]; const morphNormal = morphNormals[i]; const morphColor = morphColors[i]; const offset = width * height * 4 * i; for (let j = 0; j < morphTarget.count; j++) { const stride = j * vertexDataStride; if (hasMorphPosition === true) { _morphVec4.fromBufferAttribute(morphTarget, j); buffer2[offset + stride + 0] = _morphVec4.x; buffer2[offset + stride + 1] = _morphVec4.y; buffer2[offset + stride + 2] = _morphVec4.z; buffer2[offset + stride + 3] = 0; } if (hasMorphNormals === true) { _morphVec4.fromBufferAttribute(morphNormal, j); buffer2[offset + stride + 4] = _morphVec4.x; buffer2[offset + stride + 5] = _morphVec4.y; buffer2[offset + stride + 6] = _morphVec4.z; buffer2[offset + stride + 7] = 0; } if (hasMorphColors === true) { _morphVec4.fromBufferAttribute(morphColor, j); buffer2[offset + stride + 8] = _morphVec4.x; buffer2[offset + stride + 9] = _morphVec4.y; buffer2[offset + stride + 10] = _morphVec4.z; buffer2[offset + stride + 11] = morphColor.itemSize === 4 ? _morphVec4.w : 1; } } } entry = { count: morphTargetsCount, texture: bufferTexture, stride: vertexDataCount, size: new Vector22(width, height) }; _morphTextures.set(geometry, entry); geometry.addEventListener("dispose", disposeTexture); } return entry; } var MorphNode = class extends Node { static get type() { return "MorphNode"; } constructor(mesh) { super("void"); this.mesh = mesh; this.morphBaseInfluence = uniform(1); this.updateType = NodeUpdateType.OBJECT; } setup(builder) { const { geometry } = builder; const hasMorphPosition = geometry.morphAttributes.position !== void 0; const hasMorphNormals = geometry.hasAttribute("normal") && geometry.morphAttributes.normal !== void 0; const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color; const morphTargetsCount = morphAttribute !== void 0 ? morphAttribute.length : 0; const { texture: bufferMap, stride, size } = getEntry(geometry); if (hasMorphPosition === true) positionLocal.mulAssign(this.morphBaseInfluence); if (hasMorphNormals === true) normalLocal.mulAssign(this.morphBaseInfluence); const width = int(size.width); Loop(morphTargetsCount, ({ i }) => { const influence = float(0).toVar(); if (this.mesh.count > 1 && (this.mesh.morphTexture !== null && this.mesh.morphTexture !== void 0)) { influence.assign(textureLoad(this.mesh.morphTexture, ivec2(int(i).add(1), int(instanceIndex))).r); } else { influence.assign(reference("morphTargetInfluences", "float").element(i).toVar()); } if (hasMorphPosition === true) { positionLocal.addAssign(getMorph({ bufferMap, influence, stride, width, depth: i, offset: int(0) })); } if (hasMorphNormals === true) { normalLocal.addAssign(getMorph({ bufferMap, influence, stride, width, depth: i, offset: int(1) })); } }); } update() { const morphBaseInfluence = this.morphBaseInfluence; if (this.mesh.geometry.morphTargetsRelative) { morphBaseInfluence.value = 1; } else { morphBaseInfluence.value = 1 - this.mesh.morphTargetInfluences.reduce((a2, b) => a2 + b, 0); } } }; var morphReference = /* @__PURE__ */ nodeProxy(MorphNode); var LightingNode = class extends Node { static get type() { return "LightingNode"; } constructor() { super("vec3"); this.isLightingNode = true; } generate() { console.warn("Abstract function."); } }; var AONode = class extends LightingNode { static get type() { return "AONode"; } constructor(aoNode = null) { super(); this.aoNode = aoNode; } setup(builder) { builder.context.ambientOcclusion.mulAssign(this.aoNode); } }; var LightingContextNode = class extends ContextNode { static get type() { return "LightingContextNode"; } constructor(node, lightingModel = null, backdropNode = null, backdropAlphaNode = null) { super(node); this.lightingModel = lightingModel; this.backdropNode = backdropNode; this.backdropAlphaNode = backdropAlphaNode; this._value = null; } getContext() { const { backdropNode, backdropAlphaNode } = this; const directDiffuse = vec3().toVar("directDiffuse"), directSpecular = vec3().toVar("directSpecular"), indirectDiffuse = vec3().toVar("indirectDiffuse"), indirectSpecular = vec3().toVar("indirectSpecular"); const reflectedLight = { directDiffuse, directSpecular, indirectDiffuse, indirectSpecular }; const context2 = { radiance: vec3().toVar("radiance"), irradiance: vec3().toVar("irradiance"), iblIrradiance: vec3().toVar("iblIrradiance"), ambientOcclusion: float(1).toVar("ambientOcclusion"), reflectedLight, backdrop: backdropNode, backdropAlpha: backdropAlphaNode }; return context2; } setup(builder) { this.value = this._value || (this._value = this.getContext()); this.value.lightingModel = this.lightingModel || builder.context.lightingModel; return super.setup(builder); } }; var lightingContext = /* @__PURE__ */ nodeProxy(LightingContextNode); var IrradianceNode = class extends LightingNode { static get type() { return "IrradianceNode"; } constructor(node) { super(); this.node = node; } setup(builder) { builder.context.irradiance.addAssign(this.node); } }; var screenSizeVec; var viewportVec; var ScreenNode = class _ScreenNode extends Node { static get type() { return "ScreenNode"; } constructor(scope) { super(); this.scope = scope; this.isViewportNode = true; } getNodeType() { if (this.scope === _ScreenNode.VIEWPORT) return "vec4"; else return "vec2"; } getUpdateType() { let updateType = NodeUpdateType.NONE; if (this.scope === _ScreenNode.SIZE || this.scope === _ScreenNode.VIEWPORT) { updateType = NodeUpdateType.RENDER; } this.updateType = updateType; return updateType; } update({ renderer: renderer3 }) { const renderTarget = renderer3.getRenderTarget(); if (this.scope === _ScreenNode.VIEWPORT) { if (renderTarget !== null) { viewportVec.copy(renderTarget.viewport); } else { renderer3.getViewport(viewportVec); viewportVec.multiplyScalar(renderer3.getPixelRatio()); } } else { if (renderTarget !== null) { screenSizeVec.width = renderTarget.width; screenSizeVec.height = renderTarget.height; } else { renderer3.getDrawingBufferSize(screenSizeVec); } } } setup() { const scope = this.scope; let output2 = null; if (scope === _ScreenNode.SIZE) { output2 = uniform(screenSizeVec || (screenSizeVec = new Vector22())); } else if (scope === _ScreenNode.VIEWPORT) { output2 = uniform(viewportVec || (viewportVec = new Vector42())); } else { output2 = vec2(screenCoordinate.div(screenSize)); } return output2; } generate(builder) { if (this.scope === _ScreenNode.COORDINATE) { let coord = builder.getFragCoord(); if (builder.isFlipY()) { const size = builder.getNodeProperties(screenSize).outputNode.build(builder); coord = `${builder.getType("vec2")}( ${coord}.x, ${size}.y - ${coord}.y )`; } return coord; } return super.generate(builder); } }; ScreenNode.COORDINATE = "coordinate"; ScreenNode.VIEWPORT = "viewport"; ScreenNode.SIZE = "size"; ScreenNode.UV = "uv"; var screenUV = /* @__PURE__ */ nodeImmutable(ScreenNode, ScreenNode.UV); var screenSize = /* @__PURE__ */ nodeImmutable(ScreenNode, ScreenNode.SIZE); var screenCoordinate = /* @__PURE__ */ nodeImmutable(ScreenNode, ScreenNode.COORDINATE); var viewport = /* @__PURE__ */ nodeImmutable(ScreenNode, ScreenNode.VIEWPORT); var viewportSize = viewport.zw; var viewportCoordinate = /* @__PURE__ */ screenCoordinate.sub(viewport.xy); var _size$4 = /* @__PURE__ */ new Vector22(); var ViewportTextureNode = class extends TextureNode { static get type() { return "ViewportTextureNode"; } constructor(uvNode = screenUV, levelNode = null, framebufferTexture = null) { if (framebufferTexture === null) { framebufferTexture = new FramebufferTexture(); framebufferTexture.minFilter = LinearMipmapLinearFilter2; } super(framebufferTexture, uvNode, levelNode); this.generateMipmaps = false; this.isOutputTextureNode = true; this.updateBeforeType = NodeUpdateType.FRAME; } updateBefore(frame2) { const renderer3 = frame2.renderer; renderer3.getDrawingBufferSize(_size$4); const framebufferTexture = this.value; if (framebufferTexture.image.width !== _size$4.width || framebufferTexture.image.height !== _size$4.height) { framebufferTexture.image.width = _size$4.width; framebufferTexture.image.height = _size$4.height; framebufferTexture.needsUpdate = true; } const currentGenerateMipmaps = framebufferTexture.generateMipmaps; framebufferTexture.generateMipmaps = this.generateMipmaps; renderer3.copyFramebufferToTexture(framebufferTexture); framebufferTexture.generateMipmaps = currentGenerateMipmaps; } clone() { const viewportTextureNode = new this.constructor(this.uvNode, this.levelNode, this.value); viewportTextureNode.generateMipmaps = this.generateMipmaps; return viewportTextureNode; } }; var viewportMipTexture = /* @__PURE__ */ nodeProxy(ViewportTextureNode, null, null, { generateMipmaps: true }); var sharedDepthbuffer = null; var ViewportDepthTextureNode = class extends ViewportTextureNode { static get type() { return "ViewportDepthTextureNode"; } constructor(uvNode = screenUV, levelNode = null) { if (sharedDepthbuffer === null) { sharedDepthbuffer = new DepthTexture2(); } super(uvNode, levelNode, sharedDepthbuffer); } }; var viewportDepthTexture = /* @__PURE__ */ nodeProxy(ViewportDepthTextureNode); var ViewportDepthNode = class _ViewportDepthNode extends Node { static get type() { return "ViewportDepthNode"; } constructor(scope, valueNode = null) { super("float"); this.scope = scope; this.valueNode = valueNode; this.isViewportDepthNode = true; } generate(builder) { const { scope } = this; if (scope === _ViewportDepthNode.DEPTH_BASE) { return builder.getFragDepth(); } return super.generate(builder); } setup({ camera: camera3 }) { const { scope } = this; const value = this.valueNode; let node = null; if (scope === _ViewportDepthNode.DEPTH_BASE) { if (value !== null) { node = depthBase().assign(value); } } else if (scope === _ViewportDepthNode.DEPTH) { if (camera3.isPerspectiveCamera) { node = viewZToPerspectiveDepth(positionView.z, cameraNear, cameraFar); } else { node = viewZToOrthographicDepth(positionView.z, cameraNear, cameraFar); } } else if (scope === _ViewportDepthNode.LINEAR_DEPTH) { if (value !== null) { if (camera3.isPerspectiveCamera) { const viewZ = perspectiveDepthToViewZ(value, cameraNear, cameraFar); node = viewZToOrthographicDepth(viewZ, cameraNear, cameraFar); } else { node = value; } } else { node = viewZToOrthographicDepth(positionView.z, cameraNear, cameraFar); } } return node; } }; ViewportDepthNode.DEPTH_BASE = "depthBase"; ViewportDepthNode.DEPTH = "depth"; ViewportDepthNode.LINEAR_DEPTH = "linearDepth"; var viewZToOrthographicDepth = (viewZ, near, far) => viewZ.add(near).div(near.sub(far)); var viewZToPerspectiveDepth = (viewZ, near, far) => near.add(viewZ).mul(far).div(far.sub(near).mul(viewZ)); var perspectiveDepthToViewZ = (depth2, near, far) => near.mul(far).div(far.sub(near).mul(depth2).sub(far)); var perspectiveDepthToLogarithmicDepth = (perspectiveW, near, far) => { near = near.max(1e-6).toVar(); const numerator = log2(perspectiveW.div(near).add(1)); const denominator = log2(far.div(near).add(1)); return numerator.div(denominator); }; var depthBase = /* @__PURE__ */ nodeProxy(ViewportDepthNode, ViewportDepthNode.DEPTH_BASE); var depth = /* @__PURE__ */ nodeImmutable(ViewportDepthNode, ViewportDepthNode.DEPTH); var linearDepth = /* @__PURE__ */ nodeProxy(ViewportDepthNode, ViewportDepthNode.LINEAR_DEPTH); var viewportLinearDepth = /* @__PURE__ */ linearDepth(viewportDepthTexture()); depth.assign = (value) => depthBase(value); var ClippingNode = class _ClippingNode extends Node { static get type() { return "ClippingNode"; } constructor(scope = _ClippingNode.DEFAULT) { super(); this.scope = scope; } setup(builder) { super.setup(builder); const clippingContext = builder.clippingContext; const { localClipIntersection, localClippingCount, globalClippingCount } = clippingContext; const numClippingPlanes = globalClippingCount + localClippingCount; const numUnionClippingPlanes = localClipIntersection ? numClippingPlanes - localClippingCount : numClippingPlanes; if (this.scope === _ClippingNode.ALPHA_TO_COVERAGE) { return this.setupAlphaToCoverage(clippingContext.planes, numClippingPlanes, numUnionClippingPlanes); } else { return this.setupDefault(clippingContext.planes, numClippingPlanes, numUnionClippingPlanes); } } setupAlphaToCoverage(planes, numClippingPlanes, numUnionClippingPlanes) { return Fn(() => { const clippingPlanes = uniformArray(planes); const distanceToPlane = property("float", "distanceToPlane"); const distanceGradient = property("float", "distanceToGradient"); const clipOpacity = property("float", "clipOpacity"); clipOpacity.assign(1); let plane; Loop(numUnionClippingPlanes, ({ i }) => { plane = clippingPlanes.element(i); distanceToPlane.assign(positionView.dot(plane.xyz).negate().add(plane.w)); distanceGradient.assign(distanceToPlane.fwidth().div(2)); clipOpacity.mulAssign(smoothstep2(distanceGradient.negate(), distanceGradient, distanceToPlane)); clipOpacity.equal(0).discard(); }); if (numUnionClippingPlanes < numClippingPlanes) { const unionClipOpacity = property("float", "unionclipOpacity"); unionClipOpacity.assign(1); Loop({ start: numUnionClippingPlanes, end: numClippingPlanes }, ({ i }) => { plane = clippingPlanes.element(i); distanceToPlane.assign(positionView.dot(plane.xyz).negate().add(plane.w)); distanceGradient.assign(distanceToPlane.fwidth().div(2)); unionClipOpacity.mulAssign(smoothstep2(distanceGradient.negate(), distanceGradient, distanceToPlane).oneMinus()); }); clipOpacity.mulAssign(unionClipOpacity.oneMinus()); } diffuseColor.a.mulAssign(clipOpacity); diffuseColor.a.equal(0).discard(); })(); } setupDefault(planes, numClippingPlanes, numUnionClippingPlanes) { return Fn(() => { const clippingPlanes = uniformArray(planes); let plane; Loop(numUnionClippingPlanes, ({ i }) => { plane = clippingPlanes.element(i); positionView.dot(plane.xyz).greaterThan(plane.w).discard(); }); if (numUnionClippingPlanes < numClippingPlanes) { const clipped = property("bool", "clipped"); clipped.assign(true); Loop({ start: numUnionClippingPlanes, end: numClippingPlanes }, ({ i }) => { plane = clippingPlanes.element(i); clipped.assign(positionView.dot(plane.xyz).greaterThan(plane.w).and(clipped)); }); clipped.discard(); } })(); } }; ClippingNode.ALPHA_TO_COVERAGE = "alphaToCoverage"; ClippingNode.DEFAULT = "default"; var clipping = () => nodeObject(new ClippingNode()); var clippingAlpha = () => nodeObject(new ClippingNode(ClippingNode.ALPHA_TO_COVERAGE)); var ALPHA_HASH_SCALE = 0.05; var hash2D = /* @__PURE__ */ Fn(([value]) => { return fract(mul(1e4, sin(mul(17, value.x).add(mul(0.1, value.y)))).mul(add4(0.1, abs(sin(mul(13, value.y).add(value.x)))))); }); var hash3D = /* @__PURE__ */ Fn(([value]) => { return hash2D(vec2(hash2D(value.xy), value.z)); }); var getAlphaHashThreshold = /* @__PURE__ */ Fn(([position]) => { const maxDeriv = max$1( length(dFdx(position.xyz)), length(dFdy(position.xyz)) ).toVar("maxDeriv"); const pixScale = float(1).div(float(ALPHA_HASH_SCALE).mul(maxDeriv)).toVar("pixScale"); const pixScales = vec2( exp2(floor(log2(pixScale))), exp2(ceil(log2(pixScale))) ).toVar("pixScales"); const alpha = vec2( hash3D(floor(pixScales.x.mul(position.xyz))), hash3D(floor(pixScales.y.mul(position.xyz))) ).toVar("alpha"); const lerpFactor = fract(log2(pixScale)).toVar("lerpFactor"); const x2 = add4(mul(lerpFactor.oneMinus(), alpha.x), mul(lerpFactor, alpha.y)).toVar("x"); const a2 = min$1(lerpFactor, lerpFactor.oneMinus()).toVar("a"); const cases = vec3( x2.mul(x2).div(mul(2, a2).mul(sub(1, a2))), x2.sub(mul(0.5, a2)).div(sub(1, a2)), sub(1, sub(1, x2).mul(sub(1, x2)).div(mul(2, a2).mul(sub(1, a2)))) ).toVar("cases"); const threshold = x2.lessThan(a2.oneMinus()).select(x2.lessThan(a2).select(cases.x, cases.y), cases.z); return clamp2(threshold, 1e-6, 1); }); var NodeMaterial = class extends Material2 { static get type() { return "NodeMaterial"; } constructor() { super(); this.isNodeMaterial = true; this.type = this.constructor.type; this.forceSinglePass = false; this.fog = true; this.lights = false; this.lightsNode = null; this.envNode = null; this.aoNode = null; this.colorNode = null; this.normalNode = null; this.opacityNode = null; this.backdropNode = null; this.backdropAlphaNode = null; this.alphaTestNode = null; this.positionNode = null; this.geometryNode = null; this.depthNode = null; this.shadowNode = null; this.shadowPositionNode = null; this.outputNode = null; this.mrtNode = null; this.fragmentNode = null; this.vertexNode = null; } customProgramCacheKey() { return this.type + getCacheKey$1(this); } build(builder) { this.setup(builder); } setupObserver(builder) { return new NodeMaterialObserver(builder); } setup(builder) { builder.context.setupNormal = () => this.setupNormal(builder); builder.addStack(); builder.stack.outputNode = this.vertexNode || this.setupPosition(builder); if (this.geometryNode !== null) { builder.stack.outputNode = builder.stack.outputNode.bypass(this.geometryNode); } builder.addFlow("vertex", builder.removeStack()); builder.addStack(); let resultNode; const clippingNode = this.setupClipping(builder); if (this.depthWrite === true) this.setupDepth(builder); if (this.fragmentNode === null) { this.setupDiffuseColor(builder); this.setupVariants(builder); const outgoingLightNode = this.setupLighting(builder); if (clippingNode !== null) builder.stack.add(clippingNode); const basicOutput = vec4(outgoingLightNode, diffuseColor.a).max(0); resultNode = this.setupOutput(builder, basicOutput); output.assign(resultNode); if (this.outputNode !== null) resultNode = this.outputNode; const renderTarget = builder.renderer.getRenderTarget(); if (renderTarget !== null) { const mrt = builder.renderer.getMRT(); const materialMRT = this.mrtNode; if (mrt !== null) { resultNode = mrt; if (materialMRT !== null) { resultNode = mrt.merge(materialMRT); } } else if (materialMRT !== null) { resultNode = materialMRT; } } } else { let fragmentNode = this.fragmentNode; if (fragmentNode.isOutputStructNode !== true) { fragmentNode = vec4(fragmentNode); } resultNode = this.setupOutput(builder, fragmentNode); } builder.stack.outputNode = resultNode; builder.addFlow("fragment", builder.removeStack()); builder.monitor = this.setupObserver(builder); } setupClipping(builder) { if (builder.clippingContext === null) return null; const { globalClippingCount, localClippingCount } = builder.clippingContext; let result = null; if (globalClippingCount || localClippingCount) { const samples = builder.renderer.samples; if (this.alphaToCoverage && samples > 1) { result = clippingAlpha(); } else { builder.stack.add(clipping()); } } return result; } setupDepth(builder) { const { renderer: renderer3, camera: camera3 } = builder; let depthNode = this.depthNode; if (depthNode === null) { const mrt = renderer3.getMRT(); if (mrt && mrt.has("depth")) { depthNode = mrt.get("depth"); } else if (renderer3.logarithmicDepthBuffer === true) { if (camera3.isPerspectiveCamera) { depthNode = perspectiveDepthToLogarithmicDepth(modelViewProjection().w, cameraNear, cameraFar); } else { depthNode = viewZToOrthographicDepth(positionView.z, cameraNear, cameraFar); } } } if (depthNode !== null) { depth.assign(depthNode).append(); } } setupPosition(builder) { const { object } = builder; const geometry = object.geometry; builder.addStack(); if (geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color) { morphReference(object).append(); } if (object.isSkinnedMesh === true) { skinningReference(object).append(); } if (this.displacementMap) { const displacementMap = materialReference("displacementMap", "texture"); const displacementScale = materialReference("displacementScale", "float"); const displacementBias = materialReference("displacementBias", "float"); positionLocal.addAssign(normalLocal.normalize().mul(displacementMap.x.mul(displacementScale).add(displacementBias))); } if (object.isBatchedMesh) { batch(object).append(); } if (object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true) { instance(object).append(); } if (this.positionNode !== null) { positionLocal.assign(this.positionNode); } const mvp = modelViewProjection(); builder.context.vertex = builder.removeStack(); builder.context.mvp = mvp; return mvp; } setupDiffuseColor({ object, geometry }) { let colorNode = this.colorNode ? vec4(this.colorNode) : materialColor; if (this.vertexColors === true && geometry.hasAttribute("color")) { colorNode = vec4(colorNode.xyz.mul(attribute("color", "vec3")), colorNode.a); } if (object.instanceColor) { const instanceColor = varyingProperty("vec3", "vInstanceColor"); colorNode = instanceColor.mul(colorNode); } if (object.isBatchedMesh && object._colorsTexture) { const batchColor = varyingProperty("vec3", "vBatchColor"); colorNode = batchColor.mul(colorNode); } diffuseColor.assign(colorNode); const opacityNode = this.opacityNode ? float(this.opacityNode) : materialOpacity; diffuseColor.a.assign(diffuseColor.a.mul(opacityNode)); if (this.alphaTestNode !== null || this.alphaTest > 0) { const alphaTestNode = this.alphaTestNode !== null ? float(this.alphaTestNode) : materialAlphaTest; diffuseColor.a.lessThanEqual(alphaTestNode).discard(); } if (this.alphaHash === true) { diffuseColor.a.lessThan(getAlphaHashThreshold(positionLocal)).discard(); } if (this.transparent === false && this.blending === NormalBlending2 && this.alphaToCoverage === false) { diffuseColor.a.assign(1); } } setupVariants() { } setupOutgoingLight() { return this.lights === true ? vec3(0) : diffuseColor.rgb; } setupNormal() { return this.normalNode ? vec3(this.normalNode) : materialNormal; } setupEnvironment() { let node = null; if (this.envNode) { node = this.envNode; } else if (this.envMap) { node = this.envMap.isCubeTexture ? materialReference("envMap", "cubeTexture") : materialReference("envMap", "texture"); } return node; } setupLightMap(builder) { let node = null; if (builder.material.lightMap) { node = new IrradianceNode(materialLightMap); } return node; } setupLights(builder) { const materialLightsNode = []; const envNode = this.setupEnvironment(builder); if (envNode && envNode.isLightingNode) { materialLightsNode.push(envNode); } const lightMapNode = this.setupLightMap(builder); if (lightMapNode && lightMapNode.isLightingNode) { materialLightsNode.push(lightMapNode); } if (this.aoNode !== null || builder.material.aoMap) { const aoNode = this.aoNode !== null ? this.aoNode : materialAOMap; materialLightsNode.push(new AONode(aoNode)); } let lightsN = this.lightsNode || builder.lightsNode; if (materialLightsNode.length > 0) { lightsN = builder.renderer.lighting.createNode([...lightsN.getLights(), ...materialLightsNode]); } return lightsN; } setupLightingModel() { } setupLighting(builder) { const { material } = builder; const { backdropNode, backdropAlphaNode, emissiveNode } = this; const lights = this.lights === true || this.lightsNode !== null; const lightsNode = lights ? this.setupLights(builder) : null; let outgoingLightNode = this.setupOutgoingLight(builder); if (lightsNode && lightsNode.getScope().hasLights) { const lightingModel = this.setupLightingModel(builder); outgoingLightNode = lightingContext(lightsNode, lightingModel, backdropNode, backdropAlphaNode); } else if (backdropNode !== null) { outgoingLightNode = vec3(backdropAlphaNode !== null ? mix(outgoingLightNode, backdropNode, backdropAlphaNode) : backdropNode); } if (emissiveNode && emissiveNode.isNode === true || material.emissive && material.emissive.isColor === true) { emissive.assign(vec3(emissiveNode ? emissiveNode : materialEmissive)); outgoingLightNode = outgoingLightNode.add(emissive); } return outgoingLightNode; } setupOutput(builder, outputNode) { if (this.fog === true) { const fogNode = builder.fogNode; if (fogNode) outputNode = vec4(fogNode.mix(outputNode.rgb, fogNode.colorNode), outputNode.a); } return outputNode; } setDefaultValues(material) { for (const property2 in material) { const value = material[property2]; if (this[property2] === void 0) { this[property2] = value; if (value && value.clone) this[property2] = value.clone(); } } const descriptors = Object.getOwnPropertyDescriptors(material.constructor.prototype); for (const key in descriptors) { if (Object.getOwnPropertyDescriptor(this.constructor.prototype, key) === void 0 && descriptors[key].get !== void 0) { Object.defineProperty(this.constructor.prototype, key, descriptors[key]); } } } toJSON(meta) { const isRoot = meta === void 0 || typeof meta === "string"; if (isRoot) { meta = { textures: {}, images: {}, nodes: {} }; } const data = Material2.prototype.toJSON.call(this, meta); const nodeChildren = getNodeChildren(this); data.inputNodes = {}; for (const { property: property2, childNode } of nodeChildren) { data.inputNodes[property2] = childNode.toJSON(meta).uuid; } function extractFromCache(cache2) { const values = []; for (const key in cache2) { const data2 = cache2[key]; delete data2.metadata; values.push(data2); } return values; } if (isRoot) { const textures = extractFromCache(meta.textures); const images = extractFromCache(meta.images); const nodes = extractFromCache(meta.nodes); if (textures.length > 0) data.textures = textures; if (images.length > 0) data.images = images; if (nodes.length > 0) data.nodes = nodes; } return data; } copy(source) { this.lightsNode = source.lightsNode; this.envNode = source.envNode; this.colorNode = source.colorNode; this.normalNode = source.normalNode; this.opacityNode = source.opacityNode; this.backdropNode = source.backdropNode; this.backdropAlphaNode = source.backdropAlphaNode; this.alphaTestNode = source.alphaTestNode; this.positionNode = source.positionNode; this.geometryNode = source.geometryNode; this.depthNode = source.depthNode; this.shadowNode = source.shadowNode; this.shadowPositionNode = source.shadowPositionNode; this.outputNode = source.outputNode; this.mrtNode = source.mrtNode; this.fragmentNode = source.fragmentNode; this.vertexNode = source.vertexNode; return super.copy(source); } }; var _defaultValues$d = /* @__PURE__ */ new LineBasicMaterial2(); var LineBasicNodeMaterial = class extends NodeMaterial { static get type() { return "LineBasicNodeMaterial"; } constructor(parameters) { super(); this.isLineBasicNodeMaterial = true; this.lights = false; this.setDefaultValues(_defaultValues$d); this.setValues(parameters); } }; var _defaultValues$c = /* @__PURE__ */ new LineDashedMaterial(); var LineDashedNodeMaterial = class extends NodeMaterial { static get type() { return "LineDashedNodeMaterial"; } constructor(parameters) { super(); this.isLineDashedNodeMaterial = true; this.lights = false; this.setDefaultValues(_defaultValues$c); this.offsetNode = null; this.dashScaleNode = null; this.dashSizeNode = null; this.gapSizeNode = null; this.setValues(parameters); } setupVariants() { const offsetNode = this.offsetNode; const dashScaleNode = this.dashScaleNode ? float(this.dashScaleNode) : materialLineScale; const dashSizeNode = this.dashSizeNode ? float(this.dashSizeNode) : materialLineDashSize; const gapSizeNode = this.dashSizeNode ? float(this.dashGapNode) : materialLineGapSize; dashSize.assign(dashSizeNode); gapSize.assign(gapSizeNode); const vLineDistance = varying(attribute("lineDistance").mul(dashScaleNode)); const vLineDistanceOffset = offsetNode ? vLineDistance.add(offsetNode) : vLineDistance; vLineDistanceOffset.mod(dashSize.add(gapSize)).greaterThan(dashSize).discard(); } }; var directionToColor = (node) => nodeObject(node).mul(0.5).add(0.5); var _defaultValues$a = /* @__PURE__ */ new MeshNormalMaterial(); var MeshNormalNodeMaterial = class extends NodeMaterial { static get type() { return "MeshNormalNodeMaterial"; } constructor(parameters) { super(); this.lights = false; this.isMeshNormalNodeMaterial = true; this.setDefaultValues(_defaultValues$a); this.setValues(parameters); } setupDiffuseColor() { const opacityNode = this.opacityNode ? float(this.opacityNode) : materialOpacity; diffuseColor.assign(vec4(directionToColor(transformedNormalView), opacityNode)); } }; var EquirectUVNode = class extends TempNode { static get type() { return "EquirectUVNode"; } constructor(dirNode = positionWorldDirection) { super("vec2"); this.dirNode = dirNode; } setup() { const dir = this.dirNode; const u = dir.z.atan2(dir.x).mul(1 / (Math.PI * 2)).add(0.5); const v = dir.y.clamp(-1, 1).asin().mul(1 / Math.PI).add(0.5); return vec2(u, v); } }; var equirectUV = /* @__PURE__ */ nodeProxy(EquirectUVNode); var CubeRenderTarget = class extends WebGLCubeRenderTarget2 { constructor(size = 1, options = {}) { super(size, options); this.isCubeRenderTarget = true; } fromEquirectangularTexture(renderer3, texture$1) { const currentMinFilter = texture$1.minFilter; const currentGenerateMipmaps = texture$1.generateMipmaps; texture$1.generateMipmaps = true; this.texture.type = texture$1.type; this.texture.colorSpace = texture$1.colorSpace; this.texture.generateMipmaps = texture$1.generateMipmaps; this.texture.minFilter = texture$1.minFilter; this.texture.magFilter = texture$1.magFilter; const geometry = new BoxGeometry2(5, 5, 5); const uvNode = equirectUV(positionWorldDirection); const material = new NodeMaterial(); material.colorNode = texture(texture$1, uvNode, 0); material.side = BackSide2; material.blending = NoBlending2; const mesh = new Mesh2(geometry, material); const scene3 = new Scene2(); scene3.add(mesh); if (texture$1.minFilter === LinearMipmapLinearFilter2) texture$1.minFilter = LinearFilter2; const camera3 = new CubeCamera2(1, 10, this); const currentMRT = renderer3.getMRT(); renderer3.setMRT(null); camera3.update(renderer3, scene3); renderer3.setMRT(currentMRT); texture$1.minFilter = currentMinFilter; texture$1.currentGenerateMipmaps = currentGenerateMipmaps; mesh.geometry.dispose(); mesh.material.dispose(); return this; } }; var _cache$1 = /* @__PURE__ */ new WeakMap(); var CubeMapNode = class extends TempNode { static get type() { return "CubeMapNode"; } constructor(envNode) { super("vec3"); this.envNode = envNode; this._cubeTexture = null; this._cubeTextureNode = cubeTexture(); const defaultTexture = new CubeTexture2(); defaultTexture.isRenderTargetTexture = true; this._defaultTexture = defaultTexture; this.updateBeforeType = NodeUpdateType.RENDER; } updateBefore(frame2) { const { renderer: renderer3, material } = frame2; const envNode = this.envNode; if (envNode.isTextureNode || envNode.isMaterialReferenceNode) { const texture2 = envNode.isTextureNode ? envNode.value : material[envNode.property]; if (texture2 && texture2.isTexture) { const mapping = texture2.mapping; if (mapping === EquirectangularReflectionMapping2 || mapping === EquirectangularRefractionMapping2) { if (_cache$1.has(texture2)) { const cubeMap = _cache$1.get(texture2); mapTextureMapping(cubeMap, texture2.mapping); this._cubeTexture = cubeMap; } else { const image = texture2.image; if (isEquirectangularMapReady$1(image)) { const renderTarget = new CubeRenderTarget(image.height); renderTarget.fromEquirectangularTexture(renderer3, texture2); mapTextureMapping(renderTarget.texture, texture2.mapping); this._cubeTexture = renderTarget.texture; _cache$1.set(texture2, renderTarget.texture); texture2.addEventListener("dispose", onTextureDispose); } else { this._cubeTexture = this._defaultTexture; } } this._cubeTextureNode.value = this._cubeTexture; } else { this._cubeTextureNode = this.envNode; } } } } setup(builder) { this.updateBefore(builder); return this._cubeTextureNode; } }; function isEquirectangularMapReady$1(image) { if (image === null || image === void 0) return false; return image.height > 0; } function onTextureDispose(event) { const texture2 = event.target; texture2.removeEventListener("dispose", onTextureDispose); const renderTarget = _cache$1.get(texture2); if (renderTarget !== void 0) { _cache$1.delete(texture2); renderTarget.dispose(); } } function mapTextureMapping(texture2, mapping) { if (mapping === EquirectangularReflectionMapping2) { texture2.mapping = CubeReflectionMapping2; } else if (mapping === EquirectangularRefractionMapping2) { texture2.mapping = CubeRefractionMapping2; } } var cubeMapNode = /* @__PURE__ */ nodeProxy(CubeMapNode); var BasicEnvironmentNode = class extends LightingNode { static get type() { return "BasicEnvironmentNode"; } constructor(envNode = null) { super(); this.envNode = envNode; } setup(builder) { builder.context.environment = cubeMapNode(this.envNode); } }; var BasicLightMapNode = class extends LightingNode { static get type() { return "BasicLightMapNode"; } constructor(lightMapNode = null) { super(); this.lightMapNode = lightMapNode; } setup(builder) { const RECIPROCAL_PI2 = float(1 / Math.PI); builder.context.irradianceLightMap = this.lightMapNode.mul(RECIPROCAL_PI2); } }; var LightingModel = class { start() { } finish() { } direct() { } directRectArea() { } indirect() { } ambientOcclusion() { } }; var BasicLightingModel = class extends LightingModel { constructor() { super(); } indirect(context2, stack2, builder) { const ambientOcclusion = context2.ambientOcclusion; const reflectedLight = context2.reflectedLight; const irradianceLightMap = builder.context.irradianceLightMap; reflectedLight.indirectDiffuse.assign(vec4(0)); if (irradianceLightMap) { reflectedLight.indirectDiffuse.addAssign(irradianceLightMap); } else { reflectedLight.indirectDiffuse.addAssign(vec4(1, 1, 1, 0)); } reflectedLight.indirectDiffuse.mulAssign(ambientOcclusion); reflectedLight.indirectDiffuse.mulAssign(diffuseColor.rgb); } finish(context2, stack2, builder) { const material = builder.material; const outgoingLight = context2.outgoingLight; const envNode = builder.context.environment; if (envNode) { switch (material.combine) { case MultiplyOperation2: outgoingLight.rgb.assign(mix(outgoingLight.rgb, outgoingLight.rgb.mul(envNode.rgb), materialSpecularStrength.mul(materialReflectivity))); break; case MixOperation2: outgoingLight.rgb.assign(mix(outgoingLight.rgb, envNode.rgb, materialSpecularStrength.mul(materialReflectivity))); break; case AddOperation2: outgoingLight.rgb.addAssign(envNode.rgb.mul(materialSpecularStrength.mul(materialReflectivity))); break; default: console.warn("THREE.BasicLightingModel: Unsupported .combine value:", material.combine); break; } } } }; var _defaultValues$9 = /* @__PURE__ */ new MeshBasicMaterial2(); var MeshBasicNodeMaterial = class extends NodeMaterial { static get type() { return "MeshBasicNodeMaterial"; } constructor(parameters) { super(); this.isMeshBasicNodeMaterial = true; this.lights = true; this.setDefaultValues(_defaultValues$9); this.setValues(parameters); } setupNormal() { return normalView; } setupEnvironment(builder) { const envNode = super.setupEnvironment(builder); return envNode ? new BasicEnvironmentNode(envNode) : null; } setupLightMap(builder) { let node = null; if (builder.material.lightMap) { node = new BasicLightMapNode(materialLightMap); } return node; } setupOutgoingLight() { return diffuseColor.rgb; } setupLightingModel() { return new BasicLightingModel(); } }; var F_Schlick = /* @__PURE__ */ Fn(({ f0, f90, dotVH }) => { const fresnel = dotVH.mul(-5.55473).sub(6.98316).mul(dotVH).exp2(); return f0.mul(fresnel.oneMinus()).add(f90.mul(fresnel)); }); var BRDF_Lambert = /* @__PURE__ */ Fn((inputs) => { return inputs.diffuseColor.mul(1 / Math.PI); }); var G_BlinnPhong_Implicit = () => float(0.25); var D_BlinnPhong = /* @__PURE__ */ Fn(({ dotNH }) => { return shininess.mul(float(0.5)).add(1).mul(float(1 / Math.PI)).mul(dotNH.pow(shininess)); }); var BRDF_BlinnPhong = /* @__PURE__ */ Fn(({ lightDirection }) => { const halfDir = lightDirection.add(positionViewDirection).normalize(); const dotNH = transformedNormalView.dot(halfDir).clamp(); const dotVH = positionViewDirection.dot(halfDir).clamp(); const F = F_Schlick({ f0: specularColor, f90: 1, dotVH }); const G = G_BlinnPhong_Implicit(); const D = D_BlinnPhong({ dotNH }); return F.mul(G).mul(D); }); var PhongLightingModel = class extends BasicLightingModel { constructor(specular = true) { super(); this.specular = specular; } direct({ lightDirection, lightColor, reflectedLight }) { const dotNL = transformedNormalView.dot(lightDirection).clamp(); const irradiance = dotNL.mul(lightColor); reflectedLight.directDiffuse.addAssign(irradiance.mul(BRDF_Lambert({ diffuseColor: diffuseColor.rgb }))); if (this.specular === true) { reflectedLight.directSpecular.addAssign(irradiance.mul(BRDF_BlinnPhong({ lightDirection })).mul(materialSpecularStrength)); } } indirect({ ambientOcclusion, irradiance, reflectedLight }) { reflectedLight.indirectDiffuse.addAssign(irradiance.mul(BRDF_Lambert({ diffuseColor }))); reflectedLight.indirectDiffuse.mulAssign(ambientOcclusion); } }; var _defaultValues$8 = /* @__PURE__ */ new MeshLambertMaterial2(); var MeshLambertNodeMaterial = class extends NodeMaterial { static get type() { return "MeshLambertNodeMaterial"; } constructor(parameters) { super(); this.isMeshLambertNodeMaterial = true; this.lights = true; this.setDefaultValues(_defaultValues$8); this.setValues(parameters); } setupEnvironment(builder) { const envNode = super.setupEnvironment(builder); return envNode ? new BasicEnvironmentNode(envNode) : null; } setupLightingModel() { return new PhongLightingModel(false); } }; var _defaultValues$7 = /* @__PURE__ */ new MeshPhongMaterial(); var MeshPhongNodeMaterial = class extends NodeMaterial { static get type() { return "MeshPhongNodeMaterial"; } constructor(parameters) { super(); this.isMeshPhongNodeMaterial = true; this.lights = true; this.shininessNode = null; this.specularNode = null; this.setDefaultValues(_defaultValues$7); this.setValues(parameters); } setupEnvironment(builder) { const envNode = super.setupEnvironment(builder); return envNode ? new BasicEnvironmentNode(envNode) : null; } setupLightingModel() { return new PhongLightingModel(); } setupVariants() { const shininessNode = (this.shininessNode ? float(this.shininessNode) : materialShininess).max(1e-4); shininess.assign(shininessNode); const specularNode = this.specularNode || materialSpecular; specularColor.assign(specularNode); } copy(source) { this.shininessNode = source.shininessNode; this.specularNode = source.specularNode; return super.copy(source); } }; var getGeometryRoughness = /* @__PURE__ */ Fn((builder) => { if (builder.geometry.hasAttribute("normal") === false) { return float(0); } const dxy = normalView.dFdx().abs().max(normalView.dFdy().abs()); const geometryRoughness = dxy.x.max(dxy.y).max(dxy.z); return geometryRoughness; }); var getRoughness = /* @__PURE__ */ Fn((inputs) => { const { roughness: roughness2 } = inputs; const geometryRoughness = getGeometryRoughness(); let roughnessFactor = roughness2.max(0.0525); roughnessFactor = roughnessFactor.add(geometryRoughness); roughnessFactor = roughnessFactor.min(1); return roughnessFactor; }); var V_GGX_SmithCorrelated = /* @__PURE__ */ Fn(({ alpha, dotNL, dotNV }) => { const a2 = alpha.pow2(); const gv = dotNL.mul(a2.add(a2.oneMinus().mul(dotNV.pow2())).sqrt()); const gl = dotNV.mul(a2.add(a2.oneMinus().mul(dotNL.pow2())).sqrt()); return div(0.5, gv.add(gl).max(EPSILON)); }).setLayout({ name: "V_GGX_SmithCorrelated", type: "float", inputs: [ { name: "alpha", type: "float" }, { name: "dotNL", type: "float" }, { name: "dotNV", type: "float" } ] }); var V_GGX_SmithCorrelated_Anisotropic = /* @__PURE__ */ Fn(({ alphaT: alphaT2, alphaB, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL }) => { const gv = dotNL.mul(vec3(alphaT2.mul(dotTV), alphaB.mul(dotBV), dotNV).length()); const gl = dotNV.mul(vec3(alphaT2.mul(dotTL), alphaB.mul(dotBL), dotNL).length()); const v = div(0.5, gv.add(gl)); return v.saturate(); }).setLayout({ name: "V_GGX_SmithCorrelated_Anisotropic", type: "float", inputs: [ { name: "alphaT", type: "float", qualifier: "in" }, { name: "alphaB", type: "float", qualifier: "in" }, { name: "dotTV", type: "float", qualifier: "in" }, { name: "dotBV", type: "float", qualifier: "in" }, { name: "dotTL", type: "float", qualifier: "in" }, { name: "dotBL", type: "float", qualifier: "in" }, { name: "dotNV", type: "float", qualifier: "in" }, { name: "dotNL", type: "float", qualifier: "in" } ] }); var D_GGX = /* @__PURE__ */ Fn(({ alpha, dotNH }) => { const a2 = alpha.pow2(); const denom = dotNH.pow2().mul(a2.oneMinus()).oneMinus(); return a2.div(denom.pow2()).mul(1 / Math.PI); }).setLayout({ name: "D_GGX", type: "float", inputs: [ { name: "alpha", type: "float" }, { name: "dotNH", type: "float" } ] }); var RECIPROCAL_PI = /* @__PURE__ */ float(1 / Math.PI); var D_GGX_Anisotropic = /* @__PURE__ */ Fn(({ alphaT: alphaT2, alphaB, dotNH, dotTH, dotBH }) => { const a2 = alphaT2.mul(alphaB); const v = vec3(alphaB.mul(dotTH), alphaT2.mul(dotBH), a2.mul(dotNH)); const v2 = v.dot(v); const w22 = a2.div(v2); return RECIPROCAL_PI.mul(a2.mul(w22.pow2())); }).setLayout({ name: "D_GGX_Anisotropic", type: "float", inputs: [ { name: "alphaT", type: "float", qualifier: "in" }, { name: "alphaB", type: "float", qualifier: "in" }, { name: "dotNH", type: "float", qualifier: "in" }, { name: "dotTH", type: "float", qualifier: "in" }, { name: "dotBH", type: "float", qualifier: "in" } ] }); var BRDF_GGX = /* @__PURE__ */ Fn((inputs) => { const { lightDirection, f0, f90, roughness: roughness2, f, USE_IRIDESCENCE, USE_ANISOTROPY } = inputs; const normalView2 = inputs.normalView || transformedNormalView; const alpha = roughness2.pow2(); const halfDir = lightDirection.add(positionViewDirection).normalize(); const dotNL = normalView2.dot(lightDirection).clamp(); const dotNV = normalView2.dot(positionViewDirection).clamp(); const dotNH = normalView2.dot(halfDir).clamp(); const dotVH = positionViewDirection.dot(halfDir).clamp(); let F = F_Schlick({ f0, f90, dotVH }); let V, D; if (defined(USE_IRIDESCENCE)) { F = iridescence.mix(F, f); } if (defined(USE_ANISOTROPY)) { const dotTL = anisotropyT.dot(lightDirection); const dotTV = anisotropyT.dot(positionViewDirection); const dotTH = anisotropyT.dot(halfDir); const dotBL = anisotropyB.dot(lightDirection); const dotBV = anisotropyB.dot(positionViewDirection); const dotBH = anisotropyB.dot(halfDir); V = V_GGX_SmithCorrelated_Anisotropic({ alphaT, alphaB: alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL }); D = D_GGX_Anisotropic({ alphaT, alphaB: alpha, dotNH, dotTH, dotBH }); } else { V = V_GGX_SmithCorrelated({ alpha, dotNL, dotNV }); D = D_GGX({ alpha, dotNH }); } return F.mul(V).mul(D); }); var DFGApprox = /* @__PURE__ */ Fn(({ roughness: roughness2, dotNV }) => { const c0 = vec4(-1, -0.0275, -0.572, 0.022); const c1 = vec4(1, 0.0425, 1.04, -0.04); const r = roughness2.mul(c0).add(c1); const a004 = r.x.mul(r.x).min(dotNV.mul(-9.28).exp2()).mul(r.x).add(r.y); const fab = vec2(-1.04, 1.04).mul(a004).add(r.zw); return fab; }).setLayout({ name: "DFGApprox", type: "vec2", inputs: [ { name: "roughness", type: "float" }, { name: "dotNV", type: "vec3" } ] }); var EnvironmentBRDF = /* @__PURE__ */ Fn((inputs) => { const { dotNV, specularColor: specularColor2, specularF90: specularF902, roughness: roughness2 } = inputs; const fab = DFGApprox({ dotNV, roughness: roughness2 }); return specularColor2.mul(fab.x).add(specularF902.mul(fab.y)); }); var Schlick_to_F0 = /* @__PURE__ */ Fn(({ f, f90, dotVH }) => { const x2 = dotVH.oneMinus().saturate(); const x22 = x2.mul(x2); const x5 = x2.mul(x22, x22).clamp(0, 0.9999); return f.sub(vec3(f90).mul(x5)).div(x5.oneMinus()); }).setLayout({ name: "Schlick_to_F0", type: "vec3", inputs: [ { name: "f", type: "vec3" }, { name: "f90", type: "float" }, { name: "dotVH", type: "float" } ] }); var D_Charlie = /* @__PURE__ */ Fn(({ roughness: roughness2, dotNH }) => { const alpha = roughness2.pow2(); const invAlpha = float(1).div(alpha); const cos2h = dotNH.pow2(); const sin2h = cos2h.oneMinus().max(78125e-7); return float(2).add(invAlpha).mul(sin2h.pow(invAlpha.mul(0.5))).div(2 * Math.PI); }).setLayout({ name: "D_Charlie", type: "float", inputs: [ { name: "roughness", type: "float" }, { name: "dotNH", type: "float" } ] }); var V_Neubelt = /* @__PURE__ */ Fn(({ dotNV, dotNL }) => { return float(1).div(float(4).mul(dotNL.add(dotNV).sub(dotNL.mul(dotNV)))); }).setLayout({ name: "V_Neubelt", type: "float", inputs: [ { name: "dotNV", type: "float" }, { name: "dotNL", type: "float" } ] }); var BRDF_Sheen = /* @__PURE__ */ Fn(({ lightDirection }) => { const halfDir = lightDirection.add(positionViewDirection).normalize(); const dotNL = transformedNormalView.dot(lightDirection).clamp(); const dotNV = transformedNormalView.dot(positionViewDirection).clamp(); const dotNH = transformedNormalView.dot(halfDir).clamp(); const D = D_Charlie({ roughness: sheenRoughness, dotNH }); const V = V_Neubelt({ dotNV, dotNL }); return sheen.mul(D).mul(V); }); var LTC_Uv = /* @__PURE__ */ Fn(({ N, V, roughness: roughness2 }) => { const LUT_SIZE = 64; const LUT_SCALE = (LUT_SIZE - 1) / LUT_SIZE; const LUT_BIAS = 0.5 / LUT_SIZE; const dotNV = N.dot(V).saturate(); const uv2 = vec2(roughness2, dotNV.oneMinus().sqrt()); uv2.assign(uv2.mul(LUT_SCALE).add(LUT_BIAS)); return uv2; }).setLayout({ name: "LTC_Uv", type: "vec2", inputs: [ { name: "N", type: "vec3" }, { name: "V", type: "vec3" }, { name: "roughness", type: "float" } ] }); var LTC_ClippedSphereFormFactor = /* @__PURE__ */ Fn(({ f }) => { const l = f.length(); return max$1(l.mul(l).add(f.z).div(l.add(1)), 0); }).setLayout({ name: "LTC_ClippedSphereFormFactor", type: "float", inputs: [ { name: "f", type: "vec3" } ] }); var LTC_EdgeVectorFormFactor = /* @__PURE__ */ Fn(({ v1, v2 }) => { const x2 = v1.dot(v2); const y2 = x2.abs().toVar(); const a2 = y2.mul(0.0145206).add(0.4965155).mul(y2).add(0.8543985).toVar(); const b = y2.add(4.1616724).mul(y2).add(3.417594).toVar(); const v = a2.div(b); const theta_sintheta = x2.greaterThan(0).select(v, max$1(x2.mul(x2).oneMinus(), 1e-7).inverseSqrt().mul(0.5).sub(v)); return v1.cross(v2).mul(theta_sintheta); }).setLayout({ name: "LTC_EdgeVectorFormFactor", type: "vec3", inputs: [ { name: "v1", type: "vec3" }, { name: "v2", type: "vec3" } ] }); var LTC_Evaluate = /* @__PURE__ */ Fn(({ N, V, P, mInv, p0, p1, p2, p3 }) => { const v1 = p1.sub(p0).toVar(); const v2 = p3.sub(p0).toVar(); const lightNormal = v1.cross(v2); const result = vec3().toVar(); If(lightNormal.dot(P.sub(p0)).greaterThanEqual(0), () => { const T1 = V.sub(N.mul(V.dot(N))).normalize(); const T2 = N.cross(T1).negate(); const mat = mInv.mul(mat3(T1, T2, N).transpose()).toVar(); const coords0 = mat.mul(p0.sub(P)).normalize().toVar(); const coords1 = mat.mul(p1.sub(P)).normalize().toVar(); const coords2 = mat.mul(p2.sub(P)).normalize().toVar(); const coords3 = mat.mul(p3.sub(P)).normalize().toVar(); const vectorFormFactor = vec3(0).toVar(); vectorFormFactor.addAssign(LTC_EdgeVectorFormFactor({ v1: coords0, v2: coords1 })); vectorFormFactor.addAssign(LTC_EdgeVectorFormFactor({ v1: coords1, v2: coords2 })); vectorFormFactor.addAssign(LTC_EdgeVectorFormFactor({ v1: coords2, v2: coords3 })); vectorFormFactor.addAssign(LTC_EdgeVectorFormFactor({ v1: coords3, v2: coords0 })); result.assign(vec3(LTC_ClippedSphereFormFactor({ f: vectorFormFactor }))); }); return result; }).setLayout({ name: "LTC_Evaluate", type: "vec3", inputs: [ { name: "N", type: "vec3" }, { name: "V", type: "vec3" }, { name: "P", type: "vec3" }, { name: "mInv", type: "mat3" }, { name: "p0", type: "vec3" }, { name: "p1", type: "vec3" }, { name: "p2", type: "vec3" }, { name: "p3", type: "vec3" } ] }); var bC = 1 / 6; var w0 = (a2) => mul(bC, mul(a2, mul(a2, a2.negate().add(3)).sub(3)).add(1)); var w1 = (a2) => mul(bC, mul(a2, mul(a2, mul(3, a2).sub(6))).add(4)); var w2 = (a2) => mul(bC, mul(a2, mul(a2, mul(-3, a2).add(3)).add(3)).add(1)); var w3 = (a2) => mul(bC, pow(a2, 3)); var g0 = (a2) => w0(a2).add(w1(a2)); var g1 = (a2) => w2(a2).add(w3(a2)); var h0 = (a2) => add4(-1, w1(a2).div(w0(a2).add(w1(a2)))); var h1 = (a2) => add4(1, w3(a2).div(w2(a2).add(w3(a2)))); var bicubic = (textureNode, texelSize, lod) => { const uv2 = textureNode.uvNode; const uvScaled = mul(uv2, texelSize.zw).add(0.5); const iuv = floor(uvScaled); const fuv = fract(uvScaled); const g0x = g0(fuv.x); const g1x = g1(fuv.x); const h0x = h0(fuv.x); const h1x = h1(fuv.x); const h0y = h0(fuv.y); const h1y = h1(fuv.y); const p0 = vec2(iuv.x.add(h0x), iuv.y.add(h0y)).sub(0.5).mul(texelSize.xy); const p1 = vec2(iuv.x.add(h1x), iuv.y.add(h0y)).sub(0.5).mul(texelSize.xy); const p2 = vec2(iuv.x.add(h0x), iuv.y.add(h1y)).sub(0.5).mul(texelSize.xy); const p3 = vec2(iuv.x.add(h1x), iuv.y.add(h1y)).sub(0.5).mul(texelSize.xy); const a2 = g0(fuv.y).mul(add4(g0x.mul(textureNode.uv(p0).level(lod)), g1x.mul(textureNode.uv(p1).level(lod)))); const b = g1(fuv.y).mul(add4(g0x.mul(textureNode.uv(p2).level(lod)), g1x.mul(textureNode.uv(p3).level(lod)))); return a2.add(b); }; var textureBicubic = /* @__PURE__ */ Fn(([textureNode, lodNode = float(3)]) => { const fLodSize = vec2(textureNode.size(int(lodNode))); const cLodSize = vec2(textureNode.size(int(lodNode.add(1)))); const fLodSizeInv = div(1, fLodSize); const cLodSizeInv = div(1, cLodSize); const fSample = bicubic(textureNode, vec4(fLodSizeInv, fLodSize), floor(lodNode)); const cSample = bicubic(textureNode, vec4(cLodSizeInv, cLodSize), ceil(lodNode)); return fract(lodNode).mix(fSample, cSample); }); var getVolumeTransmissionRay = /* @__PURE__ */ Fn(([n, v, thickness2, ior2, modelMatrix]) => { const refractionVector = vec3(refract(v.negate(), normalize2(n), div(1, ior2))); const modelScale2 = vec3( length(modelMatrix[0].xyz), length(modelMatrix[1].xyz), length(modelMatrix[2].xyz) ); return normalize2(refractionVector).mul(thickness2.mul(modelScale2)); }).setLayout({ name: "getVolumeTransmissionRay", type: "vec3", inputs: [ { name: "n", type: "vec3" }, { name: "v", type: "vec3" }, { name: "thickness", type: "float" }, { name: "ior", type: "float" }, { name: "modelMatrix", type: "mat4" } ] }); var applyIorToRoughness = /* @__PURE__ */ Fn(([roughness2, ior2]) => { return roughness2.mul(clamp2(ior2.mul(2).sub(2), 0, 1)); }).setLayout({ name: "applyIorToRoughness", type: "float", inputs: [ { name: "roughness", type: "float" }, { name: "ior", type: "float" } ] }); var viewportBackSideTexture = /* @__PURE__ */ viewportMipTexture(); var viewportFrontSideTexture = /* @__PURE__ */ viewportMipTexture(); var getTransmissionSample = /* @__PURE__ */ Fn(([fragCoord, roughness2, ior2], { material }) => { const vTexture = material.side == BackSide2 ? viewportBackSideTexture : viewportFrontSideTexture; const transmissionSample = vTexture.uv(fragCoord); const lod = log2(screenSize.x).mul(applyIorToRoughness(roughness2, ior2)); return textureBicubic(transmissionSample, lod); }); var volumeAttenuation = /* @__PURE__ */ Fn(([transmissionDistance, attenuationColor2, attenuationDistance2]) => { If(attenuationDistance2.notEqual(0), () => { const attenuationCoefficient = log(attenuationColor2).negate().div(attenuationDistance2); const transmittance = exp(attenuationCoefficient.negate().mul(transmissionDistance)); return transmittance; }); return vec3(1); }).setLayout({ name: "volumeAttenuation", type: "vec3", inputs: [ { name: "transmissionDistance", type: "float" }, { name: "attenuationColor", type: "vec3" }, { name: "attenuationDistance", type: "float" } ] }); var getIBLVolumeRefraction = /* @__PURE__ */ Fn(([n, v, roughness2, diffuseColor2, specularColor2, specularF902, position, modelMatrix, viewMatrix, projMatrix, ior2, thickness2, attenuationColor2, attenuationDistance2, dispersion2]) => { let transmittedLight, transmittance; if (dispersion2) { transmittedLight = vec4().toVar(); transmittance = vec3().toVar(); const halfSpread = ior2.sub(1).mul(dispersion2.mul(0.025)); const iors = vec3(ior2.sub(halfSpread), ior2, ior2.add(halfSpread)); Loop({ start: 0, end: 3 }, ({ i }) => { const ior3 = iors.element(i); const transmissionRay = getVolumeTransmissionRay(n, v, thickness2, ior3, modelMatrix); const refractedRayExit = position.add(transmissionRay); const ndcPos = projMatrix.mul(viewMatrix.mul(vec4(refractedRayExit, 1))); const refractionCoords = vec2(ndcPos.xy.div(ndcPos.w)).toVar(); refractionCoords.addAssign(1); refractionCoords.divAssign(2); refractionCoords.assign(vec2(refractionCoords.x, refractionCoords.y.oneMinus())); const transmissionSample = getTransmissionSample(refractionCoords, roughness2, ior3); transmittedLight.element(i).assign(transmissionSample.element(i)); transmittedLight.a.addAssign(transmissionSample.a); transmittance.element(i).assign(diffuseColor2.element(i).mul(volumeAttenuation(length(transmissionRay), attenuationColor2, attenuationDistance2).element(i))); }); transmittedLight.a.divAssign(3); } else { const transmissionRay = getVolumeTransmissionRay(n, v, thickness2, ior2, modelMatrix); const refractedRayExit = position.add(transmissionRay); const ndcPos = projMatrix.mul(viewMatrix.mul(vec4(refractedRayExit, 1))); const refractionCoords = vec2(ndcPos.xy.div(ndcPos.w)).toVar(); refractionCoords.addAssign(1); refractionCoords.divAssign(2); refractionCoords.assign(vec2(refractionCoords.x, refractionCoords.y.oneMinus())); transmittedLight = getTransmissionSample(refractionCoords, roughness2, ior2); transmittance = diffuseColor2.mul(volumeAttenuation(length(transmissionRay), attenuationColor2, attenuationDistance2)); } const attenuatedColor = transmittance.rgb.mul(transmittedLight.rgb); const dotNV = n.dot(v).clamp(); const F = vec3(EnvironmentBRDF({ // n, v, specularColor, specularF90, roughness dotNV, specularColor: specularColor2, specularF90: specularF902, roughness: roughness2 })); const transmittanceFactor = transmittance.r.add(transmittance.g, transmittance.b).div(3); return vec4(F.oneMinus().mul(attenuatedColor), transmittedLight.a.oneMinus().mul(transmittanceFactor).oneMinus()); }); var XYZ_TO_REC709 = /* @__PURE__ */ mat3( 3.2404542, -0.969266, 0.0556434, -1.5371385, 1.8760108, -0.2040259, -0.4985314, 0.041556, 1.0572252 ); var Fresnel0ToIor = (fresnel0) => { const sqrtF0 = fresnel0.sqrt(); return vec3(1).add(sqrtF0).div(vec3(1).sub(sqrtF0)); }; var IorToFresnel0 = (transmittedIor, incidentIor) => { return transmittedIor.sub(incidentIor).div(transmittedIor.add(incidentIor)).pow2(); }; var evalSensitivity = (OPD, shift) => { const phase = OPD.mul(2 * Math.PI * 1e-9); const val = vec3(54856e-17, 44201e-17, 52481e-17); const pos = vec3(1681e3, 1795300, 2208400); const VAR = vec3(43278e5, 93046e5, 66121e5); const x2 = float(9747e-17 * Math.sqrt(2 * Math.PI * 45282e5)).mul(phase.mul(2239900).add(shift.x).cos()).mul(phase.pow2().mul(-45282e5).exp()); let xyz = val.mul(VAR.mul(2 * Math.PI).sqrt()).mul(pos.mul(phase).add(shift).cos()).mul(phase.pow2().negate().mul(VAR).exp()); xyz = vec3(xyz.x.add(x2), xyz.y, xyz.z).div(10685e-11); const rgb2 = XYZ_TO_REC709.mul(xyz); return rgb2; }; var evalIridescence = /* @__PURE__ */ Fn(({ outsideIOR, eta2, cosTheta1, thinFilmThickness, baseF0 }) => { const iridescenceIOR2 = mix(outsideIOR, eta2, smoothstep2(0, 0.03, thinFilmThickness)); const sinTheta2Sq = outsideIOR.div(iridescenceIOR2).pow2().mul(cosTheta1.pow2().oneMinus()); const cosTheta2Sq = sinTheta2Sq.oneMinus(); If(cosTheta2Sq.lessThan(0), () => { return vec3(1); }); const cosTheta2 = cosTheta2Sq.sqrt(); const R0 = IorToFresnel0(iridescenceIOR2, outsideIOR); const R12 = F_Schlick({ f0: R0, f90: 1, dotVH: cosTheta1 }); const T121 = R12.oneMinus(); const phi12 = iridescenceIOR2.lessThan(outsideIOR).select(Math.PI, 0); const phi21 = float(Math.PI).sub(phi12); const baseIOR = Fresnel0ToIor(baseF0.clamp(0, 0.9999)); const R1 = IorToFresnel0(baseIOR, iridescenceIOR2.toVec3()); const R23 = F_Schlick({ f0: R1, f90: 1, dotVH: cosTheta2 }); const phi23 = vec3( baseIOR.x.lessThan(iridescenceIOR2).select(Math.PI, 0), baseIOR.y.lessThan(iridescenceIOR2).select(Math.PI, 0), baseIOR.z.lessThan(iridescenceIOR2).select(Math.PI, 0) ); const OPD = iridescenceIOR2.mul(thinFilmThickness, cosTheta2, 2); const phi = vec3(phi21).add(phi23); const R123 = R12.mul(R23).clamp(1e-5, 0.9999); const r123 = R123.sqrt(); const Rs = T121.pow2().mul(R23).div(vec3(1).sub(R123)); const C0 = R12.add(Rs); const I = C0.toVar(); const Cm = Rs.sub(T121).toVar(); Loop({ start: 1, end: 2, condition: "<=", name: "m" }, ({ m: m2 }) => { Cm.mulAssign(r123); const Sm = evalSensitivity(float(m2).mul(OPD), float(m2).mul(phi)).mul(2); I.addAssign(Cm.mul(Sm)); }); return I.max(vec3(0)); }).setLayout({ name: "evalIridescence", type: "vec3", inputs: [ { name: "outsideIOR", type: "float" }, { name: "eta2", type: "float" }, { name: "cosTheta1", type: "float" }, { name: "thinFilmThickness", type: "float" }, { name: "baseF0", type: "vec3" } ] }); var IBLSheenBRDF = /* @__PURE__ */ Fn(({ normal: normal2, viewDir, roughness: roughness2 }) => { const dotNV = normal2.dot(viewDir).saturate(); const r2 = roughness2.pow2(); const a2 = select( roughness2.lessThan(0.25), float(-339.2).mul(r2).add(float(161.4).mul(roughness2)).sub(25.9), float(-8.48).mul(r2).add(float(14.3).mul(roughness2)).sub(9.95) ); const b = select( roughness2.lessThan(0.25), float(44).mul(r2).sub(float(23.7).mul(roughness2)).add(3.26), float(1.97).mul(r2).sub(float(3.27).mul(roughness2)).add(0.72) ); const DG = select(roughness2.lessThan(0.25), 0, float(0.1).mul(roughness2).sub(0.025)).add(a2.mul(dotNV).add(b).exp()); return DG.mul(1 / Math.PI).saturate(); }); var clearcoatF0 = vec3(0.04); var clearcoatF90 = float(1); var PhysicalLightingModel = class extends LightingModel { constructor(clearcoat2 = false, sheen2 = false, iridescence2 = false, anisotropy2 = false, transmission2 = false, dispersion2 = false) { super(); this.clearcoat = clearcoat2; this.sheen = sheen2; this.iridescence = iridescence2; this.anisotropy = anisotropy2; this.transmission = transmission2; this.dispersion = dispersion2; this.clearcoatRadiance = null; this.clearcoatSpecularDirect = null; this.clearcoatSpecularIndirect = null; this.sheenSpecularDirect = null; this.sheenSpecularIndirect = null; this.iridescenceFresnel = null; this.iridescenceF0 = null; } start(context2) { if (this.clearcoat === true) { this.clearcoatRadiance = vec3().toVar("clearcoatRadiance"); this.clearcoatSpecularDirect = vec3().toVar("clearcoatSpecularDirect"); this.clearcoatSpecularIndirect = vec3().toVar("clearcoatSpecularIndirect"); } if (this.sheen === true) { this.sheenSpecularDirect = vec3().toVar("sheenSpecularDirect"); this.sheenSpecularIndirect = vec3().toVar("sheenSpecularIndirect"); } if (this.iridescence === true) { const dotNVi = transformedNormalView.dot(positionViewDirection).clamp(); this.iridescenceFresnel = evalIridescence({ outsideIOR: float(1), eta2: iridescenceIOR, cosTheta1: dotNVi, thinFilmThickness: iridescenceThickness, baseF0: specularColor }); this.iridescenceF0 = Schlick_to_F0({ f: this.iridescenceFresnel, f90: 1, dotVH: dotNVi }); } if (this.transmission === true) { const position = positionWorld; const v = cameraPosition.sub(positionWorld).normalize(); const n = transformedNormalWorld; context2.backdrop = getIBLVolumeRefraction( n, v, roughness, diffuseColor, specularColor, specularF90, // specularF90 position, // positionWorld modelWorldMatrix, // modelMatrix cameraViewMatrix, // viewMatrix cameraProjectionMatrix, // projMatrix ior, thickness, attenuationColor, attenuationDistance, this.dispersion ? dispersion : null ); context2.backdropAlpha = transmission; diffuseColor.a.mulAssign(mix(1, context2.backdrop.a, transmission)); } } // Fdez-Agüera's "Multiple-Scattering Microfacet Model for Real-Time Image Based Lighting" // Approximates multiscattering in order to preserve energy. // http://www.jcgt.org/published/0008/01/03/ computeMultiscattering(singleScatter, multiScatter, specularF902) { const dotNV = transformedNormalView.dot(positionViewDirection).clamp(); const fab = DFGApprox({ roughness, dotNV }); const Fr = this.iridescenceF0 ? iridescence.mix(specularColor, this.iridescenceF0) : specularColor; const FssEss = Fr.mul(fab.x).add(specularF902.mul(fab.y)); const Ess = fab.x.add(fab.y); const Ems = Ess.oneMinus(); const Favg = specularColor.add(specularColor.oneMinus().mul(0.047619)); const Fms = FssEss.mul(Favg).div(Ems.mul(Favg).oneMinus()); singleScatter.addAssign(FssEss); multiScatter.addAssign(Fms.mul(Ems)); } direct({ lightDirection, lightColor, reflectedLight }) { const dotNL = transformedNormalView.dot(lightDirection).clamp(); const irradiance = dotNL.mul(lightColor); if (this.sheen === true) { this.sheenSpecularDirect.addAssign(irradiance.mul(BRDF_Sheen({ lightDirection }))); } if (this.clearcoat === true) { const dotNLcc = transformedClearcoatNormalView.dot(lightDirection).clamp(); const ccIrradiance = dotNLcc.mul(lightColor); this.clearcoatSpecularDirect.addAssign(ccIrradiance.mul(BRDF_GGX({ lightDirection, f0: clearcoatF0, f90: clearcoatF90, roughness: clearcoatRoughness, normalView: transformedClearcoatNormalView }))); } reflectedLight.directDiffuse.addAssign(irradiance.mul(BRDF_Lambert({ diffuseColor: diffuseColor.rgb }))); reflectedLight.directSpecular.addAssign(irradiance.mul(BRDF_GGX({ lightDirection, f0: specularColor, f90: 1, roughness, iridescence: this.iridescence, f: this.iridescenceFresnel, USE_IRIDESCENCE: this.iridescence, USE_ANISOTROPY: this.anisotropy }))); } directRectArea({ lightColor, lightPosition: lightPosition2, halfWidth, halfHeight, reflectedLight, ltc_1, ltc_2 }) { const p0 = lightPosition2.add(halfWidth).sub(halfHeight); const p1 = lightPosition2.sub(halfWidth).sub(halfHeight); const p2 = lightPosition2.sub(halfWidth).add(halfHeight); const p3 = lightPosition2.add(halfWidth).add(halfHeight); const N = transformedNormalView; const V = positionViewDirection; const P = positionView.toVar(); const uv2 = LTC_Uv({ N, V, roughness }); const t1 = ltc_1.uv(uv2).toVar(); const t2 = ltc_2.uv(uv2).toVar(); const mInv = mat3( vec3(t1.x, 0, t1.y), vec3(0, 1, 0), vec3(t1.z, 0, t1.w) ).toVar(); const fresnel = specularColor.mul(t2.x).add(specularColor.oneMinus().mul(t2.y)).toVar(); reflectedLight.directSpecular.addAssign(lightColor.mul(fresnel).mul(LTC_Evaluate({ N, V, P, mInv, p0, p1, p2, p3 }))); reflectedLight.directDiffuse.addAssign(lightColor.mul(diffuseColor).mul(LTC_Evaluate({ N, V, P, mInv: mat3(1, 0, 0, 0, 1, 0, 0, 0, 1), p0, p1, p2, p3 }))); } indirect(context2, stack2, builder) { this.indirectDiffuse(context2, stack2, builder); this.indirectSpecular(context2, stack2, builder); this.ambientOcclusion(context2, stack2, builder); } indirectDiffuse({ irradiance, reflectedLight }) { reflectedLight.indirectDiffuse.addAssign(irradiance.mul(BRDF_Lambert({ diffuseColor }))); } indirectSpecular({ radiance, iblIrradiance, reflectedLight }) { if (this.sheen === true) { this.sheenSpecularIndirect.addAssign(iblIrradiance.mul( sheen, IBLSheenBRDF({ normal: transformedNormalView, viewDir: positionViewDirection, roughness: sheenRoughness }) )); } if (this.clearcoat === true) { const dotNVcc = transformedClearcoatNormalView.dot(positionViewDirection).clamp(); const clearcoatEnv = EnvironmentBRDF({ dotNV: dotNVcc, specularColor: clearcoatF0, specularF90: clearcoatF90, roughness: clearcoatRoughness }); this.clearcoatSpecularIndirect.addAssign(this.clearcoatRadiance.mul(clearcoatEnv)); } const singleScattering = vec3().toVar("singleScattering"); const multiScattering = vec3().toVar("multiScattering"); const cosineWeightedIrradiance = iblIrradiance.mul(1 / Math.PI); this.computeMultiscattering(singleScattering, multiScattering, specularF90); const totalScattering = singleScattering.add(multiScattering); const diffuse = diffuseColor.mul(totalScattering.r.max(totalScattering.g).max(totalScattering.b).oneMinus()); reflectedLight.indirectSpecular.addAssign(radiance.mul(singleScattering)); reflectedLight.indirectSpecular.addAssign(multiScattering.mul(cosineWeightedIrradiance)); reflectedLight.indirectDiffuse.addAssign(diffuse.mul(cosineWeightedIrradiance)); } ambientOcclusion({ ambientOcclusion, reflectedLight }) { const dotNV = transformedNormalView.dot(positionViewDirection).clamp(); const aoNV = dotNV.add(ambientOcclusion); const aoExp = roughness.mul(-16).oneMinus().negate().exp2(); const aoNode = ambientOcclusion.sub(aoNV.pow(aoExp).oneMinus()).clamp(); if (this.clearcoat === true) { this.clearcoatSpecularIndirect.mulAssign(ambientOcclusion); } if (this.sheen === true) { this.sheenSpecularIndirect.mulAssign(ambientOcclusion); } reflectedLight.indirectDiffuse.mulAssign(ambientOcclusion); reflectedLight.indirectSpecular.mulAssign(aoNode); } finish(context2) { const { outgoingLight } = context2; if (this.clearcoat === true) { const dotNVcc = transformedClearcoatNormalView.dot(positionViewDirection).clamp(); const Fcc = F_Schlick({ dotVH: dotNVcc, f0: clearcoatF0, f90: clearcoatF90 }); const clearcoatLight = outgoingLight.mul(clearcoat.mul(Fcc).oneMinus()).add(this.clearcoatSpecularDirect.add(this.clearcoatSpecularIndirect).mul(clearcoat)); outgoingLight.assign(clearcoatLight); } if (this.sheen === true) { const sheenEnergyComp = sheen.r.max(sheen.g).max(sheen.b).mul(0.157).oneMinus(); const sheenLight = outgoingLight.mul(sheenEnergyComp).add(this.sheenSpecularDirect, this.sheenSpecularIndirect); outgoingLight.assign(sheenLight); } } }; var cubeUV_r0 = /* @__PURE__ */ float(1); var cubeUV_m0 = /* @__PURE__ */ float(-2); var cubeUV_r1 = /* @__PURE__ */ float(0.8); var cubeUV_m1 = /* @__PURE__ */ float(-1); var cubeUV_r4 = /* @__PURE__ */ float(0.4); var cubeUV_m4 = /* @__PURE__ */ float(2); var cubeUV_r5 = /* @__PURE__ */ float(0.305); var cubeUV_m5 = /* @__PURE__ */ float(3); var cubeUV_r6 = /* @__PURE__ */ float(0.21); var cubeUV_m6 = /* @__PURE__ */ float(4); var cubeUV_minMipLevel = /* @__PURE__ */ float(4); var cubeUV_minTileSize = /* @__PURE__ */ float(16); var getFace = /* @__PURE__ */ Fn(([direction2]) => { const absDirection = vec3(abs(direction2)).toVar(); const face = float(-1).toVar(); If(absDirection.x.greaterThan(absDirection.z), () => { If(absDirection.x.greaterThan(absDirection.y), () => { face.assign(select(direction2.x.greaterThan(0), 0, 3)); }).Else(() => { face.assign(select(direction2.y.greaterThan(0), 1, 4)); }); }).Else(() => { If(absDirection.z.greaterThan(absDirection.y), () => { face.assign(select(direction2.z.greaterThan(0), 2, 5)); }).Else(() => { face.assign(select(direction2.y.greaterThan(0), 1, 4)); }); }); return face; }).setLayout({ name: "getFace", type: "float", inputs: [ { name: "direction", type: "vec3" } ] }); var getUV = /* @__PURE__ */ Fn(([direction2, face]) => { const uv2 = vec2().toVar(); If(face.equal(0), () => { uv2.assign(vec2(direction2.z, direction2.y).div(abs(direction2.x))); }).ElseIf(face.equal(1), () => { uv2.assign(vec2(direction2.x.negate(), direction2.z.negate()).div(abs(direction2.y))); }).ElseIf(face.equal(2), () => { uv2.assign(vec2(direction2.x.negate(), direction2.y).div(abs(direction2.z))); }).ElseIf(face.equal(3), () => { uv2.assign(vec2(direction2.z.negate(), direction2.y).div(abs(direction2.x))); }).ElseIf(face.equal(4), () => { uv2.assign(vec2(direction2.x.negate(), direction2.z).div(abs(direction2.y))); }).Else(() => { uv2.assign(vec2(direction2.x, direction2.y).div(abs(direction2.z))); }); return mul(0.5, uv2.add(1)); }).setLayout({ name: "getUV", type: "vec2", inputs: [ { name: "direction", type: "vec3" }, { name: "face", type: "float" } ] }); var roughnessToMip = /* @__PURE__ */ Fn(([roughness2]) => { const mip = float(0).toVar(); If(roughness2.greaterThanEqual(cubeUV_r1), () => { mip.assign(cubeUV_r0.sub(roughness2).mul(cubeUV_m1.sub(cubeUV_m0)).div(cubeUV_r0.sub(cubeUV_r1)).add(cubeUV_m0)); }).ElseIf(roughness2.greaterThanEqual(cubeUV_r4), () => { mip.assign(cubeUV_r1.sub(roughness2).mul(cubeUV_m4.sub(cubeUV_m1)).div(cubeUV_r1.sub(cubeUV_r4)).add(cubeUV_m1)); }).ElseIf(roughness2.greaterThanEqual(cubeUV_r5), () => { mip.assign(cubeUV_r4.sub(roughness2).mul(cubeUV_m5.sub(cubeUV_m4)).div(cubeUV_r4.sub(cubeUV_r5)).add(cubeUV_m4)); }).ElseIf(roughness2.greaterThanEqual(cubeUV_r6), () => { mip.assign(cubeUV_r5.sub(roughness2).mul(cubeUV_m6.sub(cubeUV_m5)).div(cubeUV_r5.sub(cubeUV_r6)).add(cubeUV_m5)); }).Else(() => { mip.assign(float(-2).mul(log2(mul(1.16, roughness2)))); }); return mip; }).setLayout({ name: "roughnessToMip", type: "float", inputs: [ { name: "roughness", type: "float" } ] }); var getDirection = /* @__PURE__ */ Fn(([uv_immutable, face]) => { const uv2 = uv_immutable.toVar(); uv2.assign(mul(2, uv2).sub(1)); const direction2 = vec3(uv2, 1).toVar(); If(face.equal(0), () => { direction2.assign(direction2.zyx); }).ElseIf(face.equal(1), () => { direction2.assign(direction2.xzy); direction2.xz.mulAssign(-1); }).ElseIf(face.equal(2), () => { direction2.x.mulAssign(-1); }).ElseIf(face.equal(3), () => { direction2.assign(direction2.zyx); direction2.xz.mulAssign(-1); }).ElseIf(face.equal(4), () => { direction2.assign(direction2.xzy); direction2.xy.mulAssign(-1); }).ElseIf(face.equal(5), () => { direction2.z.mulAssign(-1); }); return direction2; }).setLayout({ name: "getDirection", type: "vec3", inputs: [ { name: "uv", type: "vec2" }, { name: "face", type: "float" } ] }); var textureCubeUV = /* @__PURE__ */ Fn(([envMap, sampleDir_immutable, roughness_immutable, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP]) => { const roughness2 = float(roughness_immutable); const sampleDir = vec3(sampleDir_immutable); const mip = clamp2(roughnessToMip(roughness2), cubeUV_m0, CUBEUV_MAX_MIP); const mipF = fract(mip); const mipInt = floor(mip); const color0 = vec3(bilinearCubeUV(envMap, sampleDir, mipInt, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP)).toVar(); If(mipF.notEqual(0), () => { const color1 = vec3(bilinearCubeUV(envMap, sampleDir, mipInt.add(1), CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP)).toVar(); color0.assign(mix(color0, color1, mipF)); }); return color0; }); var bilinearCubeUV = /* @__PURE__ */ Fn(([envMap, direction_immutable, mipInt_immutable, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP]) => { const mipInt = float(mipInt_immutable).toVar(); const direction2 = vec3(direction_immutable); const face = float(getFace(direction2)).toVar(); const filterInt = float(max$1(cubeUV_minMipLevel.sub(mipInt), 0)).toVar(); mipInt.assign(max$1(mipInt, cubeUV_minMipLevel)); const faceSize = float(exp2(mipInt)).toVar(); const uv2 = vec2(getUV(direction2, face).mul(faceSize.sub(2)).add(1)).toVar(); If(face.greaterThan(2), () => { uv2.y.addAssign(faceSize); face.subAssign(3); }); uv2.x.addAssign(face.mul(faceSize)); uv2.x.addAssign(filterInt.mul(mul(3, cubeUV_minTileSize))); uv2.y.addAssign(mul(4, exp2(CUBEUV_MAX_MIP).sub(faceSize))); uv2.x.mulAssign(CUBEUV_TEXEL_WIDTH); uv2.y.mulAssign(CUBEUV_TEXEL_HEIGHT); return envMap.uv(uv2).grad(vec2(), vec2()); }); var getSample = /* @__PURE__ */ Fn(({ envMap, mipInt, outputDirection: outputDirection2, theta, axis, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }) => { const cosTheta = cos(theta); const sampleDirection = outputDirection2.mul(cosTheta).add(axis.cross(outputDirection2).mul(sin(theta))).add(axis.mul(axis.dot(outputDirection2).mul(cosTheta.oneMinus()))); return bilinearCubeUV(envMap, sampleDirection, mipInt, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP); }); var blur = /* @__PURE__ */ Fn(({ n, latitudinal, poleAxis, outputDirection: outputDirection2, weights, samples, dTheta, mipInt, envMap, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }) => { const axis = vec3(select(latitudinal, poleAxis, cross(poleAxis, outputDirection2))).toVar(); If(all(axis.equals(vec3(0))), () => { axis.assign(vec3(outputDirection2.z, 0, outputDirection2.x.negate())); }); axis.assign(normalize2(axis)); const gl_FragColor = vec3().toVar(); gl_FragColor.addAssign(weights.element(int(0)).mul(getSample({ theta: 0, axis, outputDirection: outputDirection2, mipInt, envMap, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }))); Loop({ start: int(1), end: n }, ({ i }) => { If(i.greaterThanEqual(samples), () => { Break(); }); const theta = float(dTheta.mul(float(i))).toVar(); gl_FragColor.addAssign(weights.element(i).mul(getSample({ theta: theta.mul(-1), axis, outputDirection: outputDirection2, mipInt, envMap, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }))); gl_FragColor.addAssign(weights.element(i).mul(getSample({ theta, axis, outputDirection: outputDirection2, mipInt, envMap, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }))); }); return vec4(gl_FragColor, 1); }); var _generator = null; var _cache2 = /* @__PURE__ */ new WeakMap(); function _generateCubeUVSize(imageHeight) { const maxMip = Math.log2(imageHeight) - 2; const texelHeight = 1 / imageHeight; const texelWidth = 1 / (3 * Math.max(Math.pow(2, maxMip), 7 * 16)); return { texelWidth, texelHeight, maxMip }; } function _getPMREMFromTexture(texture2) { let cacheTexture = _cache2.get(texture2); const pmremVersion = cacheTexture !== void 0 ? cacheTexture.pmremVersion : -1; if (pmremVersion !== texture2.pmremVersion) { const image = texture2.image; if (texture2.isCubeTexture) { if (isCubeMapReady(image)) { cacheTexture = _generator.fromCubemap(texture2, cacheTexture); } else { return null; } } else { if (isEquirectangularMapReady(image)) { cacheTexture = _generator.fromEquirectangular(texture2, cacheTexture); } else { return null; } } cacheTexture.pmremVersion = texture2.pmremVersion; _cache2.set(texture2, cacheTexture); } return cacheTexture.texture; } var PMREMNode = class extends TempNode { static get type() { return "PMREMNode"; } constructor(value, uvNode = null, levelNode = null) { super("vec3"); this._value = value; this._pmrem = null; this.uvNode = uvNode; this.levelNode = levelNode; this._generator = null; const defaultTexture = new Texture2(); defaultTexture.isRenderTargetTexture = true; this._texture = texture(defaultTexture); this._width = uniform(0); this._height = uniform(0); this._maxMip = uniform(0); this.updateBeforeType = NodeUpdateType.RENDER; } set value(value) { this._value = value; this._pmrem = null; } get value() { return this._value; } updateFromTexture(texture2) { const cubeUVSize = _generateCubeUVSize(texture2.image.height); this._texture.value = texture2; this._width.value = cubeUVSize.texelWidth; this._height.value = cubeUVSize.texelHeight; this._maxMip.value = cubeUVSize.maxMip; } updateBefore() { let pmrem = this._pmrem; const pmremVersion = pmrem ? pmrem.pmremVersion : -1; const texture2 = this._value; if (pmremVersion !== texture2.pmremVersion) { if (texture2.isPMREMTexture === true) { pmrem = texture2; } else { pmrem = _getPMREMFromTexture(texture2); } if (pmrem !== null) { this._pmrem = pmrem; this.updateFromTexture(pmrem); } } } setup(builder) { if (_generator === null) { _generator = builder.createPMREMGenerator(); } this.updateBefore(builder); let uvNode = this.uvNode; if (uvNode === null && builder.context.getUV) { uvNode = builder.context.getUV(this); } const texture2 = this.value; if (builder.renderer.coordinateSystem === WebGLCoordinateSystem2 && texture2.isPMREMTexture !== true && texture2.isRenderTargetTexture === true) { uvNode = vec3(uvNode.x.negate(), uvNode.yz); } let levelNode = this.levelNode; if (levelNode === null && builder.context.getTextureLevel) { levelNode = builder.context.getTextureLevel(this); } return textureCubeUV(this._texture, uvNode, levelNode, this._width, this._height, this._maxMip); } }; function isCubeMapReady(image) { if (image === null || image === void 0) return false; let count = 0; const length2 = 6; for (let i = 0; i < length2; i++) { if (image[i] !== void 0) count++; } return count === length2; } function isEquirectangularMapReady(image) { if (image === null || image === void 0) return false; return image.height > 0; } var pmremTexture = /* @__PURE__ */ nodeProxy(PMREMNode); var _envNodeCache = /* @__PURE__ */ new WeakMap(); var EnvironmentNode = class extends LightingNode { static get type() { return "EnvironmentNode"; } constructor(envNode = null) { super(); this.envNode = envNode; } setup(builder) { const { material } = builder; let envNode = this.envNode; if (envNode.isTextureNode || envNode.isMaterialReferenceNode) { const value = envNode.isTextureNode ? envNode.value : material[envNode.property]; let cacheEnvNode = _envNodeCache.get(value); if (cacheEnvNode === void 0) { cacheEnvNode = pmremTexture(value); _envNodeCache.set(value, cacheEnvNode); } envNode = cacheEnvNode; } const envMap = material.envMap; const intensity = envMap ? reference("envMapIntensity", "float", builder.material) : reference("environmentIntensity", "float", builder.scene); const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0; const radianceNormalView = useAnisotropy ? transformedBentNormalView : transformedNormalView; const radiance = envNode.context(createRadianceContext(roughness, radianceNormalView)).mul(intensity); const irradiance = envNode.context(createIrradianceContext(transformedNormalWorld)).mul(Math.PI).mul(intensity); const isolateRadiance = cache(radiance); const isolateIrradiance = cache(irradiance); builder.context.radiance.addAssign(isolateRadiance); builder.context.iblIrradiance.addAssign(isolateIrradiance); const clearcoatRadiance = builder.context.lightingModel.clearcoatRadiance; if (clearcoatRadiance) { const clearcoatRadianceContext = envNode.context(createRadianceContext(clearcoatRoughness, transformedClearcoatNormalView)).mul(intensity); const isolateClearcoatRadiance = cache(clearcoatRadianceContext); clearcoatRadiance.addAssign(isolateClearcoatRadiance); } } }; var createRadianceContext = (roughnessNode, normalViewNode) => { let reflectVec = null; return { getUV: () => { if (reflectVec === null) { reflectVec = positionViewDirection.negate().reflect(normalViewNode); reflectVec = roughnessNode.mul(roughnessNode).mix(reflectVec, normalViewNode).normalize(); reflectVec = reflectVec.transformDirection(cameraViewMatrix); } return reflectVec; }, getTextureLevel: () => { return roughnessNode; } }; }; var createIrradianceContext = (normalWorldNode) => { return { getUV: () => { return normalWorldNode; }, getTextureLevel: () => { return float(1); } }; }; var _defaultValues$6 = /* @__PURE__ */ new MeshStandardMaterial(); var MeshStandardNodeMaterial = class extends NodeMaterial { static get type() { return "MeshStandardNodeMaterial"; } constructor(parameters) { super(); this.isMeshStandardNodeMaterial = true; this.lights = true; this.emissiveNode = null; this.metalnessNode = null; this.roughnessNode = null; this.setDefaultValues(_defaultValues$6); this.setValues(parameters); } setupEnvironment(builder) { let envNode = super.setupEnvironment(builder); if (envNode === null && builder.environmentNode) { envNode = builder.environmentNode; } return envNode ? new EnvironmentNode(envNode) : null; } setupLightingModel() { return new PhysicalLightingModel(); } setupSpecular() { const specularColorNode = mix(vec3(0.04), diffuseColor.rgb, metalness); specularColor.assign(specularColorNode); specularF90.assign(1); } setupVariants() { const metalnessNode = this.metalnessNode ? float(this.metalnessNode) : materialMetalness; metalness.assign(metalnessNode); let roughnessNode = this.roughnessNode ? float(this.roughnessNode) : materialRoughness; roughnessNode = getRoughness({ roughness: roughnessNode }); roughness.assign(roughnessNode); this.setupSpecular(); diffuseColor.assign(vec4(diffuseColor.rgb.mul(metalnessNode.oneMinus()), diffuseColor.a)); } copy(source) { this.emissiveNode = source.emissiveNode; this.metalnessNode = source.metalnessNode; this.roughnessNode = source.roughnessNode; return super.copy(source); } }; var _defaultValues$5 = /* @__PURE__ */ new MeshPhysicalMaterial(); var MeshPhysicalNodeMaterial = class extends MeshStandardNodeMaterial { static get type() { return "MeshPhysicalNodeMaterial"; } constructor(parameters) { super(); this.isMeshPhysicalNodeMaterial = true; this.clearcoatNode = null; this.clearcoatRoughnessNode = null; this.clearcoatNormalNode = null; this.sheenNode = null; this.sheenRoughnessNode = null; this.iridescenceNode = null; this.iridescenceIORNode = null; this.iridescenceThicknessNode = null; this.specularIntensityNode = null; this.specularColorNode = null; this.iorNode = null; this.transmissionNode = null; this.thicknessNode = null; this.attenuationDistanceNode = null; this.attenuationColorNode = null; this.dispersionNode = null; this.anisotropyNode = null; this.setDefaultValues(_defaultValues$5); this.setValues(parameters); } get useClearcoat() { return this.clearcoat > 0 || this.clearcoatNode !== null; } get useIridescence() { return this.iridescence > 0 || this.iridescenceNode !== null; } get useSheen() { return this.sheen > 0 || this.sheenNode !== null; } get useAnisotropy() { return this.anisotropy > 0 || this.anisotropyNode !== null; } get useTransmission() { return this.transmission > 0 || this.transmissionNode !== null; } get useDispersion() { return this.dispersion > 0 || this.dispersionNode !== null; } setupSpecular() { const iorNode = this.iorNode ? float(this.iorNode) : materialIOR; ior.assign(iorNode); specularColor.assign(mix(min$1(pow2(ior.sub(1).div(ior.add(1))).mul(materialSpecularColor), vec3(1)).mul(materialSpecularIntensity), diffuseColor.rgb, metalness)); specularF90.assign(mix(materialSpecularIntensity, 1, metalness)); } setupLightingModel() { return new PhysicalLightingModel(this.useClearcoat, this.useSheen, this.useIridescence, this.useAnisotropy, this.useTransmission, this.useDispersion); } setupVariants(builder) { super.setupVariants(builder); if (this.useClearcoat) { const clearcoatNode = this.clearcoatNode ? float(this.clearcoatNode) : materialClearcoat; const clearcoatRoughnessNode = this.clearcoatRoughnessNode ? float(this.clearcoatRoughnessNode) : materialClearcoatRoughness; clearcoat.assign(clearcoatNode); clearcoatRoughness.assign(getRoughness({ roughness: clearcoatRoughnessNode })); } if (this.useSheen) { const sheenNode = this.sheenNode ? vec3(this.sheenNode) : materialSheen; const sheenRoughnessNode = this.sheenRoughnessNode ? float(this.sheenRoughnessNode) : materialSheenRoughness; sheen.assign(sheenNode); sheenRoughness.assign(sheenRoughnessNode); } if (this.useIridescence) { const iridescenceNode = this.iridescenceNode ? float(this.iridescenceNode) : materialIridescence; const iridescenceIORNode = this.iridescenceIORNode ? float(this.iridescenceIORNode) : materialIridescenceIOR; const iridescenceThicknessNode = this.iridescenceThicknessNode ? float(this.iridescenceThicknessNode) : materialIridescenceThickness; iridescence.assign(iridescenceNode); iridescenceIOR.assign(iridescenceIORNode); iridescenceThickness.assign(iridescenceThicknessNode); } if (this.useAnisotropy) { const anisotropyV = (this.anisotropyNode ? vec2(this.anisotropyNode) : materialAnisotropy).toVar(); anisotropy.assign(anisotropyV.length()); If(anisotropy.equal(0), () => { anisotropyV.assign(vec2(1, 0)); }).Else(() => { anisotropyV.divAssign(vec2(anisotropy)); anisotropy.assign(anisotropy.saturate()); }); alphaT.assign(anisotropy.pow2().mix(roughness.pow2(), 1)); anisotropyT.assign(TBNViewMatrix[0].mul(anisotropyV.x).add(TBNViewMatrix[1].mul(anisotropyV.y))); anisotropyB.assign(TBNViewMatrix[1].mul(anisotropyV.x).sub(TBNViewMatrix[0].mul(anisotropyV.y))); } if (this.useTransmission) { const transmissionNode = this.transmissionNode ? float(this.transmissionNode) : materialTransmission; const thicknessNode = this.thicknessNode ? float(this.thicknessNode) : materialThickness; const attenuationDistanceNode = this.attenuationDistanceNode ? float(this.attenuationDistanceNode) : materialAttenuationDistance; const attenuationColorNode = this.attenuationColorNode ? vec3(this.attenuationColorNode) : materialAttenuationColor; transmission.assign(transmissionNode); thickness.assign(thicknessNode); attenuationDistance.assign(attenuationDistanceNode); attenuationColor.assign(attenuationColorNode); if (this.useDispersion) { const dispersionNode = this.dispersionNode ? float(this.dispersionNode) : materialDispersion; dispersion.assign(dispersionNode); } } } setupClearcoatNormal() { return this.clearcoatNormalNode ? vec3(this.clearcoatNormalNode) : materialClearcoatNormal; } setup(builder) { builder.context.setupClearcoatNormal = () => this.setupClearcoatNormal(builder); super.setup(builder); } copy(source) { this.clearcoatNode = source.clearcoatNode; this.clearcoatRoughnessNode = source.clearcoatRoughnessNode; this.clearcoatNormalNode = source.clearcoatNormalNode; this.sheenNode = source.sheenNode; this.sheenRoughnessNode = source.sheenRoughnessNode; this.iridescenceNode = source.iridescenceNode; this.iridescenceIORNode = source.iridescenceIORNode; this.iridescenceThicknessNode = source.iridescenceThicknessNode; this.specularIntensityNode = source.specularIntensityNode; this.specularColorNode = source.specularColorNode; this.transmissionNode = source.transmissionNode; this.thicknessNode = source.thicknessNode; this.attenuationDistanceNode = source.attenuationDistanceNode; this.attenuationColorNode = source.attenuationColorNode; this.dispersionNode = source.dispersionNode; this.anisotropyNode = source.anisotropyNode; return super.copy(source); } }; var getGradientIrradiance = /* @__PURE__ */ Fn(({ normal: normal2, lightDirection, builder }) => { const dotNL = normal2.dot(lightDirection); const coord = vec2(dotNL.mul(0.5).add(0.5), 0); if (builder.material.gradientMap) { const gradientMap = materialReference("gradientMap", "texture").context({ getUV: () => coord }); return vec3(gradientMap.r); } else { const fw = coord.fwidth().mul(0.5); return mix(vec3(0.7), vec3(1), smoothstep2(float(0.7).sub(fw.x), float(0.7).add(fw.x), coord.x)); } }); var ToonLightingModel = class extends LightingModel { direct({ lightDirection, lightColor, reflectedLight }, stack2, builder) { const irradiance = getGradientIrradiance({ normal: normalGeometry, lightDirection, builder }).mul(lightColor); reflectedLight.directDiffuse.addAssign(irradiance.mul(BRDF_Lambert({ diffuseColor: diffuseColor.rgb }))); } indirect({ ambientOcclusion, irradiance, reflectedLight }) { reflectedLight.indirectDiffuse.addAssign(irradiance.mul(BRDF_Lambert({ diffuseColor }))); reflectedLight.indirectDiffuse.mulAssign(ambientOcclusion); } }; var _defaultValues$4 = /* @__PURE__ */ new MeshToonMaterial(); var MeshToonNodeMaterial = class extends NodeMaterial { static get type() { return "MeshToonNodeMaterial"; } constructor(parameters) { super(); this.isMeshToonNodeMaterial = true; this.lights = true; this.setDefaultValues(_defaultValues$4); this.setValues(parameters); } setupLightingModel() { return new ToonLightingModel(); } }; var MatcapUVNode = class extends TempNode { static get type() { return "MatcapUVNode"; } constructor() { super("vec2"); } setup() { const x2 = vec3(positionViewDirection.z, 0, positionViewDirection.x.negate()).normalize(); const y2 = positionViewDirection.cross(x2); return vec2(x2.dot(transformedNormalView), y2.dot(transformedNormalView)).mul(0.495).add(0.5); } }; var matcapUV = /* @__PURE__ */ nodeImmutable(MatcapUVNode); var _defaultValues$3 = /* @__PURE__ */ new MeshMatcapMaterial(); var MeshMatcapNodeMaterial = class extends NodeMaterial { static get type() { return "MeshMatcapNodeMaterial"; } constructor(parameters) { super(); this.lights = false; this.isMeshMatcapNodeMaterial = true; this.setDefaultValues(_defaultValues$3); this.setValues(parameters); } setupVariants(builder) { const uv2 = matcapUV; let matcapColor; if (builder.material.matcap) { matcapColor = materialReference("matcap", "texture").context({ getUV: () => uv2 }); } else { matcapColor = vec3(mix(0.2, 0.8, uv2.y)); } diffuseColor.rgb.mulAssign(matcapColor.rgb); } }; var _defaultValues$2 = /* @__PURE__ */ new PointsMaterial(); var PointsNodeMaterial = class extends NodeMaterial { static get type() { return "PointsNodeMaterial"; } constructor(parameters) { super(); this.isPointsNodeMaterial = true; this.lights = false; this.transparent = true; this.sizeNode = null; this.setDefaultValues(_defaultValues$2); this.setValues(parameters); } copy(source) { this.sizeNode = source.sizeNode; return super.copy(source); } }; var RotateNode = class extends TempNode { static get type() { return "RotateNode"; } constructor(positionNode, rotationNode) { super(); this.positionNode = positionNode; this.rotationNode = rotationNode; } getNodeType(builder) { return this.positionNode.getNodeType(builder); } setup(builder) { const { rotationNode, positionNode } = this; const nodeType = this.getNodeType(builder); if (nodeType === "vec2") { const cosAngle = rotationNode.cos(); const sinAngle = rotationNode.sin(); const rotationMatrix = mat2( cosAngle, sinAngle, sinAngle.negate(), cosAngle ); return rotationMatrix.mul(positionNode); } else { const rotation = rotationNode; const rotationXMatrix = mat4(vec4(1, 0, 0, 0), vec4(0, cos(rotation.x), sin(rotation.x).negate(), 0), vec4(0, sin(rotation.x), cos(rotation.x), 0), vec4(0, 0, 0, 1)); const rotationYMatrix = mat4(vec4(cos(rotation.y), 0, sin(rotation.y), 0), vec4(0, 1, 0, 0), vec4(sin(rotation.y).negate(), 0, cos(rotation.y), 0), vec4(0, 0, 0, 1)); const rotationZMatrix = mat4(vec4(cos(rotation.z), sin(rotation.z).negate(), 0, 0), vec4(sin(rotation.z), cos(rotation.z), 0, 0), vec4(0, 0, 1, 0), vec4(0, 0, 0, 1)); return rotationXMatrix.mul(rotationYMatrix).mul(rotationZMatrix).mul(vec4(positionNode, 1)).xyz; } } }; var rotate = /* @__PURE__ */ nodeProxy(RotateNode); var _defaultValues$1 = /* @__PURE__ */ new SpriteMaterial(); var SpriteNodeMaterial = class extends NodeMaterial { static get type() { return "SpriteNodeMaterial"; } constructor(parameters) { super(); this.isSpriteNodeMaterial = true; this.lights = false; this._useSizeAttenuation = true; this.positionNode = null; this.rotationNode = null; this.scaleNode = null; this.setDefaultValues(_defaultValues$1); this.setValues(parameters); } setupPosition({ object, camera: camera3, context: context2 }) { const sizeAttenuation = this.sizeAttenuation; const { positionNode, rotationNode, scaleNode } = this; const vertex2 = positionLocal; let mvPosition = modelViewMatrix.mul(vec3(positionNode || 0)); let scale = vec2(modelWorldMatrix[0].xyz.length(), modelWorldMatrix[1].xyz.length()); if (scaleNode !== null) { scale = scale.mul(scaleNode); } if (!sizeAttenuation) { if (camera3.isPerspectiveCamera) { scale = scale.mul(mvPosition.z.negate()); } else { const orthoScale = float(2).div(cameraProjectionMatrix.element(1).element(1)); scale = scale.mul(orthoScale.mul(2)); } } let alignedPosition = vertex2.xy; if (object.center && object.center.isVector2 === true) { const center = reference$1("center", "vec2"); alignedPosition = alignedPosition.sub(center.sub(0.5)); } alignedPosition = alignedPosition.mul(scale); const rotation = float(rotationNode || materialRotation); const rotatedPosition = rotate(alignedPosition, rotation); mvPosition = vec4(mvPosition.xy.add(rotatedPosition), mvPosition.zw); const modelViewProjection2 = cameraProjectionMatrix.mul(mvPosition); context2.vertex = vertex2; return modelViewProjection2; } copy(source) { this.positionNode = source.positionNode; this.rotationNode = source.rotationNode; this.scaleNode = source.scaleNode; return super.copy(source); } get sizeAttenuation() { return this._useSizeAttenuation; } set sizeAttenuation(value) { if (this._useSizeAttenuation !== value) { this._useSizeAttenuation = value; this.needsUpdate = true; } } }; var ShadowMaskModel = class extends LightingModel { constructor() { super(); this.shadowNode = float(1).toVar("shadowMask"); } direct({ shadowMask }) { this.shadowNode.mulAssign(shadowMask); } finish(context2) { diffuseColor.a.mulAssign(this.shadowNode.oneMinus()); context2.outgoingLight.rgb.assign(diffuseColor.rgb); } }; var _defaultValues = /* @__PURE__ */ new ShadowMaterial(); var ShadowNodeMaterial = class extends NodeMaterial { static get type() { return "ShadowNodeMaterial"; } constructor(parameters) { super(); this.isShadowNodeMaterial = true; this.lights = true; this.setDefaultValues(_defaultValues); this.setValues(parameters); } setupLightingModel() { return new ShadowMaskModel(); } }; var normal = Fn(({ texture: texture2, uv: uv2 }) => { const epsilon = 1e-4; const ret = vec3().toVar(); If(uv2.x.lessThan(epsilon), () => { ret.assign(vec3(1, 0, 0)); }).ElseIf(uv2.y.lessThan(epsilon), () => { ret.assign(vec3(0, 1, 0)); }).ElseIf(uv2.z.lessThan(epsilon), () => { ret.assign(vec3(0, 0, 1)); }).ElseIf(uv2.x.greaterThan(1 - epsilon), () => { ret.assign(vec3(-1, 0, 0)); }).ElseIf(uv2.y.greaterThan(1 - epsilon), () => { ret.assign(vec3(0, -1, 0)); }).ElseIf(uv2.z.greaterThan(1 - epsilon), () => { ret.assign(vec3(0, 0, -1)); }).Else(() => { const step2 = 0.01; const x2 = texture2.uv(uv2.add(vec3(-step2, 0, 0))).r.sub(texture2.uv(uv2.add(vec3(step2, 0, 0))).r); const y2 = texture2.uv(uv2.add(vec3(0, -step2, 0))).r.sub(texture2.uv(uv2.add(vec3(0, step2, 0))).r); const z2 = texture2.uv(uv2.add(vec3(0, 0, -step2))).r.sub(texture2.uv(uv2.add(vec3(0, 0, step2))).r); ret.assign(vec3(x2, y2, z2)); }); return ret.normalize(); }); var Animation = class { constructor(nodes, info) { this.nodes = nodes; this.info = info; this.animationLoop = null; this.requestId = null; this._init(); } _init() { const update4 = (time, frame2) => { this.requestId = self.requestAnimationFrame(update4); if (this.info.autoReset === true) this.info.reset(); this.nodes.nodeFrame.update(); this.info.frame = this.nodes.nodeFrame.frameId; if (this.animationLoop !== null) this.animationLoop(time, frame2); }; update4(); } dispose() { self.cancelAnimationFrame(this.requestId); this.requestId = null; } setAnimationLoop(callback) { this.animationLoop = callback; } }; var ChainMap = class { constructor() { this.weakMap = /* @__PURE__ */ new WeakMap(); } get(keys) { let map = this.weakMap; for (let i = 0; i < keys.length; i++) { map = map.get(keys[i]); if (map === void 0) return void 0; } return map.get(keys[keys.length - 1]); } set(keys, value) { let map = this.weakMap; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (map.has(key) === false) map.set(key, /* @__PURE__ */ new WeakMap()); map = map.get(key); } return map.set(keys[keys.length - 1], value); } delete(keys) { let map = this.weakMap; for (let i = 0; i < keys.length; i++) { map = map.get(keys[i]); if (map === void 0) return false; } return map.delete(keys[keys.length - 1]); } }; var _plane2 = /* @__PURE__ */ new Plane2(); var ClippingContext = class { constructor() { this.version = 0; this.globalClippingCount = 0; this.localClippingCount = 0; this.localClippingEnabled = false; this.localClipIntersection = false; this.planes = []; this.parentVersion = 0; this.viewNormalMatrix = new Matrix32(); this.cacheKey = 0; } projectPlanes(source, offset) { const l = source.length; const planes = this.planes; for (let i = 0; i < l; i++) { _plane2.copy(source[i]).applyMatrix4(this.viewMatrix, this.viewNormalMatrix); const v = planes[offset + i]; const normal2 = _plane2.normal; v.x = -normal2.x; v.y = -normal2.y; v.z = -normal2.z; v.w = _plane2.constant; } } updateGlobal(renderer3, camera3) { const rendererClippingPlanes = renderer3.clippingPlanes; this.viewMatrix = camera3.matrixWorldInverse; this.viewNormalMatrix.getNormalMatrix(this.viewMatrix); let update4 = false; if (Array.isArray(rendererClippingPlanes) && rendererClippingPlanes.length !== 0) { const l = rendererClippingPlanes.length; if (l !== this.globalClippingCount) { const planes = []; for (let i = 0; i < l; i++) { planes.push(new Vector42()); } this.globalClippingCount = l; this.planes = planes; update4 = true; } this.projectPlanes(rendererClippingPlanes, 0); } else if (this.globalClippingCount !== 0) { this.globalClippingCount = 0; this.planes = []; update4 = true; } if (renderer3.localClippingEnabled !== this.localClippingEnabled) { this.localClippingEnabled = renderer3.localClippingEnabled; update4 = true; } if (update4) { this.version++; this.cacheKey = hash$1(this.globalClippingCount, this.localClippingEnabled === true ? 1 : 0); } } update(parent, material) { let update4 = false; if (this !== parent && parent.version !== this.parentVersion) { this.globalClippingCount = material.isShadowNodeMaterial ? 0 : parent.globalClippingCount; this.localClippingEnabled = parent.localClippingEnabled; this.planes = Array.from(parent.planes); this.parentVersion = parent.version; this.viewMatrix = parent.viewMatrix; this.viewNormalMatrix = parent.viewNormalMatrix; update4 = true; } if (this.localClippingEnabled) { const localClippingPlanes = material.clippingPlanes; if (Array.isArray(localClippingPlanes) && localClippingPlanes.length !== 0) { const l = localClippingPlanes.length; const planes = this.planes; const offset = this.globalClippingCount; if (update4 || l !== this.localClippingCount) { planes.length = offset + l; for (let i = 0; i < l; i++) { planes[offset + i] = new Vector42(); } this.localClippingCount = l; update4 = true; } this.projectPlanes(localClippingPlanes, offset); } else if (this.localClippingCount !== 0) { this.localClippingCount = 0; update4 = true; } if (this.localClipIntersection !== material.clipIntersection) { this.localClipIntersection = material.clipIntersection; update4 = true; } } if (update4) { this.version += parent.version; this.cacheKey = hash$1(parent.cacheKey, this.localClippingCount, this.localClipIntersection === true ? 1 : 0); } } }; var _id$7 = 0; function getKeys(obj) { const keys = Object.keys(obj); let proto = Object.getPrototypeOf(obj); while (proto) { const descriptors = Object.getOwnPropertyDescriptors(proto); for (const key in descriptors) { if (descriptors[key] !== void 0) { const descriptor = descriptors[key]; if (descriptor && typeof descriptor.get === "function") { keys.push(key); } } } proto = Object.getPrototypeOf(proto); } return keys; } var RenderObject = class { constructor(nodes, geometries, renderer3, object, material, scene3, camera3, lightsNode, renderContext) { this._nodes = nodes; this._geometries = geometries; this.id = _id$7++; this.renderer = renderer3; this.object = object; this.material = material; this.scene = scene3; this.camera = camera3; this.lightsNode = lightsNode; this.context = renderContext; this.geometry = object.geometry; this.version = material.version; this.drawRange = null; this.attributes = null; this.pipeline = null; this.vertexBuffers = null; this.drawParams = null; this.bundle = null; this.updateClipping(renderContext.clippingContext); this.clippingContextVersion = this.clippingContext.version; this.initialNodesCacheKey = this.getDynamicCacheKey(); this.initialCacheKey = this.getCacheKey(); this._nodeBuilderState = null; this._bindings = null; this._monitor = null; this.onDispose = null; this.isRenderObject = true; this.onMaterialDispose = () => { this.dispose(); }; this.material.addEventListener("dispose", this.onMaterialDispose); } updateClipping(parent) { const material = this.material; let clippingContext = this.clippingContext; if (Array.isArray(material.clippingPlanes)) { if (clippingContext === parent || !clippingContext) { clippingContext = new ClippingContext(); this.clippingContext = clippingContext; } clippingContext.update(parent, material); } else if (this.clippingContext !== parent) { this.clippingContext = parent; } } get clippingNeedsUpdate() { if (this.clippingContext.version === this.clippingContextVersion) return false; this.clippingContextVersion = this.clippingContext.version; return true; } getNodeBuilderState() { return this._nodeBuilderState || (this._nodeBuilderState = this._nodes.getForRender(this)); } getMonitor() { return this._monitor || (this._monitor = this.getNodeBuilderState().monitor); } getBindings() { return this._bindings || (this._bindings = this.getNodeBuilderState().createBindings()); } getIndex() { return this._geometries.getIndex(this); } getIndirect() { return this._geometries.getIndirect(this); } getChainArray() { return [this.object, this.material, this.context, this.lightsNode]; } getAttributes() { if (this.attributes !== null) return this.attributes; const nodeAttributes = this.getNodeBuilderState().nodeAttributes; const geometry = this.geometry; const attributes = []; const vertexBuffers = /* @__PURE__ */ new Set(); for (const nodeAttribute of nodeAttributes) { const attribute2 = nodeAttribute.node && nodeAttribute.node.attribute ? nodeAttribute.node.attribute : geometry.getAttribute(nodeAttribute.name); if (attribute2 === void 0) continue; attributes.push(attribute2); const bufferAttribute2 = attribute2.isInterleavedBufferAttribute ? attribute2.data : attribute2; vertexBuffers.add(bufferAttribute2); } this.attributes = attributes; this.vertexBuffers = Array.from(vertexBuffers.values()); return attributes; } getVertexBuffers() { if (this.vertexBuffers === null) this.getAttributes(); return this.vertexBuffers; } getDrawParameters() { const { object, material, geometry, group, drawRange } = this; const drawParams = this.drawParams || (this.drawParams = { vertexCount: 0, firstVertex: 0, instanceCount: 0, firstInstance: 0 }); const index5 = this.getIndex(); const hasIndex = index5 !== null; const instanceCount = geometry.isInstancedBufferGeometry ? geometry.instanceCount : object.count > 1 ? object.count : 1; if (instanceCount === 0) return null; drawParams.instanceCount = instanceCount; if (object.isBatchedMesh === true) return drawParams; let rangeFactor = 1; if (material.wireframe === true && !object.isPoints && !object.isLineSegments && !object.isLine && !object.isLineLoop) { rangeFactor = 2; } let firstVertex = drawRange.start * rangeFactor; let lastVertex = (drawRange.start + drawRange.count) * rangeFactor; if (group !== null) { firstVertex = Math.max(firstVertex, group.start * rangeFactor); lastVertex = Math.min(lastVertex, (group.start + group.count) * rangeFactor); } const position = geometry.attributes.position; let itemCount = Infinity; if (hasIndex) { itemCount = index5.count; } else if (position !== void 0 && position !== null) { itemCount = position.count; } firstVertex = Math.max(firstVertex, 0); lastVertex = Math.min(lastVertex, itemCount); const count = lastVertex - firstVertex; if (count < 0 || count === Infinity) return null; drawParams.vertexCount = count; drawParams.firstVertex = firstVertex; return drawParams; } getGeometryCacheKey() { const { geometry } = this; let cacheKey = ""; for (const name of Object.keys(geometry.attributes).sort()) { const attribute2 = geometry.attributes[name]; cacheKey += name + ","; if (attribute2.data) cacheKey += attribute2.data.stride + ","; if (attribute2.offset) cacheKey += attribute2.offset + ","; if (attribute2.itemSize) cacheKey += attribute2.itemSize + ","; if (attribute2.normalized) cacheKey += "n,"; } if (geometry.index) { cacheKey += "index,"; } return cacheKey; } getMaterialCacheKey() { const { object, material } = this; let cacheKey = material.customProgramCacheKey(); for (const property2 of getKeys(material)) { if (/^(is[A-Z]|_)|^(visible|version|uuid|name|opacity|userData)$/.test(property2)) continue; const value = material[property2]; let valueKey; if (value !== null) { const type = typeof value; if (type === "number") { valueKey = value !== 0 ? "1" : "0"; } else if (type === "object") { valueKey = "{"; if (value.isTexture) { valueKey += value.mapping; } valueKey += "}"; } else { valueKey = String(value); } } else { valueKey = String(value); } cacheKey += /*property + ':' +*/ valueKey + ","; } cacheKey += this.clippingContext.cacheKey + ","; if (object.geometry) { cacheKey += this.getGeometryCacheKey(); } if (object.skeleton) { cacheKey += object.skeleton.bones.length + ","; } if (object.morphTargetInfluences) { cacheKey += object.morphTargetInfluences.length + ","; } if (object.isBatchedMesh) { cacheKey += object._matricesTexture.uuid + ","; if (object._colorsTexture !== null) { cacheKey += object._colorsTexture.uuid + ","; } } if (object.count > 1) { cacheKey += object.uuid + ","; } return hashString(cacheKey); } get needsUpdate() { return ( /*this.object.static !== true &&*/ this.initialNodesCacheKey !== this.getDynamicCacheKey() || this.clippingNeedsUpdate ); } getDynamicCacheKey() { let cacheKey = this._nodes.getCacheKey(this.scene, this.lightsNode); if (this.object.receiveShadow) { cacheKey += 1; } return cacheKey; } getCacheKey() { return this.getMaterialCacheKey() + this.getDynamicCacheKey(); } dispose() { this.material.removeEventListener("dispose", this.onMaterialDispose); this.onDispose(); } }; var chainArray = []; var RenderObjects = class { constructor(renderer3, nodes, geometries, pipelines, bindings, info) { this.renderer = renderer3; this.nodes = nodes; this.geometries = geometries; this.pipelines = pipelines; this.bindings = bindings; this.info = info; this.chainMaps = {}; } get(object, material, scene3, camera3, lightsNode, renderContext, passId) { const chainMap = this.getChainMap(passId); chainArray[0] = object; chainArray[1] = material; chainArray[2] = renderContext; chainArray[3] = lightsNode; let renderObject = chainMap.get(chainArray); if (renderObject === void 0) { renderObject = this.createRenderObject(this.nodes, this.geometries, this.renderer, object, material, scene3, camera3, lightsNode, renderContext, passId); chainMap.set(chainArray, renderObject); } else { renderObject.updateClipping(renderContext.clippingContext); if (renderObject.version !== material.version || renderObject.needsUpdate) { if (renderObject.initialCacheKey !== renderObject.getCacheKey()) { renderObject.dispose(); renderObject = this.get(object, material, scene3, camera3, lightsNode, renderContext, passId); } else { renderObject.version = material.version; } } } return renderObject; } getChainMap(passId = "default") { return this.chainMaps[passId] || (this.chainMaps[passId] = new ChainMap()); } dispose() { this.chainMaps = {}; } createRenderObject(nodes, geometries, renderer3, object, material, scene3, camera3, lightsNode, renderContext, passId) { const chainMap = this.getChainMap(passId); const renderObject = new RenderObject(nodes, geometries, renderer3, object, material, scene3, camera3, lightsNode, renderContext); renderObject.onDispose = () => { this.pipelines.delete(renderObject); this.bindings.delete(renderObject); this.nodes.delete(renderObject); chainMap.delete(renderObject.getChainArray()); }; return renderObject; } }; var DataMap = class { constructor() { this.data = /* @__PURE__ */ new WeakMap(); } get(object) { let map = this.data.get(object); if (map === void 0) { map = {}; this.data.set(object, map); } return map; } delete(object) { let map; if (this.data.has(object)) { map = this.data.get(object); this.data.delete(object); } return map; } has(object) { return this.data.has(object); } dispose() { this.data = /* @__PURE__ */ new WeakMap(); } }; var AttributeType = { VERTEX: 1, INDEX: 2, STORAGE: 3, INDIRECT: 4 }; var GPU_CHUNK_BYTES = 16; var BlendColorFactor = 211; var OneMinusBlendColorFactor = 212; var Attributes = class extends DataMap { constructor(backend) { super(); this.backend = backend; } delete(attribute2) { const attributeData = super.delete(attribute2); if (attributeData !== void 0) { this.backend.destroyAttribute(attribute2); } return attributeData; } update(attribute2, type) { const data = this.get(attribute2); if (data.version === void 0) { if (type === AttributeType.VERTEX) { this.backend.createAttribute(attribute2); } else if (type === AttributeType.INDEX) { this.backend.createIndexAttribute(attribute2); } else if (type === AttributeType.STORAGE) { this.backend.createStorageAttribute(attribute2); } else if (type === AttributeType.INDIRECT) { this.backend.createIndirectStorageAttribute(attribute2); } data.version = this._getBufferAttribute(attribute2).version; } else { const bufferAttribute2 = this._getBufferAttribute(attribute2); if (data.version < bufferAttribute2.version || bufferAttribute2.usage === DynamicDrawUsage) { this.backend.updateAttribute(attribute2); data.version = bufferAttribute2.version; } } } _getBufferAttribute(attribute2) { if (attribute2.isInterleavedBufferAttribute) attribute2 = attribute2.data; return attribute2; } }; function arrayNeedsUint322(array) { for (let i = array.length - 1; i >= 0; --i) { if (array[i] >= 65535) return true; } return false; } function getWireframeVersion(geometry) { return geometry.index !== null ? geometry.index.version : geometry.attributes.position.version; } function getWireframeIndex(geometry) { const indices = []; const geometryIndex = geometry.index; const geometryPosition = geometry.attributes.position; if (geometryIndex !== null) { const array = geometryIndex.array; for (let i = 0, l = array.length; i < l; i += 3) { const a2 = array[i + 0]; const b = array[i + 1]; const c2 = array[i + 2]; indices.push(a2, b, b, c2, c2, a2); } } else { const array = geometryPosition.array; for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { const a2 = i + 0; const b = i + 1; const c2 = i + 2; indices.push(a2, b, b, c2, c2, a2); } } const attribute2 = new (arrayNeedsUint322(indices) ? Uint32BufferAttribute2 : Uint16BufferAttribute2)(indices, 1); attribute2.version = getWireframeVersion(geometry); return attribute2; } var Geometries = class extends DataMap { constructor(attributes, info) { super(); this.attributes = attributes; this.info = info; this.wireframes = /* @__PURE__ */ new WeakMap(); this.attributeCall = /* @__PURE__ */ new WeakMap(); } has(renderObject) { const geometry = renderObject.geometry; return super.has(geometry) && this.get(geometry).initialized === true; } updateForRender(renderObject) { if (this.has(renderObject) === false) this.initGeometry(renderObject); this.updateAttributes(renderObject); } initGeometry(renderObject) { const geometry = renderObject.geometry; const geometryData = this.get(geometry); geometryData.initialized = true; this.info.memory.geometries++; const onDispose = () => { this.info.memory.geometries--; const index5 = geometry.index; const geometryAttributes = renderObject.getAttributes(); if (index5 !== null) { this.attributes.delete(index5); } for (const geometryAttribute of geometryAttributes) { this.attributes.delete(geometryAttribute); } const wireframeAttribute = this.wireframes.get(geometry); if (wireframeAttribute !== void 0) { this.attributes.delete(wireframeAttribute); } geometry.removeEventListener("dispose", onDispose); }; geometry.addEventListener("dispose", onDispose); } updateAttributes(renderObject) { const attributes = renderObject.getAttributes(); for (const attribute2 of attributes) { if (attribute2.isStorageBufferAttribute || attribute2.isStorageInstancedBufferAttribute) { this.updateAttribute(attribute2, AttributeType.STORAGE); } else { this.updateAttribute(attribute2, AttributeType.VERTEX); } } const index5 = this.getIndex(renderObject); if (index5 !== null) { this.updateAttribute(index5, AttributeType.INDEX); } const indirect = renderObject.geometry.indirect; if (indirect !== null) { this.updateAttribute(indirect, AttributeType.INDIRECT); } } updateAttribute(attribute2, type) { const callId = this.info.render.calls; if (!attribute2.isInterleavedBufferAttribute) { if (this.attributeCall.get(attribute2) !== callId) { this.attributes.update(attribute2, type); this.attributeCall.set(attribute2, callId); } } else { if (this.attributeCall.get(attribute2) === void 0) { this.attributes.update(attribute2, type); this.attributeCall.set(attribute2, callId); } else if (this.attributeCall.get(attribute2.data) !== callId) { this.attributes.update(attribute2, type); this.attributeCall.set(attribute2.data, callId); this.attributeCall.set(attribute2, callId); } } } getIndirect(renderObject) { return renderObject.geometry.indirect; } getIndex(renderObject) { const { geometry, material } = renderObject; let index5 = geometry.index; if (material.wireframe === true) { const wireframes = this.wireframes; let wireframeAttribute = wireframes.get(geometry); if (wireframeAttribute === void 0) { wireframeAttribute = getWireframeIndex(geometry); wireframes.set(geometry, wireframeAttribute); } else if (wireframeAttribute.version !== getWireframeVersion(geometry)) { this.attributes.delete(wireframeAttribute); wireframeAttribute = getWireframeIndex(geometry); wireframes.set(geometry, wireframeAttribute); } index5 = wireframeAttribute; } return index5; } }; var Info = class { constructor() { this.autoReset = true; this.frame = 0; this.calls = 0; this.render = { calls: 0, frameCalls: 0, drawCalls: 0, triangles: 0, points: 0, lines: 0, timestamp: 0, previousFrameCalls: 0, timestampCalls: 0 }; this.compute = { calls: 0, frameCalls: 0, timestamp: 0, previousFrameCalls: 0, timestampCalls: 0 }; this.memory = { geometries: 0, textures: 0 }; } update(object, count, instanceCount) { this.render.drawCalls++; if (object.isMesh || object.isSprite) { this.render.triangles += instanceCount * (count / 3); } else if (object.isPoints) { this.render.points += instanceCount * count; } else if (object.isLineSegments) { this.render.lines += instanceCount * (count / 2); } else if (object.isLine) { this.render.lines += instanceCount * (count - 1); } else { console.error("THREE.WebGPUInfo: Unknown object type."); } } updateTimestamp(type, time) { if (this[type].timestampCalls === 0) { this[type].timestamp = 0; } this[type].timestamp += time; this[type].timestampCalls++; if (this[type].timestampCalls >= this[type].previousFrameCalls) { this[type].timestampCalls = 0; } } reset() { const previousRenderFrameCalls = this.render.frameCalls; this.render.previousFrameCalls = previousRenderFrameCalls; const previousComputeFrameCalls = this.compute.frameCalls; this.compute.previousFrameCalls = previousComputeFrameCalls; this.render.drawCalls = 0; this.render.frameCalls = 0; this.compute.frameCalls = 0; this.render.triangles = 0; this.render.points = 0; this.render.lines = 0; } dispose() { this.reset(); this.calls = 0; this.render.calls = 0; this.compute.calls = 0; this.render.timestamp = 0; this.compute.timestamp = 0; this.memory.geometries = 0; this.memory.textures = 0; } }; var Pipeline = class { constructor(cacheKey) { this.cacheKey = cacheKey; this.usedTimes = 0; } }; var RenderPipeline = class extends Pipeline { constructor(cacheKey, vertexProgram, fragmentProgram) { super(cacheKey); this.vertexProgram = vertexProgram; this.fragmentProgram = fragmentProgram; } }; var ComputePipeline = class extends Pipeline { constructor(cacheKey, computeProgram) { super(cacheKey); this.computeProgram = computeProgram; this.isComputePipeline = true; } }; var _id$6 = 0; var ProgrammableStage = class { constructor(code, type, transforms = null, attributes = null) { this.id = _id$6++; this.code = code; this.stage = type; this.transforms = transforms; this.attributes = attributes; this.usedTimes = 0; } }; var Pipelines = class extends DataMap { constructor(backend, nodes) { super(); this.backend = backend; this.nodes = nodes; this.bindings = null; this.caches = /* @__PURE__ */ new Map(); this.programs = { vertex: /* @__PURE__ */ new Map(), fragment: /* @__PURE__ */ new Map(), compute: /* @__PURE__ */ new Map() }; } getForCompute(computeNode, bindings) { const { backend } = this; const data = this.get(computeNode); if (this._needsComputeUpdate(computeNode)) { const previousPipeline = data.pipeline; if (previousPipeline) { previousPipeline.usedTimes--; previousPipeline.computeProgram.usedTimes--; } const nodeBuilderState = this.nodes.getForCompute(computeNode); let stageCompute = this.programs.compute.get(nodeBuilderState.computeShader); if (stageCompute === void 0) { if (previousPipeline && previousPipeline.computeProgram.usedTimes === 0) this._releaseProgram(previousPipeline.computeProgram); stageCompute = new ProgrammableStage(nodeBuilderState.computeShader, "compute", nodeBuilderState.transforms, nodeBuilderState.nodeAttributes); this.programs.compute.set(nodeBuilderState.computeShader, stageCompute); backend.createProgram(stageCompute); } const cacheKey = this._getComputeCacheKey(computeNode, stageCompute); let pipeline = this.caches.get(cacheKey); if (pipeline === void 0) { if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); pipeline = this._getComputePipeline(computeNode, stageCompute, cacheKey, bindings); } pipeline.usedTimes++; stageCompute.usedTimes++; data.version = computeNode.version; data.pipeline = pipeline; } return data.pipeline; } getForRender(renderObject, promises = null) { const { backend } = this; const data = this.get(renderObject); if (this._needsRenderUpdate(renderObject)) { const previousPipeline = data.pipeline; if (previousPipeline) { previousPipeline.usedTimes--; previousPipeline.vertexProgram.usedTimes--; previousPipeline.fragmentProgram.usedTimes--; } const nodeBuilderState = renderObject.getNodeBuilderState(); let stageVertex = this.programs.vertex.get(nodeBuilderState.vertexShader); if (stageVertex === void 0) { if (previousPipeline && previousPipeline.vertexProgram.usedTimes === 0) this._releaseProgram(previousPipeline.vertexProgram); stageVertex = new ProgrammableStage(nodeBuilderState.vertexShader, "vertex"); this.programs.vertex.set(nodeBuilderState.vertexShader, stageVertex); backend.createProgram(stageVertex); } let stageFragment = this.programs.fragment.get(nodeBuilderState.fragmentShader); if (stageFragment === void 0) { if (previousPipeline && previousPipeline.fragmentProgram.usedTimes === 0) this._releaseProgram(previousPipeline.fragmentProgram); stageFragment = new ProgrammableStage(nodeBuilderState.fragmentShader, "fragment"); this.programs.fragment.set(nodeBuilderState.fragmentShader, stageFragment); backend.createProgram(stageFragment); } const cacheKey = this._getRenderCacheKey(renderObject, stageVertex, stageFragment); let pipeline = this.caches.get(cacheKey); if (pipeline === void 0) { if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); pipeline = this._getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises); } else { renderObject.pipeline = pipeline; } pipeline.usedTimes++; stageVertex.usedTimes++; stageFragment.usedTimes++; data.pipeline = pipeline; } return data.pipeline; } delete(object) { const pipeline = this.get(object).pipeline; if (pipeline) { pipeline.usedTimes--; if (pipeline.usedTimes === 0) this._releasePipeline(pipeline); if (pipeline.isComputePipeline) { pipeline.computeProgram.usedTimes--; if (pipeline.computeProgram.usedTimes === 0) this._releaseProgram(pipeline.computeProgram); } else { pipeline.fragmentProgram.usedTimes--; pipeline.vertexProgram.usedTimes--; if (pipeline.vertexProgram.usedTimes === 0) this._releaseProgram(pipeline.vertexProgram); if (pipeline.fragmentProgram.usedTimes === 0) this._releaseProgram(pipeline.fragmentProgram); } } return super.delete(object); } dispose() { super.dispose(); this.caches = /* @__PURE__ */ new Map(); this.programs = { vertex: /* @__PURE__ */ new Map(), fragment: /* @__PURE__ */ new Map(), compute: /* @__PURE__ */ new Map() }; } updateForRender(renderObject) { this.getForRender(renderObject); } _getComputePipeline(computeNode, stageCompute, cacheKey, bindings) { cacheKey = cacheKey || this._getComputeCacheKey(computeNode, stageCompute); let pipeline = this.caches.get(cacheKey); if (pipeline === void 0) { pipeline = new ComputePipeline(cacheKey, stageCompute); this.caches.set(cacheKey, pipeline); this.backend.createComputePipeline(pipeline, bindings); } return pipeline; } _getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises) { cacheKey = cacheKey || this._getRenderCacheKey(renderObject, stageVertex, stageFragment); let pipeline = this.caches.get(cacheKey); if (pipeline === void 0) { pipeline = new RenderPipeline(cacheKey, stageVertex, stageFragment); this.caches.set(cacheKey, pipeline); renderObject.pipeline = pipeline; this.backend.createRenderPipeline(renderObject, promises); } return pipeline; } _getComputeCacheKey(computeNode, stageCompute) { return computeNode.id + "," + stageCompute.id; } _getRenderCacheKey(renderObject, stageVertex, stageFragment) { return stageVertex.id + "," + stageFragment.id + "," + this.backend.getRenderCacheKey(renderObject); } _releasePipeline(pipeline) { this.caches.delete(pipeline.cacheKey); } _releaseProgram(program) { const code = program.code; const stage = program.stage; this.programs[stage].delete(code); } _needsComputeUpdate(computeNode) { const data = this.get(computeNode); return data.pipeline === void 0 || data.version !== computeNode.version; } _needsRenderUpdate(renderObject) { const data = this.get(renderObject); return data.pipeline === void 0 || this.backend.needsRenderUpdate(renderObject); } }; var Bindings = class extends DataMap { constructor(backend, nodes, textures, attributes, pipelines, info) { super(); this.backend = backend; this.textures = textures; this.pipelines = pipelines; this.attributes = attributes; this.nodes = nodes; this.info = info; this.pipelines.bindings = this; } getForRender(renderObject) { const bindings = renderObject.getBindings(); for (const bindGroup of bindings) { const groupData = this.get(bindGroup); if (groupData.bindGroup === void 0) { this._init(bindGroup); this.backend.createBindings(bindGroup, bindings); groupData.bindGroup = bindGroup; } } return bindings; } getForCompute(computeNode) { const bindings = this.nodes.getForCompute(computeNode).bindings; for (const bindGroup of bindings) { const groupData = this.get(bindGroup); if (groupData.bindGroup === void 0) { this._init(bindGroup); this.backend.createBindings(bindGroup, bindings); groupData.bindGroup = bindGroup; } } return bindings; } updateForCompute(computeNode) { this._updateBindings(this.getForCompute(computeNode)); } updateForRender(renderObject) { this._updateBindings(this.getForRender(renderObject)); } _updateBindings(bindings) { for (const bindGroup of bindings) { this._update(bindGroup, bindings); } } _init(bindGroup) { for (const binding of bindGroup.bindings) { if (binding.isSampledTexture) { this.textures.updateTexture(binding.texture); } else if (binding.isStorageBuffer) { const attribute2 = binding.attribute; const attributeType = attribute2.isIndirectStorageBufferAttribute ? AttributeType.INDIRECT : AttributeType.STORAGE; this.attributes.update(attribute2, attributeType); } } } _update(bindGroup, bindings) { const { backend } = this; let needsBindingsUpdate = false; for (const binding of bindGroup.bindings) { if (binding.isNodeUniformsGroup) { const updated = this.nodes.updateGroup(binding); if (!updated) continue; } if (binding.isUniformBuffer) { const updated = binding.update(); if (updated) { backend.updateBinding(binding); } } else if (binding.isSampler) { binding.update(); } else if (binding.isSampledTexture) { if (binding.needsBindingsUpdate(this.textures.get(binding.texture).generation)) needsBindingsUpdate = true; const updated = binding.update(); const texture2 = binding.texture; if (updated) { this.textures.updateTexture(texture2); } const textureData = backend.get(texture2); if (backend.isWebGPUBackend === true && textureData.texture === void 0 && textureData.externalTexture === void 0) { console.error("Bindings._update: binding should be available:", binding, updated, texture2, binding.textureNode.value, needsBindingsUpdate); this.textures.updateTexture(texture2); needsBindingsUpdate = true; } if (texture2.isStorageTexture === true) { const textureData2 = this.get(texture2); if (binding.store === true) { textureData2.needsMipmap = true; } else if (this.textures.needsMipmaps(texture2) && textureData2.needsMipmap === true) { this.backend.generateMipmaps(texture2); textureData2.needsMipmap = false; } } } } if (needsBindingsUpdate === true) { this.backend.updateBindings(bindGroup, bindings); } } }; function painterSortStable2(a2, b) { if (a2.groupOrder !== b.groupOrder) { return a2.groupOrder - b.groupOrder; } else if (a2.renderOrder !== b.renderOrder) { return a2.renderOrder - b.renderOrder; } else if (a2.material.id !== b.material.id) { return a2.material.id - b.material.id; } else if (a2.z !== b.z) { return a2.z - b.z; } else { return a2.id - b.id; } } function reversePainterSortStable2(a2, b) { if (a2.groupOrder !== b.groupOrder) { return a2.groupOrder - b.groupOrder; } else if (a2.renderOrder !== b.renderOrder) { return a2.renderOrder - b.renderOrder; } else if (a2.z !== b.z) { return b.z - a2.z; } else { return a2.id - b.id; } } function needsDoublePass(material) { const hasTransmission = material.transmission > 0 || material.transmissionNode; return hasTransmission && material.side === DoubleSide2 && material.forceSinglePass === false; } var RenderList = class { constructor(lighting, scene3, camera3) { this.renderItems = []; this.renderItemsIndex = 0; this.opaque = []; this.transparentDoublePass = []; this.transparent = []; this.bundles = []; this.lightsNode = lighting.getNode(scene3, camera3); this.lightsArray = []; this.scene = scene3; this.camera = camera3; this.occlusionQueryCount = 0; } begin() { this.renderItemsIndex = 0; this.opaque.length = 0; this.transparentDoublePass.length = 0; this.transparent.length = 0; this.bundles.length = 0; this.lightsArray.length = 0; this.occlusionQueryCount = 0; return this; } getNextRenderItem(object, geometry, material, groupOrder, z2, group) { let renderItem = this.renderItems[this.renderItemsIndex]; if (renderItem === void 0) { renderItem = { id: object.id, object, geometry, material, groupOrder, renderOrder: object.renderOrder, z: z2, group }; this.renderItems[this.renderItemsIndex] = renderItem; } else { renderItem.id = object.id; renderItem.object = object; renderItem.geometry = geometry; renderItem.material = material; renderItem.groupOrder = groupOrder; renderItem.renderOrder = object.renderOrder; renderItem.z = z2; renderItem.group = group; } this.renderItemsIndex++; return renderItem; } push(object, geometry, material, groupOrder, z2, group) { const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z2, group); if (object.occlusionTest === true) this.occlusionQueryCount++; if (material.transparent === true || material.transmission > 0) { if (needsDoublePass(material)) this.transparentDoublePass.push(renderItem); this.transparent.push(renderItem); } else { this.opaque.push(renderItem); } } unshift(object, geometry, material, groupOrder, z2, group) { const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z2, group); if (material.transparent === true || material.transmission > 0) { if (needsDoublePass(material)) this.transparentDoublePass.unshift(renderItem); this.transparent.unshift(renderItem); } else { this.opaque.unshift(renderItem); } } pushBundle(group) { this.bundles.push(group); } pushLight(light) { this.lightsArray.push(light); } sort(customOpaqueSort, customTransparentSort) { if (this.opaque.length > 1) this.opaque.sort(customOpaqueSort || painterSortStable2); if (this.transparentDoublePass.length > 1) this.transparentDoublePass.sort(customTransparentSort || reversePainterSortStable2); if (this.transparent.length > 1) this.transparent.sort(customTransparentSort || reversePainterSortStable2); } finish() { this.lightsNode.setLights(this.lightsArray); for (let i = this.renderItemsIndex, il = this.renderItems.length; i < il; i++) { const renderItem = this.renderItems[i]; if (renderItem.id === null) break; renderItem.id = null; renderItem.object = null; renderItem.geometry = null; renderItem.material = null; renderItem.groupOrder = null; renderItem.renderOrder = null; renderItem.z = null; renderItem.group = null; } } }; var RenderLists = class { constructor(lighting) { this.lighting = lighting; this.lists = new ChainMap(); } get(scene3, camera3) { const lists = this.lists; const keys = [scene3, camera3]; let list = lists.get(keys); if (list === void 0) { list = new RenderList(this.lighting, scene3, camera3); lists.set(keys, list); } return list; } dispose() { this.lists = new ChainMap(); } }; var id$1 = 0; var RenderContext = class { constructor() { this.id = id$1++; this.color = true; this.clearColor = true; this.clearColorValue = { r: 0, g: 0, b: 0, a: 1 }; this.depth = true; this.clearDepth = true; this.clearDepthValue = 1; this.stencil = false; this.clearStencil = true; this.clearStencilValue = 1; this.viewport = false; this.viewportValue = new Vector42(); this.scissor = false; this.scissorValue = new Vector42(); this.textures = null; this.depthTexture = null; this.activeCubeFace = 0; this.sampleCount = 1; this.width = 0; this.height = 0; this.isRenderContext = true; } getCacheKey() { return getCacheKey(this); } }; function getCacheKey(renderContext) { const { textures, activeCubeFace } = renderContext; const values = [activeCubeFace]; for (const texture2 of textures) { values.push(texture2.id); } return hashArray(values); } var RenderContexts = class { constructor() { this.chainMaps = {}; } get(scene3, camera3, renderTarget = null) { const chainKey = [scene3, camera3]; let attachmentState; if (renderTarget === null) { attachmentState = "default"; } else { const format2 = renderTarget.texture.format; const count = renderTarget.textures.length; attachmentState = `${count}:${format2}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`; } const chainMap = this.getChainMap(attachmentState); let renderState = chainMap.get(chainKey); if (renderState === void 0) { renderState = new RenderContext(); chainMap.set(chainKey, renderState); } if (renderTarget !== null) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; return renderState; } getChainMap(attachmentState) { return this.chainMaps[attachmentState] || (this.chainMaps[attachmentState] = new ChainMap()); } dispose() { this.chainMaps = {}; } }; var _size$3 = /* @__PURE__ */ new Vector32(); var Textures = class extends DataMap { constructor(renderer3, backend, info) { super(); this.renderer = renderer3; this.backend = backend; this.info = info; } updateRenderTarget(renderTarget, activeMipmapLevel = 0) { const renderTargetData = this.get(renderTarget); const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; const depthTextureMips = renderTargetData.depthTextureMips || (renderTargetData.depthTextureMips = {}); const textures = renderTarget.textures; const size = this.getSize(textures[0]); const mipWidth = size.width >> activeMipmapLevel; const mipHeight = size.height >> activeMipmapLevel; let depthTexture = renderTarget.depthTexture || depthTextureMips[activeMipmapLevel]; const useDepthTexture = renderTarget.depthBuffer === true || renderTarget.stencilBuffer === true; let textureNeedsUpdate = false; if (depthTexture === void 0 && useDepthTexture) { depthTexture = new DepthTexture2(); depthTexture.format = renderTarget.stencilBuffer ? DepthStencilFormat2 : DepthFormat2; depthTexture.type = renderTarget.stencilBuffer ? UnsignedInt248Type2 : UnsignedIntType2; depthTexture.image.width = mipWidth; depthTexture.image.height = mipHeight; depthTextureMips[activeMipmapLevel] = depthTexture; } if (renderTargetData.width !== size.width || size.height !== renderTargetData.height) { textureNeedsUpdate = true; if (depthTexture) { depthTexture.needsUpdate = true; depthTexture.image.width = mipWidth; depthTexture.image.height = mipHeight; } } renderTargetData.width = size.width; renderTargetData.height = size.height; renderTargetData.textures = textures; renderTargetData.depthTexture = depthTexture || null; renderTargetData.depth = renderTarget.depthBuffer; renderTargetData.stencil = renderTarget.stencilBuffer; renderTargetData.renderTarget = renderTarget; if (renderTargetData.sampleCount !== sampleCount) { textureNeedsUpdate = true; if (depthTexture) { depthTexture.needsUpdate = true; } renderTargetData.sampleCount = sampleCount; } const options = { sampleCount }; for (let i = 0; i < textures.length; i++) { const texture2 = textures[i]; if (textureNeedsUpdate) texture2.needsUpdate = true; this.updateTexture(texture2, options); } if (depthTexture) { this.updateTexture(depthTexture, options); } if (renderTargetData.initialized !== true) { renderTargetData.initialized = true; const onDispose = () => { renderTarget.removeEventListener("dispose", onDispose); for (let i = 0; i < textures.length; i++) { this._destroyTexture(textures[i]); } if (depthTexture) { this._destroyTexture(depthTexture); } this.delete(renderTarget); }; renderTarget.addEventListener("dispose", onDispose); } } updateTexture(texture2, options = {}) { const textureData = this.get(texture2); if (textureData.initialized === true && textureData.version === texture2.version) return; const isRenderTarget = texture2.isRenderTargetTexture || texture2.isDepthTexture || texture2.isFramebufferTexture; const backend = this.backend; if (isRenderTarget && textureData.initialized === true) { backend.destroySampler(texture2); backend.destroyTexture(texture2); } if (texture2.isFramebufferTexture) { const renderTarget = this.renderer.getRenderTarget(); if (renderTarget) { texture2.type = renderTarget.texture.type; } else { texture2.type = UnsignedByteType2; } } const { width, height, depth: depth2 } = this.getSize(texture2); options.width = width; options.height = height; options.depth = depth2; options.needsMipmaps = this.needsMipmaps(texture2); options.levels = options.needsMipmaps ? this.getMipLevels(texture2, width, height) : 1; if (isRenderTarget || texture2.isStorageTexture === true) { backend.createSampler(texture2); backend.createTexture(texture2, options); textureData.generation = texture2.version; } else { const needsCreate = textureData.initialized !== true; if (needsCreate) backend.createSampler(texture2); if (texture2.version > 0) { const image = texture2.image; if (image === void 0) { console.warn("THREE.Renderer: Texture marked for update but image is undefined."); } else if (image.complete === false) { console.warn("THREE.Renderer: Texture marked for update but image is incomplete."); } else { if (texture2.images) { const images = []; for (const image2 of texture2.images) { images.push(image2); } options.images = images; } else { options.image = image; } if (textureData.isDefaultTexture === void 0 || textureData.isDefaultTexture === true) { backend.createTexture(texture2, options); textureData.isDefaultTexture = false; textureData.generation = texture2.version; } if (texture2.source.dataReady === true) backend.updateTexture(texture2, options); if (options.needsMipmaps && texture2.mipmaps.length === 0) backend.generateMipmaps(texture2); } } else { backend.createDefaultTexture(texture2); textureData.isDefaultTexture = true; textureData.generation = texture2.version; } } if (textureData.initialized !== true) { textureData.initialized = true; textureData.generation = texture2.version; this.info.memory.textures++; const onDispose = () => { texture2.removeEventListener("dispose", onDispose); this._destroyTexture(texture2); this.info.memory.textures--; }; texture2.addEventListener("dispose", onDispose); } textureData.version = texture2.version; } getSize(texture2, target = _size$3) { let image = texture2.images ? texture2.images[0] : texture2.image; if (image) { if (image.image !== void 0) image = image.image; target.width = image.width; target.height = image.height; target.depth = texture2.isCubeTexture ? 6 : image.depth || 1; } else { target.width = target.height = target.depth = 1; } return target; } getMipLevels(texture2, width, height) { let mipLevelCount; if (texture2.isCompressedTexture) { mipLevelCount = texture2.mipmaps.length; } else { mipLevelCount = Math.floor(Math.log2(Math.max(width, height))) + 1; } return mipLevelCount; } needsMipmaps(texture2) { return this.isEnvironmentTexture(texture2) || texture2.isCompressedTexture === true || texture2.generateMipmaps; } isEnvironmentTexture(texture2) { const mapping = texture2.mapping; return mapping === EquirectangularReflectionMapping2 || mapping === EquirectangularRefractionMapping2 || (mapping === CubeReflectionMapping2 || mapping === CubeRefractionMapping2); } _destroyTexture(texture2) { this.backend.destroySampler(texture2); this.backend.destroyTexture(texture2); this.delete(texture2); } }; var Color4 = class extends Color2 { constructor(r, g, b, a2 = 1) { super(r, g, b); this.a = a2; } set(r, g, b, a2 = 1) { this.a = a2; return super.set(r, g, b); } copy(color2) { if (color2.a !== void 0) this.a = color2.a; return super.copy(color2); } clone() { return new this.constructor(this.r, this.g, this.b, this.a); } }; var ParameterNode = class extends PropertyNode { static get type() { return "ParameterNode"; } constructor(nodeType, name = null) { super(nodeType, name); this.isParameterNode = true; } getHash() { return this.uuid; } generate() { return this.name; } }; var StackNode = class extends Node { static get type() { return "StackNode"; } constructor(parent = null) { super(); this.nodes = []; this.outputNode = null; this.parent = parent; this._currentCond = null; this.isStackNode = true; } getNodeType(builder) { return this.outputNode ? this.outputNode.getNodeType(builder) : "void"; } add(node) { this.nodes.push(node); return this; } If(boolNode, method) { const methodNode = new ShaderNode(method); this._currentCond = select(boolNode, methodNode); return this.add(this._currentCond); } ElseIf(boolNode, method) { const methodNode = new ShaderNode(method); const ifNode = select(boolNode, methodNode); this._currentCond.elseNode = ifNode; this._currentCond = ifNode; return this; } Else(method) { this._currentCond.elseNode = new ShaderNode(method); return this; } build(builder, ...params) { const previousStack = getCurrentStack(); setCurrentStack(this); for (const node of this.nodes) { node.build(builder, "void"); } setCurrentStack(previousStack); return this.outputNode ? this.outputNode.build(builder, ...params) : super.build(builder, ...params); } // else(...params) { console.warn("TSL.StackNode: .else() has been renamed to .Else()."); return this.Else(...params); } elseif(...params) { console.warn("TSL.StackNode: .elseif() has been renamed to .ElseIf()."); return this.ElseIf(...params); } }; var stack = /* @__PURE__ */ nodeProxy(StackNode); var _reflectorPlane = new Plane2(); var _normal = new Vector32(); var _reflectorWorldPosition = new Vector32(); var _cameraWorldPosition = new Vector32(); var _rotationMatrix = new Matrix42(); var _lookAtPosition = new Vector32(0, 0, -1); var clipPlane = new Vector42(); var _view = new Vector32(); var _target2 = new Vector32(); var _q = new Vector42(); var _size$2 = new Vector22(); var _defaultRT = new RenderTarget2(); var _defaultUV = screenUV.flipX(); _defaultRT.depthTexture = new DepthTexture2(1, 1); var _camera = /* @__PURE__ */ new OrthographicCamera2(-1, 1, 1, -1, 0, 1); var QuadGeometry = class extends BufferGeometry2 { constructor(flipY = false) { super(); const uv2 = flipY === false ? [0, -1, 0, 1, 2, 1] : [0, 2, 0, 0, 2, 0]; this.setAttribute("position", new Float32BufferAttribute2([-1, 3, 0, -1, -1, 0, 3, -1, 0], 3)); this.setAttribute("uv", new Float32BufferAttribute2(uv2, 2)); } }; var _geometry = /* @__PURE__ */ new QuadGeometry(); var QuadMesh = class extends Mesh2 { constructor(material = null) { super(_geometry, material); this.camera = _camera; this.isQuadMesh = true; } renderAsync(renderer3) { return renderer3.renderAsync(this, _camera); } render(renderer3) { renderer3.render(this, _camera); } }; var _e12 = /* @__PURE__ */ new Euler2(); var _m12 = /* @__PURE__ */ new Matrix42(); var SceneNode = class _SceneNode extends Node { static get type() { return "SceneNode"; } constructor(scope = _SceneNode.BACKGROUND_BLURRINESS, scene3 = null) { super(); this.scope = scope; this.scene = scene3; } setup(builder) { const scope = this.scope; const scene3 = this.scene !== null ? this.scene : builder.scene; let output2; if (scope === _SceneNode.BACKGROUND_BLURRINESS) { output2 = reference("backgroundBlurriness", "float", scene3); } else if (scope === _SceneNode.BACKGROUND_INTENSITY) { output2 = reference("backgroundIntensity", "float", scene3); } else if (scope === _SceneNode.BACKGROUND_ROTATION) { output2 = uniform("mat4").label("backgroundRotation").setGroup(renderGroup).onRenderUpdate(() => { const background = scene3.background; if (background !== null && background.isTexture && background.mapping !== UVMapping2) { _e12.copy(scene3.backgroundRotation); _e12.x *= -1; _e12.y *= -1; _e12.z *= -1; _m12.makeRotationFromEuler(_e12); } else { _m12.identity(); } return _m12; }); } else { console.error("THREE.SceneNode: Unknown scope:", scope); } return output2; } }; SceneNode.BACKGROUND_BLURRINESS = "backgroundBlurriness"; SceneNode.BACKGROUND_INTENSITY = "backgroundIntensity"; SceneNode.BACKGROUND_ROTATION = "backgroundRotation"; var backgroundBlurriness = /* @__PURE__ */ nodeImmutable(SceneNode, SceneNode.BACKGROUND_BLURRINESS); var backgroundIntensity = /* @__PURE__ */ nodeImmutable(SceneNode, SceneNode.BACKGROUND_INTENSITY); var backgroundRotation = /* @__PURE__ */ nodeImmutable(SceneNode, SceneNode.BACKGROUND_ROTATION); var GPUPrimitiveTopology = { PointList: "point-list", LineList: "line-list", LineStrip: "line-strip", TriangleList: "triangle-list", TriangleStrip: "triangle-strip" }; var GPUCompareFunction = { Never: "never", Less: "less", Equal: "equal", LessEqual: "less-equal", Greater: "greater", NotEqual: "not-equal", GreaterEqual: "greater-equal", Always: "always" }; var GPUStoreOp = { Store: "store", Discard: "discard" }; var GPULoadOp = { Load: "load", Clear: "clear" }; var GPUFrontFace = { CCW: "ccw", CW: "cw" }; var GPUCullMode = { None: "none", Front: "front", Back: "back" }; var GPUIndexFormat = { Uint16: "uint16", Uint32: "uint32" }; var GPUTextureFormat = { // 8-bit formats R8Unorm: "r8unorm", R8Snorm: "r8snorm", R8Uint: "r8uint", R8Sint: "r8sint", // 16-bit formats R16Uint: "r16uint", R16Sint: "r16sint", R16Float: "r16float", RG8Unorm: "rg8unorm", RG8Snorm: "rg8snorm", RG8Uint: "rg8uint", RG8Sint: "rg8sint", // 32-bit formats R32Uint: "r32uint", R32Sint: "r32sint", R32Float: "r32float", RG16Uint: "rg16uint", RG16Sint: "rg16sint", RG16Float: "rg16float", RGBA8Unorm: "rgba8unorm", RGBA8UnormSRGB: "rgba8unorm-srgb", RGBA8Snorm: "rgba8snorm", RGBA8Uint: "rgba8uint", RGBA8Sint: "rgba8sint", BGRA8Unorm: "bgra8unorm", BGRA8UnormSRGB: "bgra8unorm-srgb", // Packed 32-bit formats RGB9E5UFloat: "rgb9e5ufloat", RGB10A2Unorm: "rgb10a2unorm", RG11B10uFloat: "rgb10a2unorm", // 64-bit formats RG32Uint: "rg32uint", RG32Sint: "rg32sint", RG32Float: "rg32float", RGBA16Uint: "rgba16uint", RGBA16Sint: "rgba16sint", RGBA16Float: "rgba16float", // 128-bit formats RGBA32Uint: "rgba32uint", RGBA32Sint: "rgba32sint", RGBA32Float: "rgba32float", // Depth and stencil formats Stencil8: "stencil8", Depth16Unorm: "depth16unorm", Depth24Plus: "depth24plus", Depth24PlusStencil8: "depth24plus-stencil8", Depth32Float: "depth32float", // 'depth32float-stencil8' extension Depth32FloatStencil8: "depth32float-stencil8", // BC compressed formats usable if 'texture-compression-bc' is both // supported by the device/user agent and enabled in requestDevice. BC1RGBAUnorm: "bc1-rgba-unorm", BC1RGBAUnormSRGB: "bc1-rgba-unorm-srgb", BC2RGBAUnorm: "bc2-rgba-unorm", BC2RGBAUnormSRGB: "bc2-rgba-unorm-srgb", BC3RGBAUnorm: "bc3-rgba-unorm", BC3RGBAUnormSRGB: "bc3-rgba-unorm-srgb", BC4RUnorm: "bc4-r-unorm", BC4RSnorm: "bc4-r-snorm", BC5RGUnorm: "bc5-rg-unorm", BC5RGSnorm: "bc5-rg-snorm", BC6HRGBUFloat: "bc6h-rgb-ufloat", BC6HRGBFloat: "bc6h-rgb-float", BC7RGBAUnorm: "bc7-rgba-unorm", BC7RGBAUnormSRGB: "bc7-rgba-srgb", // ETC2 compressed formats usable if 'texture-compression-etc2' is both // supported by the device/user agent and enabled in requestDevice. ETC2RGB8Unorm: "etc2-rgb8unorm", ETC2RGB8UnormSRGB: "etc2-rgb8unorm-srgb", ETC2RGB8A1Unorm: "etc2-rgb8a1unorm", ETC2RGB8A1UnormSRGB: "etc2-rgb8a1unorm-srgb", ETC2RGBA8Unorm: "etc2-rgba8unorm", ETC2RGBA8UnormSRGB: "etc2-rgba8unorm-srgb", EACR11Unorm: "eac-r11unorm", EACR11Snorm: "eac-r11snorm", EACRG11Unorm: "eac-rg11unorm", EACRG11Snorm: "eac-rg11snorm", // ASTC compressed formats usable if 'texture-compression-astc' is both // supported by the device/user agent and enabled in requestDevice. ASTC4x4Unorm: "astc-4x4-unorm", ASTC4x4UnormSRGB: "astc-4x4-unorm-srgb", ASTC5x4Unorm: "astc-5x4-unorm", ASTC5x4UnormSRGB: "astc-5x4-unorm-srgb", ASTC5x5Unorm: "astc-5x5-unorm", ASTC5x5UnormSRGB: "astc-5x5-unorm-srgb", ASTC6x5Unorm: "astc-6x5-unorm", ASTC6x5UnormSRGB: "astc-6x5-unorm-srgb", ASTC6x6Unorm: "astc-6x6-unorm", ASTC6x6UnormSRGB: "astc-6x6-unorm-srgb", ASTC8x5Unorm: "astc-8x5-unorm", ASTC8x5UnormSRGB: "astc-8x5-unorm-srgb", ASTC8x6Unorm: "astc-8x6-unorm", ASTC8x6UnormSRGB: "astc-8x6-unorm-srgb", ASTC8x8Unorm: "astc-8x8-unorm", ASTC8x8UnormSRGB: "astc-8x8-unorm-srgb", ASTC10x5Unorm: "astc-10x5-unorm", ASTC10x5UnormSRGB: "astc-10x5-unorm-srgb", ASTC10x6Unorm: "astc-10x6-unorm", ASTC10x6UnormSRGB: "astc-10x6-unorm-srgb", ASTC10x8Unorm: "astc-10x8-unorm", ASTC10x8UnormSRGB: "astc-10x8-unorm-srgb", ASTC10x10Unorm: "astc-10x10-unorm", ASTC10x10UnormSRGB: "astc-10x10-unorm-srgb", ASTC12x10Unorm: "astc-12x10-unorm", ASTC12x10UnormSRGB: "astc-12x10-unorm-srgb", ASTC12x12Unorm: "astc-12x12-unorm", ASTC12x12UnormSRGB: "astc-12x12-unorm-srgb" }; var GPUAddressMode = { ClampToEdge: "clamp-to-edge", Repeat: "repeat", MirrorRepeat: "mirror-repeat" }; var GPUFilterMode = { Linear: "linear", Nearest: "nearest" }; var GPUBlendFactor = { Zero: "zero", One: "one", Src: "src", OneMinusSrc: "one-minus-src", SrcAlpha: "src-alpha", OneMinusSrcAlpha: "one-minus-src-alpha", Dst: "dst", OneMinusDstColor: "one-minus-dst", DstAlpha: "dst-alpha", OneMinusDstAlpha: "one-minus-dst-alpha", SrcAlphaSaturated: "src-alpha-saturated", Constant: "constant", OneMinusConstant: "one-minus-constant" }; var GPUBlendOperation = { Add: "add", Subtract: "subtract", ReverseSubtract: "reverse-subtract", Min: "min", Max: "max" }; var GPUColorWriteFlags = { None: 0, Red: 1, Green: 2, Blue: 4, Alpha: 8, All: 15 }; var GPUStencilOperation = { Keep: "keep", Zero: "zero", Replace: "replace", Invert: "invert", IncrementClamp: "increment-clamp", DecrementClamp: "decrement-clamp", IncrementWrap: "increment-wrap", DecrementWrap: "decrement-wrap" }; var GPUBufferBindingType = { Uniform: "uniform", Storage: "storage", ReadOnlyStorage: "read-only-storage" }; var GPUStorageTextureAccess = { WriteOnly: "write-only", ReadOnly: "read-only", ReadWrite: "read-write" }; var GPUTextureSampleType = { Float: "float", UnfilterableFloat: "unfilterable-float", Depth: "depth", SInt: "sint", UInt: "uint" }; var GPUTextureDimension = { OneD: "1d", TwoD: "2d", ThreeD: "3d" }; var GPUTextureViewDimension = { OneD: "1d", TwoD: "2d", TwoDArray: "2d-array", Cube: "cube", CubeArray: "cube-array", ThreeD: "3d" }; var GPUTextureAspect = { All: "all", StencilOnly: "stencil-only", DepthOnly: "depth-only" }; var GPUInputStepMode = { Vertex: "vertex", Instance: "instance" }; var GPUFeatureName = { DepthClipControl: "depth-clip-control", Depth32FloatStencil8: "depth32float-stencil8", TextureCompressionBC: "texture-compression-bc", TextureCompressionETC2: "texture-compression-etc2", TextureCompressionASTC: "texture-compression-astc", TimestampQuery: "timestamp-query", IndirectFirstInstance: "indirect-first-instance", ShaderF16: "shader-f16", RG11B10UFloat: "rg11b10ufloat-renderable", BGRA8UNormStorage: "bgra8unorm-storage", Float32Filterable: "float32-filterable", ClipDistances: "clip-distances", DualSourceBlending: "dual-source-blending", Subgroups: "subgroups" }; var _size = /* @__PURE__ */ new Vector22(); var PassTextureNode = class extends TextureNode { static get type() { return "PassTextureNode"; } constructor(passNode, texture2) { super(texture2); this.passNode = passNode; this.setUpdateMatrix(false); } setup(builder) { if (builder.object.isQuadMesh) this.passNode.build(builder); return super.setup(builder); } clone() { return new this.constructor(this.passNode, this.value); } }; var PassMultipleTextureNode = class extends PassTextureNode { static get type() { return "PassMultipleTextureNode"; } constructor(passNode, textureName, previousTexture = false) { super(passNode, null); this.textureName = textureName; this.previousTexture = previousTexture; } updateTexture() { this.value = this.previousTexture ? this.passNode.getPreviousTexture(this.textureName) : this.passNode.getTexture(this.textureName); } setup(builder) { this.updateTexture(); return super.setup(builder); } clone() { return new this.constructor(this.passNode, this.textureName, this.previousTexture); } }; var PassNode = class _PassNode extends TempNode { static get type() { return "PassNode"; } constructor(scope, scene3, camera3, options = {}) { super("vec4"); this.scope = scope; this.scene = scene3; this.camera = camera3; this.options = options; this._pixelRatio = 1; this._width = 1; this._height = 1; const depthTexture = new DepthTexture2(); depthTexture.isRenderTargetTexture = true; depthTexture.name = "depth"; const renderTarget = new RenderTarget2(this._width * this._pixelRatio, this._height * this._pixelRatio, { type: HalfFloatType2, ...options }); renderTarget.texture.name = "output"; renderTarget.depthTexture = depthTexture; this.renderTarget = renderTarget; this.updateBeforeType = NodeUpdateType.FRAME; this._textures = { output: renderTarget.texture, depth: depthTexture }; this._textureNodes = {}; this._linearDepthNodes = {}; this._viewZNodes = {}; this._previousTextures = {}; this._previousTextureNodes = {}; this._cameraNear = uniform(0); this._cameraFar = uniform(0); this._mrt = null; this.isPassNode = true; } setMRT(mrt) { this._mrt = mrt; return this; } getMRT() { return this._mrt; } isGlobal() { return true; } getTexture(name) { let texture2 = this._textures[name]; if (texture2 === void 0) { const refTexture = this.renderTarget.texture; texture2 = refTexture.clone(); texture2.isRenderTargetTexture = true; texture2.name = name; this._textures[name] = texture2; this.renderTarget.textures.push(texture2); } return texture2; } getPreviousTexture(name) { let texture2 = this._previousTextures[name]; if (texture2 === void 0) { texture2 = this.getTexture(name).clone(); texture2.isRenderTargetTexture = true; this._previousTextures[name] = texture2; } return texture2; } toggleTexture(name) { const prevTexture = this._previousTextures[name]; if (prevTexture !== void 0) { const texture2 = this._textures[name]; const index5 = this.renderTarget.textures.indexOf(texture2); this.renderTarget.textures[index5] = prevTexture; this._textures[name] = prevTexture; this._previousTextures[name] = texture2; this._textureNodes[name].updateTexture(); this._previousTextureNodes[name].updateTexture(); } } getTextureNode(name = "output") { let textureNode = this._textureNodes[name]; if (textureNode === void 0) { textureNode = nodeObject(new PassMultipleTextureNode(this, name)); textureNode.updateTexture(); this._textureNodes[name] = textureNode; } return textureNode; } getPreviousTextureNode(name = "output") { let textureNode = this._previousTextureNodes[name]; if (textureNode === void 0) { if (this._textureNodes[name] === void 0) this.getTextureNode(name); textureNode = nodeObject(new PassMultipleTextureNode(this, name, true)); textureNode.updateTexture(); this._previousTextureNodes[name] = textureNode; } return textureNode; } getViewZNode(name = "depth") { let viewZNode = this._viewZNodes[name]; if (viewZNode === void 0) { const cameraNear2 = this._cameraNear; const cameraFar2 = this._cameraFar; this._viewZNodes[name] = viewZNode = perspectiveDepthToViewZ(this.getTextureNode(name), cameraNear2, cameraFar2); } return viewZNode; } getLinearDepthNode(name = "depth") { let linearDepthNode = this._linearDepthNodes[name]; if (linearDepthNode === void 0) { const cameraNear2 = this._cameraNear; const cameraFar2 = this._cameraFar; const viewZNode = this.getViewZNode(name); this._linearDepthNodes[name] = linearDepthNode = viewZToOrthographicDepth(viewZNode, cameraNear2, cameraFar2); } return linearDepthNode; } setup({ renderer: renderer3 }) { this.renderTarget.samples = this.options.samples === void 0 ? renderer3.samples : this.options.samples; if (renderer3.backend.isWebGLBackend === true) { this.renderTarget.samples = 0; } this.renderTarget.depthTexture.isMultisampleRenderTargetTexture = this.renderTarget.samples > 1; return this.scope === _PassNode.COLOR ? this.getTextureNode() : this.getLinearDepthNode(); } updateBefore(frame2) { const { renderer: renderer3 } = frame2; const { scene: scene3, camera: camera3 } = this; this._pixelRatio = renderer3.getPixelRatio(); const size = renderer3.getSize(_size); this.setSize(size.width, size.height); const currentRenderTarget = renderer3.getRenderTarget(); const currentMRT = renderer3.getMRT(); this._cameraNear.value = camera3.near; this._cameraFar.value = camera3.far; for (const name in this._previousTextures) { this.toggleTexture(name); } renderer3.setRenderTarget(this.renderTarget); renderer3.setMRT(this._mrt); renderer3.render(scene3, camera3); renderer3.setRenderTarget(currentRenderTarget); renderer3.setMRT(currentMRT); } setSize(width, height) { this._width = width; this._height = height; const effectiveWidth = this._width * this._pixelRatio; const effectiveHeight = this._height * this._pixelRatio; this.renderTarget.setSize(effectiveWidth, effectiveHeight); } setPixelRatio(pixelRatio) { this._pixelRatio = pixelRatio; this.setSize(this._width, this._height); } dispose() { this.renderTarget.dispose(); } }; PassNode.COLOR = "color"; PassNode.DEPTH = "depth"; var linearToneMapping = /* @__PURE__ */ Fn(([color2, exposure]) => { return color2.mul(exposure).clamp(); }).setLayout({ name: "linearToneMapping", type: "vec3", inputs: [ { name: "color", type: "vec3" }, { name: "exposure", type: "float" } ] }); var reinhardToneMapping = /* @__PURE__ */ Fn(([color2, exposure]) => { color2 = color2.mul(exposure); return color2.div(color2.add(1)).clamp(); }).setLayout({ name: "reinhardToneMapping", type: "vec3", inputs: [ { name: "color", type: "vec3" }, { name: "exposure", type: "float" } ] }); var cineonToneMapping = /* @__PURE__ */ Fn(([color2, exposure]) => { color2 = color2.mul(exposure); color2 = color2.sub(4e-3).max(0); const a2 = color2.mul(color2.mul(6.2).add(0.5)); const b = color2.mul(color2.mul(6.2).add(1.7)).add(0.06); return a2.div(b).pow(2.2); }).setLayout({ name: "cineonToneMapping", type: "vec3", inputs: [ { name: "color", type: "vec3" }, { name: "exposure", type: "float" } ] }); var RRTAndODTFit = /* @__PURE__ */ Fn(([color2]) => { const a2 = color2.mul(color2.add(0.0245786)).sub(90537e-9); const b = color2.mul(color2.add(0.432951).mul(0.983729)).add(0.238081); return a2.div(b); }); var acesFilmicToneMapping = /* @__PURE__ */ Fn(([color2, exposure]) => { const ACESInputMat = mat3( 0.59719, 0.35458, 0.04823, 0.076, 0.90834, 0.01566, 0.0284, 0.13383, 0.83777 ); const ACESOutputMat = mat3( 1.60475, -0.53108, -0.07367, -0.10208, 1.10813, -605e-5, -327e-5, -0.07276, 1.07602 ); color2 = color2.mul(exposure).div(0.6); color2 = ACESInputMat.mul(color2); color2 = RRTAndODTFit(color2); color2 = ACESOutputMat.mul(color2); return color2.clamp(); }).setLayout({ name: "acesFilmicToneMapping", type: "vec3", inputs: [ { name: "color", type: "vec3" }, { name: "exposure", type: "float" } ] }); var LINEAR_REC2020_TO_LINEAR_SRGB = /* @__PURE__ */ mat3(vec3(1.6605, -0.1246, -0.0182), vec3(-0.5876, 1.1329, -0.1006), vec3(-0.0728, -83e-4, 1.1187)); var LINEAR_SRGB_TO_LINEAR_REC2020 = /* @__PURE__ */ mat3(vec3(0.6274, 0.0691, 0.0164), vec3(0.3293, 0.9195, 0.088), vec3(0.0433, 0.0113, 0.8956)); var agxDefaultContrastApprox = /* @__PURE__ */ Fn(([x_immutable]) => { const x2 = vec3(x_immutable).toVar(); const x22 = vec3(x2.mul(x2)).toVar(); const x4 = vec3(x22.mul(x22)).toVar(); return float(15.5).mul(x4.mul(x22)).sub(mul(40.14, x4.mul(x2))).add(mul(31.96, x4).sub(mul(6.868, x22.mul(x2))).add(mul(0.4298, x22).add(mul(0.1191, x2).sub(232e-5)))); }); var agxToneMapping = /* @__PURE__ */ Fn(([color2, exposure]) => { const colortone = vec3(color2).toVar(); const AgXInsetMatrix = mat3(vec3(0.856627153315983, 0.137318972929847, 0.11189821299995), vec3(0.0951212405381588, 0.761241990602591, 0.0767994186031903), vec3(0.0482516061458583, 0.101439036467562, 0.811302368396859)); const AgXOutsetMatrix = mat3(vec3(1.1271005818144368, -0.1413297634984383, -0.14132976349843826), vec3(-0.11060664309660323, 1.157823702216272, -0.11060664309660294), vec3(-0.016493938717834573, -0.016493938717834257, 1.2519364065950405)); const AgxMinEv = float(-12.47393); const AgxMaxEv = float(4.026069); colortone.mulAssign(exposure); colortone.assign(LINEAR_SRGB_TO_LINEAR_REC2020.mul(colortone)); colortone.assign(AgXInsetMatrix.mul(colortone)); colortone.assign(max$1(colortone, 1e-10)); colortone.assign(log2(colortone)); colortone.assign(colortone.sub(AgxMinEv).div(AgxMaxEv.sub(AgxMinEv))); colortone.assign(clamp2(colortone, 0, 1)); colortone.assign(agxDefaultContrastApprox(colortone)); colortone.assign(AgXOutsetMatrix.mul(colortone)); colortone.assign(pow(max$1(vec3(0), colortone), vec3(2.2))); colortone.assign(LINEAR_REC2020_TO_LINEAR_SRGB.mul(colortone)); colortone.assign(clamp2(colortone, 0, 1)); return colortone; }).setLayout({ name: "agxToneMapping", type: "vec3", inputs: [ { name: "color", type: "vec3" }, { name: "exposure", type: "float" } ] }); var neutralToneMapping = /* @__PURE__ */ Fn(([color2, exposure]) => { const StartCompression = float(0.8 - 0.04); const Desaturation = float(0.15); color2 = color2.mul(exposure); const x2 = min$1(color2.r, min$1(color2.g, color2.b)); const offset = select(x2.lessThan(0.08), x2.sub(mul(6.25, x2.mul(x2))), 0.04); color2.subAssign(offset); const peak = max$1(color2.r, max$1(color2.g, color2.b)); If(peak.lessThan(StartCompression), () => { return color2; }); const d = sub(1, StartCompression); const newPeak = sub(1, d.mul(d).div(peak.add(d.sub(StartCompression)))); color2.mulAssign(newPeak.div(peak)); const g = sub(1, div(1, Desaturation.mul(peak.sub(newPeak)).add(1))); return mix(color2, vec3(newPeak), g); }).setLayout({ name: "neutralToneMapping", type: "vec3", inputs: [ { name: "color", type: "vec3" }, { name: "exposure", type: "float" } ] }); var CodeNode = class extends Node { static get type() { return "CodeNode"; } constructor(code = "", includes = [], language = "") { super("code"); this.isCodeNode = true; this.code = code; this.language = language; this.includes = includes; } isGlobal() { return true; } setIncludes(includes) { this.includes = includes; return this; } getIncludes() { return this.includes; } generate(builder) { const includes = this.getIncludes(builder); for (const include of includes) { include.build(builder); } const nodeCode = builder.getCodeFromNode(this, this.getNodeType(builder)); nodeCode.code = this.code; return nodeCode.code; } serialize(data) { super.serialize(data); data.code = this.code; data.language = this.language; } deserialize(data) { super.deserialize(data); this.code = data.code; this.language = data.language; } }; var FunctionNode = class extends CodeNode { static get type() { return "FunctionNode"; } constructor(code = "", includes = [], language = "") { super(code, includes, language); } getNodeType(builder) { return this.getNodeFunction(builder).type; } getInputs(builder) { return this.getNodeFunction(builder).inputs; } getNodeFunction(builder) { const nodeData = builder.getDataFromNode(this); let nodeFunction = nodeData.nodeFunction; if (nodeFunction === void 0) { nodeFunction = builder.parser.parseFunction(this.code); nodeData.nodeFunction = nodeFunction; } return nodeFunction; } generate(builder, output2) { super.generate(builder); const nodeFunction = this.getNodeFunction(builder); const name = nodeFunction.name; const type = nodeFunction.type; const nodeCode = builder.getCodeFromNode(this, type); if (name !== "") { nodeCode.name = name; } const propertyName = builder.getPropertyName(nodeCode); const code = this.getNodeFunction(builder).getCode(propertyName); nodeCode.code = code + "\n"; if (output2 === "property") { return propertyName; } else { return builder.format(`${propertyName}()`, type, output2); } } }; var Resources = class extends Map { get(key, callback = null, ...params) { if (this.has(key)) return super.get(key); if (callback !== null) { const value = callback(...params); this.set(key, value); return value; } } }; var ScriptableNodeResources = new Resources(); var FogNode = class extends Node { static get type() { return "FogNode"; } constructor(colorNode, factorNode) { super("float"); this.isFogNode = true; this.colorNode = colorNode; this.factorNode = factorNode; } getViewZNode(builder) { let viewZ; const getViewZ = builder.context.getViewZ; if (getViewZ !== void 0) { viewZ = getViewZ(this); } return (viewZ || positionView.z).negate(); } setup() { return this.factorNode; } }; var FogRangeNode = class extends FogNode { static get type() { return "FogRangeNode"; } constructor(colorNode, nearNode, farNode) { super(colorNode); this.isFogRangeNode = true; this.nearNode = nearNode; this.farNode = farNode; } setup(builder) { const viewZ = this.getViewZNode(builder); return smoothstep2(this.nearNode, this.farNode, viewZ); } }; var rangeFog = /* @__PURE__ */ nodeProxy(FogRangeNode); var FogExp2Node = class extends FogNode { static get type() { return "FogExp2Node"; } constructor(colorNode, densityNode) { super(colorNode); this.isFogExp2Node = true; this.densityNode = densityNode; } setup(builder) { const viewZ = this.getViewZNode(builder); const density = this.densityNode; return density.mul(density, viewZ, viewZ).negate().exp().oneMinus(); } }; var densityFog = /* @__PURE__ */ nodeProxy(FogExp2Node); var BarrierNode = class extends Node { constructor(scope) { super(); this.scope = scope; } generate(builder) { const { scope } = this; const { renderer: renderer3 } = builder; if (renderer3.backend.isWebGLBackend === true) { builder.addFlowCode(` // ${scope}Barrier `); } else { builder.addLineFlowCode(`${scope}Barrier()`, this); } } }; var barrier = nodeProxy(BarrierNode); var AtomicFunctionNode = class extends TempNode { static get type() { return "AtomicFunctionNode"; } constructor(method, pointerNode, valueNode, storeNode = null) { super("uint"); this.method = method; this.pointerNode = pointerNode; this.valueNode = valueNode; this.storeNode = storeNode; } getInputType(builder) { return this.pointerNode.getNodeType(builder); } getNodeType(builder) { return this.getInputType(builder); } generate(builder) { const method = this.method; const type = this.getNodeType(builder); const inputType = this.getInputType(builder); const a2 = this.pointerNode; const b = this.valueNode; const params = []; params.push(`&${a2.build(builder, inputType)}`); params.push(b.build(builder, inputType)); const methodSnippet = `${builder.getMethod(method, type)}( ${params.join(", ")} )`; if (this.storeNode !== null) { const varSnippet = this.storeNode.build(builder, inputType); builder.addLineFlowCode(`${varSnippet} = ${methodSnippet}`, this); } else { builder.addLineFlowCode(methodSnippet, this); } } }; AtomicFunctionNode.ATOMIC_LOAD = "atomicLoad"; AtomicFunctionNode.ATOMIC_STORE = "atomicStore"; AtomicFunctionNode.ATOMIC_ADD = "atomicAdd"; AtomicFunctionNode.ATOMIC_SUB = "atomicSub"; AtomicFunctionNode.ATOMIC_MAX = "atomicMax"; AtomicFunctionNode.ATOMIC_MIN = "atomicMin"; AtomicFunctionNode.ATOMIC_AND = "atomicAnd"; AtomicFunctionNode.ATOMIC_OR = "atomicOr"; AtomicFunctionNode.ATOMIC_XOR = "atomicXor"; var atomicNode = nodeProxy(AtomicFunctionNode); var uniformsLib; function getLightData(light) { uniformsLib = uniformsLib || /* @__PURE__ */ new WeakMap(); let uniforms = uniformsLib.get(light); if (uniforms === void 0) uniformsLib.set(light, uniforms = {}); return uniforms; } function lightPosition(light) { const data = getLightData(light); return data.position || (data.position = uniform(new Vector32()).setGroup(renderGroup).onRenderUpdate((_, self2) => self2.value.setFromMatrixPosition(light.matrixWorld))); } function lightTargetPosition(light) { const data = getLightData(light); return data.targetPosition || (data.targetPosition = uniform(new Vector32()).setGroup(renderGroup).onRenderUpdate((_, self2) => self2.value.setFromMatrixPosition(light.target.matrixWorld))); } function lightViewPosition(light) { const data = getLightData(light); return data.viewPosition || (data.viewPosition = uniform(new Vector32()).setGroup(renderGroup).onRenderUpdate(({ camera: camera3 }, self2) => { self2.value = self2.value || new Vector32(); self2.value.setFromMatrixPosition(light.matrixWorld); self2.value.applyMatrix4(camera3.matrixWorldInverse); })); } var lightTargetDirection = (light) => cameraViewMatrix.transformDirection(lightPosition(light).sub(lightTargetPosition(light))); var sortLights = (lights) => { return lights.sort((a2, b) => a2.id - b.id); }; var getLightNodeById = (id2, lightNodes) => { for (const lightNode of lightNodes) { if (lightNode.isAnalyticLightNode && lightNode.light.id === id2) { return lightNode; } } return null; }; var _lightsNodeRef = /* @__PURE__ */ new WeakMap(); var LightsNode = class extends Node { static get type() { return "LightsNode"; } constructor() { super("vec3"); this.totalDiffuseNode = vec3().toVar("totalDiffuse"); this.totalSpecularNode = vec3().toVar("totalSpecular"); this.outgoingLightNode = vec3().toVar("outgoingLight"); this._lights = []; this._lightNodes = null; this._lightNodesHash = null; this.global = true; } getHash(builder) { if (this._lightNodesHash === null) { if (this._lightNodes === null) this.setupLightsNode(builder); const hash = []; for (const lightNode of this._lightNodes) { hash.push(lightNode.getSelf().getHash()); } this._lightNodesHash = "lights-" + hash.join(","); } return this._lightNodesHash; } analyze(builder) { const properties = builder.getDataFromNode(this); for (const node of properties.nodes) { node.build(builder); } } setupLightsNode(builder) { const lightNodes = []; const previousLightNodes = this._lightNodes; const lights = sortLights(this._lights); const nodeLibrary = builder.renderer.library; for (const light of lights) { if (light.isNode) { lightNodes.push(nodeObject(light)); } else { let lightNode = null; if (previousLightNodes !== null) { lightNode = getLightNodeById(light.id, previousLightNodes); } if (lightNode === null) { const lightNodeClass = nodeLibrary.getLightNodeClass(light.constructor); if (lightNodeClass === null) { console.warn(`LightsNode.setupNodeLights: Light node not found for ${light.constructor.name}`); continue; } let lightNode2 = null; if (!_lightsNodeRef.has(light)) { lightNode2 = nodeObject(new lightNodeClass(light)); _lightsNodeRef.set(light, lightNode2); } else { lightNode2 = _lightsNodeRef.get(light); } lightNodes.push(lightNode2); } } } this._lightNodes = lightNodes; } setupLights(builder, lightNodes) { for (const lightNode of lightNodes) { lightNode.build(builder); } } setup(builder) { if (this._lightNodes === null) this.setupLightsNode(builder); const context2 = builder.context; const lightingModel = context2.lightingModel; let outgoingLightNode = this.outgoingLightNode; if (lightingModel) { const { _lightNodes, totalDiffuseNode, totalSpecularNode } = this; context2.outgoingLight = outgoingLightNode; const stack2 = builder.addStack(); const properties = builder.getDataFromNode(this); properties.nodes = stack2.nodes; lightingModel.start(context2, stack2, builder); this.setupLights(builder, _lightNodes); lightingModel.indirect(context2, stack2, builder); const { backdrop, backdropAlpha } = context2; const { directDiffuse, directSpecular, indirectDiffuse, indirectSpecular } = context2.reflectedLight; let totalDiffuse = directDiffuse.add(indirectDiffuse); if (backdrop !== null) { if (backdropAlpha !== null) { totalDiffuse = vec3(backdropAlpha.mix(totalDiffuse, backdrop)); } else { totalDiffuse = vec3(backdrop); } context2.material.transparent = true; } totalDiffuseNode.assign(totalDiffuse); totalSpecularNode.assign(directSpecular.add(indirectSpecular)); outgoingLightNode.assign(totalDiffuseNode.add(totalSpecularNode)); lightingModel.finish(context2, stack2, builder); outgoingLightNode = outgoingLightNode.bypass(builder.removeStack()); } return outgoingLightNode; } setLights(lights) { this._lights = lights; this._lightNodes = null; this._lightNodesHash = null; return this; } getLights() { return this._lights; } get hasLights() { return this._lights.length > 0; } }; var BasicShadowMap = Fn(({ depthTexture, shadowCoord }) => { return texture(depthTexture, shadowCoord.xy).compare(shadowCoord.z); }); var PCFShadowMap2 = Fn(({ depthTexture, shadowCoord, shadow: shadow2 }) => { const depthCompare = (uv2, compare) => texture(depthTexture, uv2).compare(compare); const mapSize = reference("mapSize", "vec2", shadow2).setGroup(renderGroup); const radius = reference("radius", "float", shadow2).setGroup(renderGroup); const texelSize = vec2(1).div(mapSize); const dx0 = texelSize.x.negate().mul(radius); const dy0 = texelSize.y.negate().mul(radius); const dx1 = texelSize.x.mul(radius); const dy1 = texelSize.y.mul(radius); const dx2 = dx0.div(2); const dy2 = dy0.div(2); const dx3 = dx1.div(2); const dy3 = dy1.div(2); return add4( depthCompare(shadowCoord.xy.add(vec2(dx0, dy0)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(0, dy0)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx1, dy0)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx2, dy2)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(0, dy2)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx3, dy2)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx0, 0)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx2, 0)), shadowCoord.z), depthCompare(shadowCoord.xy, shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx3, 0)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx1, 0)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx2, dy3)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(0, dy3)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx3, dy3)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx0, dy1)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(0, dy1)), shadowCoord.z), depthCompare(shadowCoord.xy.add(vec2(dx1, dy1)), shadowCoord.z) ).mul(1 / 17); }); var PCFSoftShadowMap2 = Fn(({ depthTexture, shadowCoord, shadow: shadow2 }) => { const depthCompare = (uv3, compare) => texture(depthTexture, uv3).compare(compare); const mapSize = reference("mapSize", "vec2", shadow2).setGroup(renderGroup); const texelSize = vec2(1).div(mapSize); const dx = texelSize.x; const dy = texelSize.y; const uv2 = shadowCoord.xy; const f = fract(uv2.mul(mapSize).add(0.5)); uv2.subAssign(f.mul(texelSize)); return add4( depthCompare(uv2, shadowCoord.z), depthCompare(uv2.add(vec2(dx, 0)), shadowCoord.z), depthCompare(uv2.add(vec2(0, dy)), shadowCoord.z), depthCompare(uv2.add(texelSize), shadowCoord.z), mix( depthCompare(uv2.add(vec2(dx.negate(), 0)), shadowCoord.z), depthCompare(uv2.add(vec2(dx.mul(2), 0)), shadowCoord.z), f.x ), mix( depthCompare(uv2.add(vec2(dx.negate(), dy)), shadowCoord.z), depthCompare(uv2.add(vec2(dx.mul(2), dy)), shadowCoord.z), f.x ), mix( depthCompare(uv2.add(vec2(0, dy.negate())), shadowCoord.z), depthCompare(uv2.add(vec2(0, dy.mul(2))), shadowCoord.z), f.y ), mix( depthCompare(uv2.add(vec2(dx, dy.negate())), shadowCoord.z), depthCompare(uv2.add(vec2(dx, dy.mul(2))), shadowCoord.z), f.y ), mix( mix( depthCompare(uv2.add(vec2(dx.negate(), dy.negate())), shadowCoord.z), depthCompare(uv2.add(vec2(dx.mul(2), dy.negate())), shadowCoord.z), f.x ), mix( depthCompare(uv2.add(vec2(dx.negate(), dy.mul(2))), shadowCoord.z), depthCompare(uv2.add(vec2(dx.mul(2), dy.mul(2))), shadowCoord.z), f.x ), f.y ) ).mul(1 / 9); }); var VSMShadowMapNode = Fn(({ depthTexture, shadowCoord }) => { const occlusion = float(1).toVar(); const distribution = texture(depthTexture).uv(shadowCoord.xy).rg; const hardShadow = step(shadowCoord.z, distribution.x); If(hardShadow.notEqual(float(1)), () => { const distance2 = shadowCoord.z.sub(distribution.x); const variance = max$1(0, distribution.y.mul(distribution.y)); let softnessProbability = variance.div(variance.add(distance2.mul(distance2))); softnessProbability = clamp2(sub(softnessProbability, 0.3).div(0.95 - 0.3)); occlusion.assign(clamp2(max$1(hardShadow, softnessProbability))); }); return occlusion; }); var VSMPassVertical = Fn(({ samples, radius, size, shadowPass }) => { const mean = float(0).toVar(); const squaredMean = float(0).toVar(); const uvStride = samples.lessThanEqual(float(1)).select(float(0), float(2).div(samples.sub(1))); const uvStart = samples.lessThanEqual(float(1)).select(float(0), float(-1)); Loop({ start: int(0), end: int(samples), type: "int", condition: "<" }, ({ i }) => { const uvOffset = uvStart.add(float(i).mul(uvStride)); const depth2 = shadowPass.uv(add4(screenCoordinate.xy, vec2(0, uvOffset).mul(radius)).div(size)).x; mean.addAssign(depth2); squaredMean.addAssign(depth2.mul(depth2)); }); mean.divAssign(samples); squaredMean.divAssign(samples); const std_dev = sqrt(squaredMean.sub(mean.mul(mean))); return vec2(mean, std_dev); }); var VSMPassHorizontal = Fn(({ samples, radius, size, shadowPass }) => { const mean = float(0).toVar(); const squaredMean = float(0).toVar(); const uvStride = samples.lessThanEqual(float(1)).select(float(0), float(2).div(samples.sub(1))); const uvStart = samples.lessThanEqual(float(1)).select(float(0), float(-1)); Loop({ start: int(0), end: int(samples), type: "int", condition: "<" }, ({ i }) => { const uvOffset = uvStart.add(float(i).mul(uvStride)); const distribution = shadowPass.uv(add4(screenCoordinate.xy, vec2(uvOffset, 0).mul(radius)).div(size)); mean.addAssign(distribution.x); squaredMean.addAssign(add4(distribution.y.mul(distribution.y), distribution.x.mul(distribution.x))); }); mean.divAssign(samples); squaredMean.divAssign(samples); const std_dev = sqrt(squaredMean.sub(mean.mul(mean))); return vec2(mean, std_dev); }); var _shadowFilterLib = [BasicShadowMap, PCFShadowMap2, PCFSoftShadowMap2, VSMShadowMapNode]; var _overrideMaterial = null; var _quadMesh$1 = /* @__PURE__ */ new QuadMesh(); var ShadowNode = class extends Node { static get type() { return "ShadowNode"; } constructor(light, shadow2 = null) { super(); this.light = light; this.shadow = shadow2 || light.shadow; this.shadowMap = null; this.vsmShadowMapVertical = null; this.vsmShadowMapHorizontal = null; this.vsmMaterialVertical = null; this.vsmMaterialHorizontal = null; this.updateBeforeType = NodeUpdateType.RENDER; this._node = null; this.isShadowNode = true; } setupShadow(builder) { const { object, renderer: renderer3 } = builder; if (_overrideMaterial === null) { _overrideMaterial = new NodeMaterial(); _overrideMaterial.fragmentNode = vec4(0, 0, 0, 1); _overrideMaterial.isShadowNodeMaterial = true; _overrideMaterial.name = "ShadowMaterial"; } const shadow2 = this.shadow; const shadowMapType = renderer3.shadowMap.type; const depthTexture = new DepthTexture2(shadow2.mapSize.width, shadow2.mapSize.height); depthTexture.compareFunction = LessCompare2; const shadowMap = builder.createRenderTarget(shadow2.mapSize.width, shadow2.mapSize.height); shadowMap.depthTexture = depthTexture; shadow2.camera.updateProjectionMatrix(); if (shadowMapType === VSMShadowMap2) { depthTexture.compareFunction = null; this.vsmShadowMapVertical = builder.createRenderTarget(shadow2.mapSize.width, shadow2.mapSize.height, { format: RGFormat2, type: HalfFloatType2 }); this.vsmShadowMapHorizontal = builder.createRenderTarget(shadow2.mapSize.width, shadow2.mapSize.height, { format: RGFormat2, type: HalfFloatType2 }); const shadowPassVertical = texture(depthTexture); const shadowPassHorizontal = texture(this.vsmShadowMapVertical.texture); const samples = reference("blurSamples", "float", shadow2).setGroup(renderGroup); const radius = reference("radius", "float", shadow2).setGroup(renderGroup); const size = reference("mapSize", "vec2", shadow2).setGroup(renderGroup); let material = this.vsmMaterialVertical || (this.vsmMaterialVertical = new NodeMaterial()); material.fragmentNode = VSMPassVertical({ samples, radius, size, shadowPass: shadowPassVertical }).context(builder.getSharedContext()); material.name = "VSMVertical"; material = this.vsmMaterialHorizontal || (this.vsmMaterialHorizontal = new NodeMaterial()); material.fragmentNode = VSMPassHorizontal({ samples, radius, size, shadowPass: shadowPassHorizontal }).context(builder.getSharedContext()); material.name = "VSMHorizontal"; } const shadowIntensity = reference("intensity", "float", shadow2).setGroup(renderGroup); const bias = reference("bias", "float", shadow2).setGroup(renderGroup); const normalBias = reference("normalBias", "float", shadow2).setGroup(renderGroup); const position = object.material.shadowPositionNode || positionWorld; let shadowCoord = uniform(shadow2.matrix).setGroup(renderGroup).mul(position.add(transformedNormalWorld.mul(normalBias))); let coordZ; if (shadow2.camera.isOrthographicCamera || renderer3.logarithmicDepthBuffer !== true) { shadowCoord = shadowCoord.xyz.div(shadowCoord.w); coordZ = shadowCoord.z; if (renderer3.coordinateSystem === WebGPUCoordinateSystem2) { coordZ = coordZ.mul(2).sub(1); } } else { const w = shadowCoord.w; shadowCoord = shadowCoord.xy.div(w); const cameraNearLocal = uniform("float").onRenderUpdate(() => shadow2.camera.near); const cameraFarLocal = uniform("float").onRenderUpdate(() => shadow2.camera.far); coordZ = perspectiveDepthToLogarithmicDepth(w, cameraNearLocal, cameraFarLocal); } shadowCoord = vec3( shadowCoord.x, shadowCoord.y.oneMinus(), // follow webgpu standards coordZ.add(bias) ); const frustumTest = shadowCoord.x.greaterThanEqual(0).and(shadowCoord.x.lessThanEqual(1)).and(shadowCoord.y.greaterThanEqual(0)).and(shadowCoord.y.lessThanEqual(1)).and(shadowCoord.z.lessThanEqual(1)); const filterFn = shadow2.filterNode || _shadowFilterLib[renderer3.shadowMap.type] || null; if (filterFn === null) { throw new Error("THREE.WebGPURenderer: Shadow map type not supported yet."); } const shadowColor = texture(shadowMap.texture, shadowCoord); const shadowNode = frustumTest.select(filterFn({ depthTexture: shadowMapType === VSMShadowMap2 ? this.vsmShadowMapHorizontal.texture : depthTexture, shadowCoord, shadow: shadow2 }), float(1)); this.shadowMap = shadowMap; this.shadow.map = shadowMap; return mix(1, shadowNode.rgb.mix(shadowColor, 1), shadowIntensity.mul(shadowColor.a)); } setup(builder) { if (builder.renderer.shadowMap.enabled === false) return; return this._node !== null ? this._node : this._node = this.setupShadow(builder); } updateShadow(frame2) { const { shadowMap, light, shadow: shadow2 } = this; const { renderer: renderer3, scene: scene3, camera: camera3 } = frame2; const shadowType = renderer3.shadowMap.type; const depthVersion = shadowMap.depthTexture.version; this._depthVersionCached = depthVersion; const currentOverrideMaterial = scene3.overrideMaterial; scene3.overrideMaterial = _overrideMaterial; shadowMap.setSize(shadow2.mapSize.width, shadow2.mapSize.height); shadow2.updateMatrices(light); shadow2.camera.layers.mask = camera3.layers.mask; const currentRenderTarget = renderer3.getRenderTarget(); const currentRenderObjectFunction = renderer3.getRenderObjectFunction(); renderer3.setRenderObjectFunction((object, ...params) => { if (object.castShadow === true || object.receiveShadow && shadowType === VSMShadowMap2) { renderer3.renderObject(object, ...params); } }); renderer3.setRenderTarget(shadowMap); renderer3.render(scene3, shadow2.camera); renderer3.setRenderObjectFunction(currentRenderObjectFunction); if (light.isPointLight !== true && shadowType === VSMShadowMap2) { this.vsmPass(renderer3); } renderer3.setRenderTarget(currentRenderTarget); scene3.overrideMaterial = currentOverrideMaterial; } vsmPass(renderer3) { const { shadow: shadow2 } = this; this.vsmShadowMapVertical.setSize(shadow2.mapSize.width, shadow2.mapSize.height); this.vsmShadowMapHorizontal.setSize(shadow2.mapSize.width, shadow2.mapSize.height); renderer3.setRenderTarget(this.vsmShadowMapVertical); _quadMesh$1.material = this.vsmMaterialVertical; _quadMesh$1.render(renderer3); renderer3.setRenderTarget(this.vsmShadowMapHorizontal); _quadMesh$1.material = this.vsmMaterialHorizontal; _quadMesh$1.render(renderer3); } dispose() { this.shadowMap.dispose(); this.shadowMap = null; if (this.vsmShadowMapVertical !== null) { this.vsmShadowMapVertical.dispose(); this.vsmShadowMapVertical = null; this.vsmMaterialVertical.dispose(); this.vsmMaterialVertical = null; } if (this.vsmShadowMapHorizontal !== null) { this.vsmShadowMapHorizontal.dispose(); this.vsmShadowMapHorizontal = null; this.vsmMaterialHorizontal.dispose(); this.vsmMaterialHorizontal = null; } this.updateBeforeType = NodeUpdateType.NONE; } updateBefore(frame2) { const { shadow: shadow2 } = this; const needsUpdate = shadow2.needsUpdate || shadow2.autoUpdate; if (needsUpdate) { this.updateShadow(frame2); if (this.shadowMap.depthTexture.version === this._depthVersionCached) { shadow2.needsUpdate = false; } } } }; var shadow = (light, shadow2) => nodeObject(new ShadowNode(light, shadow2)); var AnalyticLightNode = class extends LightingNode { static get type() { return "AnalyticLightNode"; } constructor(light = null) { super(); this.updateType = NodeUpdateType.FRAME; this.light = light; this.color = new Color2(); this.colorNode = uniform(this.color).setGroup(renderGroup); this.baseColorNode = null; this.shadowNode = null; this.shadowColorNode = null; this.isAnalyticLightNode = true; } getCacheKey() { return hash$1(super.getCacheKey(), this.light.id, this.light.castShadow ? 1 : 0); } getHash() { return this.light.uuid; } setupShadow(builder) { const { renderer: renderer3 } = builder; if (renderer3.shadowMap.enabled === false) return; let shadowColorNode = this.shadowColorNode; if (shadowColorNode === null) { const customShadowNode = this.light.shadow.shadowNode; let shadowNode; if (customShadowNode !== void 0) { shadowNode = nodeObject(customShadowNode); } else { shadowNode = shadow(this.light); } this.shadowNode = shadowNode; this.shadowColorNode = shadowColorNode = this.colorNode.mul(shadowNode); this.baseColorNode = this.colorNode; } this.colorNode = shadowColorNode; } setup(builder) { this.colorNode = this.baseColorNode || this.colorNode; if (this.light.castShadow) { if (builder.object.receiveShadow) { this.setupShadow(builder); } } else if (this.shadowNode !== null) { this.shadowNode.dispose(); } } update() { const { light } = this; this.color.copy(light.color).multiplyScalar(light.intensity); } }; var getDistanceAttenuation = /* @__PURE__ */ Fn((inputs) => { const { lightDistance, cutoffDistance, decayExponent } = inputs; const distanceFalloff = lightDistance.pow(decayExponent).max(0.01).reciprocal(); return cutoffDistance.greaterThan(0).select( distanceFalloff.mul(lightDistance.div(cutoffDistance).pow4().oneMinus().clamp().pow2()), distanceFalloff ); }); var directPointLight = Fn(({ color: color2, lightViewPosition: lightViewPosition2, cutoffDistance, decayExponent }, builder) => { const lightingModel = builder.context.lightingModel; const lVector = lightViewPosition2.sub(positionView); const lightDirection = lVector.normalize(); const lightDistance = lVector.length(); const lightAttenuation = getDistanceAttenuation({ lightDistance, cutoffDistance, decayExponent }); const lightColor = color2.mul(lightAttenuation); const reflectedLight = builder.context.reflectedLight; lightingModel.direct({ lightDirection, lightColor, reflectedLight }, builder.stack, builder); }); var PointLightNode = class extends AnalyticLightNode { static get type() { return "PointLightNode"; } constructor(light = null) { super(light); this.cutoffDistanceNode = uniform(0).setGroup(renderGroup); this.decayExponentNode = uniform(0).setGroup(renderGroup); } update(frame2) { const { light } = this; super.update(frame2); this.cutoffDistanceNode.value = light.distance; this.decayExponentNode.value = light.decay; } setup() { directPointLight({ color: this.colorNode, lightViewPosition: lightViewPosition(this.light), cutoffDistance: this.cutoffDistanceNode, decayExponent: this.decayExponentNode }).append(); } }; var getShIrradianceAt = /* @__PURE__ */ Fn(([normal2, shCoefficients]) => { const x2 = normal2.x, y2 = normal2.y, z2 = normal2.z; let result = shCoefficients.element(0).mul(0.886227); result = result.add(shCoefficients.element(1).mul(2 * 0.511664).mul(y2)); result = result.add(shCoefficients.element(2).mul(2 * 0.511664).mul(z2)); result = result.add(shCoefficients.element(3).mul(2 * 0.511664).mul(x2)); result = result.add(shCoefficients.element(4).mul(2 * 0.429043).mul(x2).mul(y2)); result = result.add(shCoefficients.element(5).mul(2 * 0.429043).mul(y2).mul(z2)); result = result.add(shCoefficients.element(6).mul(z2.mul(z2).mul(0.743125).sub(0.247708))); result = result.add(shCoefficients.element(7).mul(2 * 0.429043).mul(x2).mul(z2)); result = result.add(shCoefficients.element(8).mul(0.429043).mul(mul(x2, x2).sub(mul(y2, y2)))); return result; }); var _clearColor$1 = /* @__PURE__ */ new Color4(); var Background = class extends DataMap { constructor(renderer3, nodes) { super(); this.renderer = renderer3; this.nodes = nodes; } update(scene3, renderList, renderContext) { const renderer3 = this.renderer; const background = this.nodes.getBackgroundNode(scene3) || scene3.background; let forceClear = false; if (background === null) { renderer3._clearColor.getRGB(_clearColor$1, LinearSRGBColorSpace2); _clearColor$1.a = renderer3._clearColor.a; } else if (background.isColor === true) { background.getRGB(_clearColor$1, LinearSRGBColorSpace2); _clearColor$1.a = 1; forceClear = true; } else if (background.isNode === true) { const sceneData = this.get(scene3); const backgroundNode = background; _clearColor$1.copy(renderer3._clearColor); let backgroundMesh = sceneData.backgroundMesh; if (backgroundMesh === void 0) { const backgroundMeshNode = context(vec4(backgroundNode).mul(backgroundIntensity), { // @TODO: Add Texture2D support using node context getUV: () => backgroundRotation.mul(normalWorld), getTextureLevel: () => backgroundBlurriness }); let viewProj = modelViewProjection(); viewProj = viewProj.setZ(viewProj.w); const nodeMaterial = new NodeMaterial(); nodeMaterial.name = "Background.material"; nodeMaterial.side = BackSide2; nodeMaterial.depthTest = false; nodeMaterial.depthWrite = false; nodeMaterial.fog = false; nodeMaterial.lights = false; nodeMaterial.vertexNode = viewProj; nodeMaterial.colorNode = backgroundMeshNode; sceneData.backgroundMeshNode = backgroundMeshNode; sceneData.backgroundMesh = backgroundMesh = new Mesh2(new SphereGeometry2(1, 32, 32), nodeMaterial); backgroundMesh.frustumCulled = false; backgroundMesh.name = "Background.mesh"; backgroundMesh.onBeforeRender = function(renderer4, scene4, camera3) { this.matrixWorld.copyPosition(camera3.matrixWorld); }; } const backgroundCacheKey = backgroundNode.getCacheKey(); if (sceneData.backgroundCacheKey !== backgroundCacheKey) { sceneData.backgroundMeshNode.node = vec4(backgroundNode).mul(backgroundIntensity); sceneData.backgroundMeshNode.needsUpdate = true; backgroundMesh.material.needsUpdate = true; sceneData.backgroundCacheKey = backgroundCacheKey; } renderList.unshift(backgroundMesh, backgroundMesh.geometry, backgroundMesh.material, 0, 0, null); } else { console.error("THREE.Renderer: Unsupported background configuration.", background); } if (renderer3.autoClear === true || forceClear === true) { const clearColorValue = renderContext.clearColorValue; clearColorValue.r = _clearColor$1.r; clearColorValue.g = _clearColor$1.g; clearColorValue.b = _clearColor$1.b; clearColorValue.a = _clearColor$1.a; if (renderer3.backend.isWebGLBackend === true || renderer3.alpha === true) { clearColorValue.r *= clearColorValue.a; clearColorValue.g *= clearColorValue.a; clearColorValue.b *= clearColorValue.a; } renderContext.depthClearValue = renderer3._clearDepth; renderContext.stencilClearValue = renderer3._clearStencil; renderContext.clearColor = renderer3.autoClearColor === true; renderContext.clearDepth = renderer3.autoClearDepth === true; renderContext.clearStencil = renderer3.autoClearStencil === true; } else { renderContext.clearColor = false; renderContext.clearDepth = false; renderContext.clearStencil = false; } } }; var _id$5 = 0; var BindGroup = class { constructor(name = "", bindings = [], index5 = 0, bindingsReference = []) { this.name = name; this.bindings = bindings; this.index = index5; this.bindingsReference = bindingsReference; this.id = _id$5++; } }; var NodeBuilderState = class { constructor(vertexShader, fragmentShader, computeShader, nodeAttributes, bindings, updateNodes, updateBeforeNodes, updateAfterNodes, monitor, transforms = []) { this.vertexShader = vertexShader; this.fragmentShader = fragmentShader; this.computeShader = computeShader; this.transforms = transforms; this.nodeAttributes = nodeAttributes; this.bindings = bindings; this.updateNodes = updateNodes; this.updateBeforeNodes = updateBeforeNodes; this.updateAfterNodes = updateAfterNodes; this.monitor = monitor; this.usedTimes = 0; } createBindings() { const bindings = []; for (const instanceGroup of this.bindings) { const shared = instanceGroup.bindings[0].groupNode.shared; if (shared !== true) { const bindingsGroup = new BindGroup(instanceGroup.name, [], instanceGroup.index, instanceGroup); bindings.push(bindingsGroup); for (const instanceBinding of instanceGroup.bindings) { bindingsGroup.bindings.push(instanceBinding.clone()); } } else { bindings.push(instanceGroup); } } return bindings; } }; var NodeAttribute = class { constructor(name, type, node = null) { this.isNodeAttribute = true; this.name = name; this.type = type; this.node = node; } }; var NodeUniform = class { constructor(name, type, node) { this.isNodeUniform = true; this.name = name; this.type = type; this.node = node.getSelf(); } get value() { return this.node.value; } set value(val) { this.node.value = val; } get id() { return this.node.id; } get groupNode() { return this.node.groupNode; } }; var NodeVar = class { constructor(name, type) { this.isNodeVar = true; this.name = name; this.type = type; } }; var NodeVarying = class extends NodeVar { constructor(name, type) { super(name, type); this.needsInterpolation = false; this.isNodeVarying = true; } }; var NodeCode = class { constructor(name, type, code = "") { this.name = name; this.type = type; this.code = code; Object.defineProperty(this, "isNodeCode", { value: true }); } }; var id = 0; var NodeCache = class { constructor(parent = null) { this.id = id++; this.nodesData = /* @__PURE__ */ new WeakMap(); this.parent = parent; } getData(node) { let data = this.nodesData.get(node); if (data === void 0 && this.parent !== null) { data = this.parent.getData(node); } return data; } setData(node, data) { this.nodesData.set(node, data); } }; var Uniform = class { constructor(name, value) { this.name = name; this.value = value; this.boundary = 0; this.itemSize = 0; this.offset = 0; } setValue(value) { this.value = value; } getValue() { return this.value; } }; var NumberUniform = class extends Uniform { constructor(name, value = 0) { super(name, value); this.isNumberUniform = true; this.boundary = 4; this.itemSize = 1; } }; var Vector2Uniform = class extends Uniform { constructor(name, value = new Vector22()) { super(name, value); this.isVector2Uniform = true; this.boundary = 8; this.itemSize = 2; } }; var Vector3Uniform = class extends Uniform { constructor(name, value = new Vector32()) { super(name, value); this.isVector3Uniform = true; this.boundary = 16; this.itemSize = 3; } }; var Vector4Uniform = class extends Uniform { constructor(name, value = new Vector42()) { super(name, value); this.isVector4Uniform = true; this.boundary = 16; this.itemSize = 4; } }; var ColorUniform = class extends Uniform { constructor(name, value = new Color2()) { super(name, value); this.isColorUniform = true; this.boundary = 16; this.itemSize = 3; } }; var Matrix3Uniform = class extends Uniform { constructor(name, value = new Matrix32()) { super(name, value); this.isMatrix3Uniform = true; this.boundary = 48; this.itemSize = 12; } }; var Matrix4Uniform = class extends Uniform { constructor(name, value = new Matrix42()) { super(name, value); this.isMatrix4Uniform = true; this.boundary = 64; this.itemSize = 16; } }; var NumberNodeUniform = class extends NumberUniform { constructor(nodeUniform) { super(nodeUniform.name, nodeUniform.value); this.nodeUniform = nodeUniform; } getValue() { return this.nodeUniform.value; } }; var Vector2NodeUniform = class extends Vector2Uniform { constructor(nodeUniform) { super(nodeUniform.name, nodeUniform.value); this.nodeUniform = nodeUniform; } getValue() { return this.nodeUniform.value; } }; var Vector3NodeUniform = class extends Vector3Uniform { constructor(nodeUniform) { super(nodeUniform.name, nodeUniform.value); this.nodeUniform = nodeUniform; } getValue() { return this.nodeUniform.value; } }; var Vector4NodeUniform = class extends Vector4Uniform { constructor(nodeUniform) { super(nodeUniform.name, nodeUniform.value); this.nodeUniform = nodeUniform; } getValue() { return this.nodeUniform.value; } }; var ColorNodeUniform = class extends ColorUniform { constructor(nodeUniform) { super(nodeUniform.name, nodeUniform.value); this.nodeUniform = nodeUniform; } getValue() { return this.nodeUniform.value; } }; var Matrix3NodeUniform = class extends Matrix3Uniform { constructor(nodeUniform) { super(nodeUniform.name, nodeUniform.value); this.nodeUniform = nodeUniform; } getValue() { return this.nodeUniform.value; } }; var Matrix4NodeUniform = class extends Matrix4Uniform { constructor(nodeUniform) { super(nodeUniform.name, nodeUniform.value); this.nodeUniform = nodeUniform; } getValue() { return this.nodeUniform.value; } }; var LOD_MIN2 = 4; var EXTRA_LOD_SIGMA2 = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; var MAX_SAMPLES2 = 20; var _flatCamera2 = /* @__PURE__ */ new OrthographicCamera2(-1, 1, 1, -1, 0, 1); var _cubeCamera = /* @__PURE__ */ new PerspectiveCamera2(90, 1); var _clearColor2 = /* @__PURE__ */ new Color2(); var _oldTarget2 = null; var _oldActiveCubeFace2 = 0; var _oldActiveMipmapLevel2 = 0; var PHI2 = (1 + Math.sqrt(5)) / 2; var INV_PHI2 = 1 / PHI2; var _axisDirections2 = [ /* @__PURE__ */ new Vector32(-PHI2, INV_PHI2, 0), /* @__PURE__ */ new Vector32(PHI2, INV_PHI2, 0), /* @__PURE__ */ new Vector32(-INV_PHI2, 0, PHI2), /* @__PURE__ */ new Vector32(INV_PHI2, 0, PHI2), /* @__PURE__ */ new Vector32(0, PHI2, -INV_PHI2), /* @__PURE__ */ new Vector32(0, PHI2, INV_PHI2), /* @__PURE__ */ new Vector32(-1, 1, -1), /* @__PURE__ */ new Vector32(1, 1, -1), /* @__PURE__ */ new Vector32(-1, 1, 1), /* @__PURE__ */ new Vector32(1, 1, 1) ]; var _faceLib = [ 3, 1, 5, 0, 4, 2 ]; var direction = getDirection(uv(), attribute("faceIndex")).normalize(); var outputDirection = vec3(direction.x, direction.y.negate(), direction.z); var PMREMGenerator2 = class { constructor(renderer3) { this._renderer = renderer3; this._pingPongRenderTarget = null; this._lodMax = 0; this._cubeSize = 0; this._lodPlanes = []; this._sizeLods = []; this._sigmas = []; this._lodMeshes = []; this._blurMaterial = null; this._cubemapMaterial = null; this._equirectMaterial = null; this._backgroundBox = null; } /** * Generates a PMREM from a supplied Scene, which can be faster than using an * image if networking bandwidth is low. Optional sigma specifies a blur radius * in radians to be applied to the scene before PMREM generation. Optional near * and far planes ensure the scene is rendered in its entirety (the cubeCamera * is placed at the origin). */ fromScene(scene3, sigma = 0, near = 0.1, far = 100) { _oldTarget2 = this._renderer.getRenderTarget(); _oldActiveCubeFace2 = this._renderer.getActiveCubeFace(); _oldActiveMipmapLevel2 = this._renderer.getActiveMipmapLevel(); this._setSize(256); const cubeUVRenderTarget = this._allocateTargets(); cubeUVRenderTarget.depthBuffer = true; this._sceneToCubeUV(scene3, near, far, cubeUVRenderTarget); if (sigma > 0) { this._blur(cubeUVRenderTarget, 0, 0, sigma); } this._applyPMREM(cubeUVRenderTarget); this._cleanup(cubeUVRenderTarget); return cubeUVRenderTarget; } /** * Generates a PMREM from an equirectangular texture, which can be either LDR * or HDR. The ideal input image size is 1k (1024 x 512), * as this matches best with the 256 x 256 cubemap output. */ fromEquirectangular(equirectangular, renderTarget = null) { return this._fromTexture(equirectangular, renderTarget); } /** * Generates a PMREM from an cubemap texture, which can be either LDR * or HDR. The ideal input cube size is 256 x 256, * as this matches best with the 256 x 256 cubemap output. */ fromCubemap(cubemap, renderTarget = null) { return this._fromTexture(cubemap, renderTarget); } /** * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during * your texture's network fetch for increased concurrency. */ async compileCubemapShader() { if (this._cubemapMaterial === null) { this._cubemapMaterial = _getCubemapMaterial2(); await this._compileMaterial(this._cubemapMaterial); } } /** * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during * your texture's network fetch for increased concurrency. */ async compileEquirectangularShader() { if (this._equirectMaterial === null) { this._equirectMaterial = _getEquirectMaterial2(); await this._compileMaterial(this._equirectMaterial); } } /** * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on * one of them will cause any others to also become unusable. */ dispose() { this._dispose(); if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); if (this._backgroundBox !== null) { this._backgroundBox.geometry.dispose(); this._backgroundBox.material.dispose(); } } // private interface _setSize(cubeSize) { this._lodMax = Math.floor(Math.log2(cubeSize)); this._cubeSize = Math.pow(2, this._lodMax); } _dispose() { if (this._blurMaterial !== null) this._blurMaterial.dispose(); if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); for (let i = 0; i < this._lodPlanes.length; i++) { this._lodPlanes[i].dispose(); } } _cleanup(outputTarget) { this._renderer.setRenderTarget(_oldTarget2, _oldActiveCubeFace2, _oldActiveMipmapLevel2); outputTarget.scissorTest = false; _setViewport2(outputTarget, 0, 0, outputTarget.width, outputTarget.height); } _fromTexture(texture2, renderTarget) { if (texture2.mapping === CubeReflectionMapping2 || texture2.mapping === CubeRefractionMapping2) { this._setSize(texture2.image.length === 0 ? 16 : texture2.image[0].width || texture2.image[0].image.width); } else { this._setSize(texture2.image.width / 4); } _oldTarget2 = this._renderer.getRenderTarget(); _oldActiveCubeFace2 = this._renderer.getActiveCubeFace(); _oldActiveMipmapLevel2 = this._renderer.getActiveMipmapLevel(); const cubeUVRenderTarget = renderTarget || this._allocateTargets(); this._textureToCubeUV(texture2, cubeUVRenderTarget); this._applyPMREM(cubeUVRenderTarget); this._cleanup(cubeUVRenderTarget); return cubeUVRenderTarget; } _allocateTargets() { const width = 3 * Math.max(this._cubeSize, 16 * 7); const height = 4 * this._cubeSize; const params = { magFilter: LinearFilter2, minFilter: LinearFilter2, generateMipmaps: false, type: HalfFloatType2, format: RGBAFormat2, colorSpace: LinearSRGBColorSpace2 //depthBuffer: false }; const cubeUVRenderTarget = _createRenderTarget2(width, height, params); if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width || this._pingPongRenderTarget.height !== height) { if (this._pingPongRenderTarget !== null) { this._dispose(); } this._pingPongRenderTarget = _createRenderTarget2(width, height, params); const { _lodMax } = this; ({ sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas, lodMeshes: this._lodMeshes } = _createPlanes2(_lodMax)); this._blurMaterial = _getBlurShader2(_lodMax, width, height); } return cubeUVRenderTarget; } async _compileMaterial(material) { const tmpMesh = new Mesh2(this._lodPlanes[0], material); await this._renderer.compile(tmpMesh, _flatCamera2); } _sceneToCubeUV(scene3, near, far, cubeUVRenderTarget) { const cubeCamera = _cubeCamera; cubeCamera.near = near; cubeCamera.far = far; const upSign = [-1, 1, -1, -1, -1, -1]; const forwardSign = [1, 1, 1, -1, -1, -1]; const renderer3 = this._renderer; const originalAutoClear = renderer3.autoClear; renderer3.getClearColor(_clearColor2); renderer3.autoClear = false; let backgroundBox = this._backgroundBox; if (backgroundBox === null) { const backgroundMaterial = new MeshBasicMaterial2({ name: "PMREM.Background", side: BackSide2, depthWrite: false, depthTest: false }); backgroundBox = new Mesh2(new BoxGeometry2(), backgroundMaterial); } let useSolidColor = false; const background = scene3.background; if (background) { if (background.isColor) { backgroundBox.material.color.copy(background); scene3.background = null; useSolidColor = true; } } else { backgroundBox.material.color.copy(_clearColor2); useSolidColor = true; } renderer3.setRenderTarget(cubeUVRenderTarget); renderer3.clear(); if (useSolidColor) { renderer3.render(backgroundBox, cubeCamera); } 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]); } const size = this._cubeSize; _setViewport2(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); renderer3.render(scene3, cubeCamera); } renderer3.autoClear = originalAutoClear; scene3.background = background; } _textureToCubeUV(texture2, cubeUVRenderTarget) { const renderer3 = this._renderer; const isCubeTexture = texture2.mapping === CubeReflectionMapping2 || texture2.mapping === CubeRefractionMapping2; if (isCubeTexture) { if (this._cubemapMaterial === null) { this._cubemapMaterial = _getCubemapMaterial2(texture2); } } else { if (this._equirectMaterial === null) { this._equirectMaterial = _getEquirectMaterial2(texture2); } } const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; material.fragmentNode.value = texture2; const mesh = this._lodMeshes[0]; mesh.material = material; const size = this._cubeSize; _setViewport2(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); renderer3.setRenderTarget(cubeUVRenderTarget); renderer3.render(mesh, _flatCamera2); } _applyPMREM(cubeUVRenderTarget) { const renderer3 = this._renderer; const autoClear = renderer3.autoClear; renderer3.autoClear = false; const n = this._lodPlanes.length; for (let i = 1; i < n; i++) { const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]); const poleAxis = _axisDirections2[(n - i - 1) % _axisDirections2.length]; this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); } renderer3.autoClear = autoClear; } /** * This is a two-pass Gaussian blur for a cubemap. Normally this is done * vertically and horizontally, but this breaks down on a cube. Here we apply * the blur latitudinally (around the poles), and then longitudinally (towards * the poles) to approximate the orthogonally-separable blur. It is least * accurate at the poles, but still does a decent job. */ _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, direction2, poleAxis) { const renderer3 = this._renderer; const blurMaterial = this._blurMaterial; if (direction2 !== "latitudinal" && direction2 !== "longitudinal") { console.error("blur direction must be either latitudinal or longitudinal!"); } const STANDARD_DEVIATIONS = 3; const blurMesh = this._lodMeshes[lodOut]; blurMesh.material = blurMaterial; const blurUniforms = blurMaterial.uniforms; const pixels = this._sizeLods[lodIn] - 1; const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES2 - 1); const sigmaPixels = sigmaRadians / radiansPerPixel; const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES2; if (samples > MAX_SAMPLES2) { console.warn(`sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${samples} samples when the maximum is set to ${MAX_SAMPLES2}`); } const weights = []; let sum = 0; for (let i = 0; i < MAX_SAMPLES2; ++i) { const x3 = i / sigmaPixels; const weight = Math.exp(-x3 * x3 / 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; } targetIn.texture.frame = (targetIn.texture.frame || 0) + 1; blurUniforms.envMap.value = targetIn.texture; blurUniforms.samples.value = samples; blurUniforms.weights.array = weights; blurUniforms.latitudinal.value = direction2 === "latitudinal" ? 1 : 0; if (poleAxis) { blurUniforms.poleAxis.value = poleAxis; } const { _lodMax } = this; blurUniforms.dTheta.value = radiansPerPixel; blurUniforms.mipInt.value = _lodMax - lodIn; const outputSize = this._sizeLods[lodOut]; const x2 = 3 * outputSize * (lodOut > _lodMax - LOD_MIN2 ? lodOut - _lodMax + LOD_MIN2 : 0); const y2 = 4 * (this._cubeSize - outputSize); _setViewport2(targetOut, x2, y2, 3 * outputSize, 2 * outputSize); renderer3.setRenderTarget(targetOut); renderer3.render(blurMesh, _flatCamera2); } }; function _createPlanes2(lodMax) { const lodPlanes = []; const sizeLods = []; const sigmas = []; const lodMeshes = []; let lod = lodMax; const totalLods = lodMax - LOD_MIN2 + 1 + EXTRA_LOD_SIGMA2.length; for (let i = 0; i < totalLods; i++) { const sizeLod = Math.pow(2, lod); sizeLods.push(sizeLod); let sigma = 1 / sizeLod; if (i > lodMax - LOD_MIN2) { sigma = EXTRA_LOD_SIGMA2[i - lodMax + LOD_MIN2 - 1]; } else if (i === 0) { sigma = 0; } sigmas.push(sigma); const texelSize = 1 / (sizeLod - 2); const min2 = -texelSize; const max2 = 1 + texelSize; const uv1 = [min2, min2, max2, min2, max2, max2, min2, min2, max2, max2, min2, max2]; const cubeFaces = 6; const vertices = 6; const positionSize = 3; const uvSize = 2; const faceIndexSize = 1; const position = new Float32Array(positionSize * vertices * cubeFaces); const uv2 = new Float32Array(uvSize * vertices * cubeFaces); const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); for (let face = 0; face < cubeFaces; face++) { const x2 = face % 3 * 2 / 3 - 1; const y2 = face > 2 ? 0 : -1; const coordinates = [ x2, y2, 0, x2 + 2 / 3, y2, 0, x2 + 2 / 3, y2 + 1, 0, x2, y2, 0, x2 + 2 / 3, y2 + 1, 0, x2, y2 + 1, 0 ]; const faceIdx = _faceLib[face]; position.set(coordinates, positionSize * vertices * faceIdx); uv2.set(uv1, uvSize * vertices * faceIdx); const fill = [faceIdx, faceIdx, faceIdx, faceIdx, faceIdx, faceIdx]; faceIndex.set(fill, faceIndexSize * vertices * faceIdx); } const planes = new BufferGeometry2(); planes.setAttribute("position", new BufferAttribute2(position, positionSize)); planes.setAttribute("uv", new BufferAttribute2(uv2, uvSize)); planes.setAttribute("faceIndex", new BufferAttribute2(faceIndex, faceIndexSize)); lodPlanes.push(planes); lodMeshes.push(new Mesh2(planes, null)); if (lod > LOD_MIN2) { lod--; } } return { lodPlanes, sizeLods, sigmas, lodMeshes }; } function _createRenderTarget2(width, height, params) { const cubeUVRenderTarget = new RenderTarget2(width, height, params); cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping2; cubeUVRenderTarget.texture.name = "PMREM.cubeUv"; cubeUVRenderTarget.texture.isPMREMTexture = true; cubeUVRenderTarget.scissorTest = true; return cubeUVRenderTarget; } function _setViewport2(target, x2, y2, width, height) { target.viewport.set(x2, y2, width, height); target.scissor.set(x2, y2, width, height); } function _getMaterial(type) { const material = new NodeMaterial(); material.depthTest = false; material.depthWrite = false; material.blending = NoBlending2; material.name = `PMREM_${type}`; return material; } function _getBlurShader2(lodMax, width, height) { const weights = uniformArray(new Array(MAX_SAMPLES2).fill(0)); const poleAxis = uniform(new Vector32(0, 1, 0)); const dTheta = uniform(0); const n = float(MAX_SAMPLES2); const latitudinal = uniform(0); const samples = uniform(1); const envMap = texture(null); const mipInt = uniform(0); const CUBEUV_TEXEL_WIDTH = float(1 / width); const CUBEUV_TEXEL_HEIGHT = float(1 / height); const CUBEUV_MAX_MIP = float(lodMax); const materialUniforms = { n, latitudinal, weights, poleAxis, outputDirection, dTheta, samples, envMap, mipInt, CUBEUV_TEXEL_WIDTH, CUBEUV_TEXEL_HEIGHT, CUBEUV_MAX_MIP }; const material = _getMaterial("blur"); material.uniforms = materialUniforms; material.fragmentNode = blur({ ...materialUniforms, latitudinal: latitudinal.equal(1) }); return material; } function _getCubemapMaterial2(envTexture) { const material = _getMaterial("cubemap"); material.fragmentNode = cubeTexture(envTexture, outputDirection); return material; } function _getEquirectMaterial2(envTexture) { const material = _getMaterial("equirect"); material.fragmentNode = texture(envTexture, equirectUV(outputDirection), 0); return material; } var rendererCache = /* @__PURE__ */ new WeakMap(); var typeFromLength = /* @__PURE__ */ new Map([ [2, "vec2"], [3, "vec3"], [4, "vec4"], [9, "mat3"], [16, "mat4"] ]); var typeFromArray = /* @__PURE__ */ new Map([ [Int8Array, "int"], [Int16Array, "int"], [Int32Array, "int"], [Uint8Array, "uint"], [Uint16Array, "uint"], [Uint32Array, "uint"], [Float32Array, "float"] ]); var toFloat = (value) => { if (/e/g.test(value)) { return String(value).replace(/\+/g, ""); } else { value = Number(value); return value + (value % 1 ? "" : ".0"); } }; var NodeBuilder = class { constructor(object, renderer3, parser) { this.object = object; this.material = object && object.material || null; this.geometry = object && object.geometry || null; this.renderer = renderer3; this.parser = parser; this.scene = null; this.camera = null; this.nodes = []; this.sequentialNodes = []; this.updateNodes = []; this.updateBeforeNodes = []; this.updateAfterNodes = []; this.hashNodes = {}; this.monitor = null; this.lightsNode = null; this.environmentNode = null; this.fogNode = null; this.clippingContext = null; this.vertexShader = null; this.fragmentShader = null; this.computeShader = null; this.flowNodes = { vertex: [], fragment: [], compute: [] }; this.flowCode = { vertex: "", fragment: "", compute: "" }; this.uniforms = { vertex: [], fragment: [], compute: [], index: 0 }; this.structs = { vertex: [], fragment: [], compute: [], index: 0 }; this.bindings = { vertex: {}, fragment: {}, compute: {} }; this.bindingsIndexes = {}; this.bindGroups = null; this.attributes = []; this.bufferAttributes = []; this.varyings = []; this.codes = {}; this.vars = {}; this.flow = { code: "" }; this.chaining = []; this.stack = stack(); this.stacks = []; this.tab = " "; this.currentFunctionNode = null; this.context = { material: this.material }; this.cache = new NodeCache(); this.globalCache = this.cache; this.flowsData = /* @__PURE__ */ new WeakMap(); this.shaderStage = null; this.buildStage = null; this.useComparisonMethod = false; } getBindGroupsCache() { let bindGroupsCache = rendererCache.get(this.renderer); if (bindGroupsCache === void 0) { bindGroupsCache = new ChainMap(); rendererCache.set(this.renderer, bindGroupsCache); } return bindGroupsCache; } createRenderTarget(width, height, options) { return new RenderTarget2(width, height, options); } createCubeRenderTarget(size, options) { return new CubeRenderTarget(size, options); } createPMREMGenerator() { return new PMREMGenerator2(this.renderer); } includes(node) { return this.nodes.includes(node); } _getBindGroup(groupName, bindings) { const bindGroupsCache = this.getBindGroupsCache(); const bindingsArray = []; let sharedGroup = true; for (const binding of bindings) { bindingsArray.push(binding); sharedGroup = sharedGroup && binding.groupNode.shared !== true; } let bindGroup; if (sharedGroup) { bindGroup = bindGroupsCache.get(bindingsArray); if (bindGroup === void 0) { bindGroup = new BindGroup(groupName, bindingsArray, this.bindingsIndexes[groupName].group, bindingsArray); bindGroupsCache.set(bindingsArray, bindGroup); } } else { bindGroup = new BindGroup(groupName, bindingsArray, this.bindingsIndexes[groupName].group, bindingsArray); } return bindGroup; } getBindGroupArray(groupName, shaderStage) { const bindings = this.bindings[shaderStage]; let bindGroup = bindings[groupName]; if (bindGroup === void 0) { if (this.bindingsIndexes[groupName] === void 0) { this.bindingsIndexes[groupName] = { binding: 0, group: Object.keys(this.bindingsIndexes).length }; } bindings[groupName] = bindGroup = []; } return bindGroup; } getBindings() { let bindingsGroups = this.bindGroups; if (bindingsGroups === null) { const groups = {}; const bindings = this.bindings; for (const shaderStage of shaderStages) { for (const groupName in bindings[shaderStage]) { const uniforms = bindings[shaderStage][groupName]; const groupUniforms = groups[groupName] || (groups[groupName] = []); groupUniforms.push(...uniforms); } } bindingsGroups = []; for (const groupName in groups) { const group = groups[groupName]; const bindingsGroup = this._getBindGroup(groupName, group); bindingsGroups.push(bindingsGroup); } this.bindGroups = bindingsGroups; } return bindingsGroups; } sortBindingGroups() { const bindingsGroups = this.getBindings(); bindingsGroups.sort((a2, b) => a2.bindings[0].groupNode.order - b.bindings[0].groupNode.order); for (let i = 0; i < bindingsGroups.length; i++) { const bindingGroup = bindingsGroups[i]; this.bindingsIndexes[bindingGroup.name].group = i; bindingGroup.index = i; } } setHashNode(node, hash) { this.hashNodes[hash] = node; } addNode(node) { if (this.nodes.includes(node) === false) { this.nodes.push(node); this.setHashNode(node, node.getHash(this)); } } addSequentialNode(node) { if (this.sequentialNodes.includes(node) === false) { this.sequentialNodes.push(node); } } buildUpdateNodes() { for (const node of this.nodes) { const updateType = node.getUpdateType(); if (updateType !== NodeUpdateType.NONE) { this.updateNodes.push(node.getSelf()); } } for (const node of this.sequentialNodes) { const updateBeforeType = node.getUpdateBeforeType(); const updateAfterType = node.getUpdateAfterType(); if (updateBeforeType !== NodeUpdateType.NONE) { this.updateBeforeNodes.push(node.getSelf()); } if (updateAfterType !== NodeUpdateType.NONE) { this.updateAfterNodes.push(node.getSelf()); } } } get currentNode() { return this.chaining[this.chaining.length - 1]; } isFilteredTexture(texture2) { return texture2.magFilter === LinearFilter2 || texture2.magFilter === LinearMipmapNearestFilter2 || texture2.magFilter === NearestMipmapLinearFilter2 || texture2.magFilter === LinearMipmapLinearFilter2 || texture2.minFilter === LinearFilter2 || texture2.minFilter === LinearMipmapNearestFilter2 || texture2.minFilter === NearestMipmapLinearFilter2 || texture2.minFilter === LinearMipmapLinearFilter2; } addChain(node) { this.chaining.push(node); } removeChain(node) { const lastChain = this.chaining.pop(); if (lastChain !== node) { throw new Error("NodeBuilder: Invalid node chaining!"); } } getMethod(method) { return method; } getNodeFromHash(hash) { return this.hashNodes[hash]; } addFlow(shaderStage, node) { this.flowNodes[shaderStage].push(node); return node; } setContext(context2) { this.context = context2; } getContext() { return this.context; } getSharedContext() { ({ ...this.context }); return this.context; } setCache(cache2) { this.cache = cache2; } getCache() { return this.cache; } getCacheFromNode(node, parent = true) { const data = this.getDataFromNode(node); if (data.cache === void 0) data.cache = new NodeCache(parent ? this.getCache() : null); return data.cache; } isAvailable() { return false; } getVertexIndex() { console.warn("Abstract function."); } getInstanceIndex() { console.warn("Abstract function."); } getDrawIndex() { console.warn("Abstract function."); } getFrontFacing() { console.warn("Abstract function."); } getFragCoord() { console.warn("Abstract function."); } isFlipY() { return false; } increaseUsage(node) { const nodeData = this.getDataFromNode(node); nodeData.usageCount = nodeData.usageCount === void 0 ? 1 : nodeData.usageCount + 1; return nodeData.usageCount; } generateTexture() { console.warn("Abstract function."); } generateTextureLod() { console.warn("Abstract function."); } generateConst(type, value = null) { if (value === null) { if (type === "float" || type === "int" || type === "uint") value = 0; else if (type === "bool") value = false; else if (type === "color") value = new Color2(); else if (type === "vec2") value = new Vector22(); else if (type === "vec3") value = new Vector32(); else if (type === "vec4") value = new Vector42(); } if (type === "float") return toFloat(value); if (type === "int") return `${Math.round(value)}`; if (type === "uint") return value >= 0 ? `${Math.round(value)}u` : "0u"; if (type === "bool") return value ? "true" : "false"; if (type === "color") return `${this.getType("vec3")}( ${toFloat(value.r)}, ${toFloat(value.g)}, ${toFloat(value.b)} )`; const typeLength = this.getTypeLength(type); const componentType = this.getComponentType(type); const generateConst = (value2) => this.generateConst(componentType, value2); if (typeLength === 2) { return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)} )`; } else if (typeLength === 3) { return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)} )`; } else if (typeLength === 4) { return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)}, ${generateConst(value.w)} )`; } else if (typeLength > 4 && value && (value.isMatrix3 || value.isMatrix4)) { return `${this.getType(type)}( ${value.elements.map(generateConst).join(", ")} )`; } else if (typeLength > 4) { return `${this.getType(type)}()`; } throw new Error(`NodeBuilder: Type '${type}' not found in generate constant attempt.`); } getType(type) { if (type === "color") return "vec3"; return type; } hasGeometryAttribute(name) { return this.geometry && this.geometry.getAttribute(name) !== void 0; } getAttribute(name, type) { const attributes = this.attributes; for (const attribute3 of attributes) { if (attribute3.name === name) { return attribute3; } } const attribute2 = new NodeAttribute(name, type); attributes.push(attribute2); return attribute2; } getPropertyName(node) { return node.name; } isVector(type) { return /vec\d/.test(type); } isMatrix(type) { return /mat\d/.test(type); } isReference(type) { return type === "void" || type === "property" || type === "sampler" || type === "texture" || type === "cubeTexture" || type === "storageTexture" || type === "depthTexture" || type === "texture3D"; } needsToWorkingColorSpace() { return false; } getComponentTypeFromTexture(texture2) { const type = texture2.type; if (texture2.isDataTexture) { if (type === IntType2) return "int"; if (type === UnsignedIntType2) return "uint"; } return "float"; } getElementType(type) { if (type === "mat2") return "vec2"; if (type === "mat3") return "vec3"; if (type === "mat4") return "vec4"; return this.getComponentType(type); } getComponentType(type) { type = this.getVectorType(type); if (type === "float" || type === "bool" || type === "int" || type === "uint") return type; const componentType = /(b|i|u|)(vec|mat)([2-4])/.exec(type); if (componentType === null) return null; if (componentType[1] === "b") return "bool"; if (componentType[1] === "i") return "int"; if (componentType[1] === "u") return "uint"; return "float"; } getVectorType(type) { if (type === "color") return "vec3"; if (type === "texture" || type === "cubeTexture" || type === "storageTexture" || type === "texture3D") return "vec4"; return type; } getTypeFromLength(length2, componentType = "float") { if (length2 === 1) return componentType; const baseType = typeFromLength.get(length2); const prefix = componentType === "float" ? "" : componentType[0]; return prefix + baseType; } getTypeFromArray(array) { return typeFromArray.get(array.constructor); } getTypeFromAttribute(attribute2) { let dataAttribute = attribute2; if (attribute2.isInterleavedBufferAttribute) dataAttribute = attribute2.data; const array = dataAttribute.array; const itemSize = attribute2.itemSize; const normalized = attribute2.normalized; let arrayType; if (!(attribute2 instanceof Float16BufferAttribute) && normalized !== true) { arrayType = this.getTypeFromArray(array); } return this.getTypeFromLength(itemSize, arrayType); } getTypeLength(type) { const vecType = this.getVectorType(type); const vecNum = /vec([2-4])/.exec(vecType); if (vecNum !== null) return Number(vecNum[1]); if (vecType === "float" || vecType === "bool" || vecType === "int" || vecType === "uint") return 1; if (/mat2/.test(type) === true) return 4; if (/mat3/.test(type) === true) return 9; if (/mat4/.test(type) === true) return 16; return 0; } getVectorFromMatrix(type) { return type.replace("mat", "vec"); } changeComponentType(type, newComponentType) { return this.getTypeFromLength(this.getTypeLength(type), newComponentType); } getIntegerType(type) { const componentType = this.getComponentType(type); if (componentType === "int" || componentType === "uint") return type; return this.changeComponentType(type, "int"); } addStack() { this.stack = stack(this.stack); this.stacks.push(getCurrentStack() || this.stack); setCurrentStack(this.stack); return this.stack; } removeStack() { const lastStack = this.stack; this.stack = lastStack.parent; setCurrentStack(this.stacks.pop()); return lastStack; } getDataFromNode(node, shaderStage = this.shaderStage, cache2 = null) { cache2 = cache2 === null ? node.isGlobal(this) ? this.globalCache : this.cache : cache2; let nodeData = cache2.getData(node); if (nodeData === void 0) { nodeData = {}; cache2.setData(node, nodeData); } if (nodeData[shaderStage] === void 0) nodeData[shaderStage] = {}; return nodeData[shaderStage]; } getNodeProperties(node, shaderStage = "any") { const nodeData = this.getDataFromNode(node, shaderStage); return nodeData.properties || (nodeData.properties = { outputNode: null }); } getBufferAttributeFromNode(node, type) { const nodeData = this.getDataFromNode(node); let bufferAttribute2 = nodeData.bufferAttribute; if (bufferAttribute2 === void 0) { const index5 = this.uniforms.index++; bufferAttribute2 = new NodeAttribute("nodeAttribute" + index5, type, node); this.bufferAttributes.push(bufferAttribute2); nodeData.bufferAttribute = bufferAttribute2; } return bufferAttribute2; } getStructTypeFromNode(node, shaderStage = this.shaderStage) { const nodeData = this.getDataFromNode(node, shaderStage); if (nodeData.structType === void 0) { const index5 = this.structs.index++; node.name = `StructType${index5}`; this.structs[shaderStage].push(node); nodeData.structType = node; } return node; } getUniformFromNode(node, type, shaderStage = this.shaderStage, name = null) { const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); let nodeUniform = nodeData.uniform; if (nodeUniform === void 0) { const index5 = this.uniforms.index++; nodeUniform = new NodeUniform(name || "nodeUniform" + index5, type, node); this.uniforms[shaderStage].push(nodeUniform); nodeData.uniform = nodeUniform; } return nodeUniform; } getVarFromNode(node, name = null, type = node.getNodeType(this), shaderStage = this.shaderStage) { const nodeData = this.getDataFromNode(node, shaderStage); let nodeVar = nodeData.variable; if (nodeVar === void 0) { const vars = this.vars[shaderStage] || (this.vars[shaderStage] = []); if (name === null) name = "nodeVar" + vars.length; nodeVar = new NodeVar(name, type); vars.push(nodeVar); nodeData.variable = nodeVar; } return nodeVar; } getVaryingFromNode(node, name = null, type = node.getNodeType(this)) { const nodeData = this.getDataFromNode(node, "any"); let nodeVarying = nodeData.varying; if (nodeVarying === void 0) { const varyings = this.varyings; const index5 = varyings.length; if (name === null) name = "nodeVarying" + index5; nodeVarying = new NodeVarying(name, type); varyings.push(nodeVarying); nodeData.varying = nodeVarying; } return nodeVarying; } getCodeFromNode(node, type, shaderStage = this.shaderStage) { const nodeData = this.getDataFromNode(node); let nodeCode = nodeData.code; if (nodeCode === void 0) { const codes = this.codes[shaderStage] || (this.codes[shaderStage] = []); const index5 = codes.length; nodeCode = new NodeCode("nodeCode" + index5, type); codes.push(nodeCode); nodeData.code = nodeCode; } return nodeCode; } addFlowCodeHierarchy(node, nodeBlock) { const { flowCodes, flowCodeBlock } = this.getDataFromNode(node); let needsFlowCode = true; let nodeBlockHierarchy = nodeBlock; while (nodeBlockHierarchy) { if (flowCodeBlock.get(nodeBlockHierarchy) === true) { needsFlowCode = false; break; } nodeBlockHierarchy = this.getDataFromNode(nodeBlockHierarchy).parentNodeBlock; } if (needsFlowCode) { for (const flowCode of flowCodes) { this.addLineFlowCode(flowCode); } } } addLineFlowCodeBlock(node, code, nodeBlock) { const nodeData = this.getDataFromNode(node); const flowCodes = nodeData.flowCodes || (nodeData.flowCodes = []); const codeBlock = nodeData.flowCodeBlock || (nodeData.flowCodeBlock = /* @__PURE__ */ new WeakMap()); flowCodes.push(code); codeBlock.set(nodeBlock, true); } addLineFlowCode(code, node = null) { if (code === "") return this; if (node !== null && this.context.nodeBlock) { this.addLineFlowCodeBlock(node, code, this.context.nodeBlock); } code = this.tab + code; if (!/;\s*$/.test(code)) { code = code + ";\n"; } this.flow.code += code; return this; } addFlowCode(code) { this.flow.code += code; return this; } addFlowTab() { this.tab += " "; return this; } removeFlowTab() { this.tab = this.tab.slice(0, -1); return this; } getFlowData(node) { return this.flowsData.get(node); } flowNode(node) { const output2 = node.getNodeType(this); const flowData = this.flowChildNode(node, output2); this.flowsData.set(node, flowData); return flowData; } buildFunctionNode(shaderNode) { const fn = new FunctionNode(); const previous = this.currentFunctionNode; this.currentFunctionNode = fn; fn.code = this.buildFunctionCode(shaderNode); this.currentFunctionNode = previous; return fn; } flowShaderNode(shaderNode) { const layout = shaderNode.layout; const inputs = { [Symbol.iterator]() { let index5 = 0; const values = Object.values(this); return { next: () => ({ value: values[index5], done: index5++ >= values.length }) }; } }; for (const input of layout.inputs) { inputs[input.name] = new ParameterNode(input.type, input.name); } shaderNode.layout = null; const callNode = shaderNode.call(inputs); const flowData = this.flowStagesNode(callNode, layout.type); shaderNode.layout = layout; return flowData; } flowStagesNode(node, output2 = null) { const previousFlow = this.flow; const previousVars = this.vars; const previousCache = this.cache; const previousBuildStage = this.buildStage; const previousStack = this.stack; const flow = { code: "" }; this.flow = flow; this.vars = {}; this.cache = new NodeCache(); this.stack = stack(); for (const buildStage of defaultBuildStages) { this.setBuildStage(buildStage); flow.result = node.build(this, output2); } flow.vars = this.getVars(this.shaderStage); this.flow = previousFlow; this.vars = previousVars; this.cache = previousCache; this.stack = previousStack; this.setBuildStage(previousBuildStage); return flow; } getFunctionOperator() { return null; } flowChildNode(node, output2 = null) { const previousFlow = this.flow; const flow = { code: "" }; this.flow = flow; flow.result = node.build(this, output2); this.flow = previousFlow; return flow; } flowNodeFromShaderStage(shaderStage, node, output2 = null, propertyName = null) { const previousShaderStage = this.shaderStage; this.setShaderStage(shaderStage); const flowData = this.flowChildNode(node, output2); if (propertyName !== null) { flowData.code += `${this.tab + propertyName} = ${flowData.result}; `; } this.flowCode[shaderStage] = this.flowCode[shaderStage] + flowData.code; this.setShaderStage(previousShaderStage); return flowData; } getAttributesArray() { return this.attributes.concat(this.bufferAttributes); } getAttributes() { console.warn("Abstract function."); } getVaryings() { console.warn("Abstract function."); } getVar(type, name) { return `${this.getType(type)} ${name}`; } getVars(shaderStage) { let snippet = ""; const vars = this.vars[shaderStage]; if (vars !== void 0) { for (const variable of vars) { snippet += `${this.getVar(variable.type, variable.name)}; `; } } return snippet; } getUniforms() { console.warn("Abstract function."); } getCodes(shaderStage) { const codes = this.codes[shaderStage]; let code = ""; if (codes !== void 0) { for (const nodeCode of codes) { code += nodeCode.code + "\n"; } } return code; } getHash() { return this.vertexShader + this.fragmentShader + this.computeShader; } setShaderStage(shaderStage) { this.shaderStage = shaderStage; } getShaderStage() { return this.shaderStage; } setBuildStage(buildStage) { this.buildStage = buildStage; } getBuildStage() { return this.buildStage; } buildCode() { console.warn("Abstract function."); } build() { const { object, material, renderer: renderer3 } = this; if (material !== null) { let nodeMaterial = renderer3.library.fromMaterial(material); if (nodeMaterial === null) { console.error(`NodeMaterial: Material "${material.type}" is not compatible.`); nodeMaterial = new NodeMaterial(); } nodeMaterial.build(this); } else { this.addFlow("compute", object); } for (const buildStage of defaultBuildStages) { this.setBuildStage(buildStage); if (this.context.vertex && this.context.vertex.isNode) { this.flowNodeFromShaderStage("vertex", this.context.vertex); } for (const shaderStage of shaderStages) { this.setShaderStage(shaderStage); const flowNodes = this.flowNodes[shaderStage]; for (const node of flowNodes) { if (buildStage === "generate") { this.flowNode(node); } else { node.build(this); } } } } this.setBuildStage(null); this.setShaderStage(null); this.buildCode(); this.buildUpdateNodes(); return this; } getNodeUniform(uniformNode, type) { if (type === "float" || type === "int" || type === "uint") return new NumberNodeUniform(uniformNode); if (type === "vec2" || type === "ivec2" || type === "uvec2") return new Vector2NodeUniform(uniformNode); if (type === "vec3" || type === "ivec3" || type === "uvec3") return new Vector3NodeUniform(uniformNode); if (type === "vec4" || type === "ivec4" || type === "uvec4") return new Vector4NodeUniform(uniformNode); if (type === "color") return new ColorNodeUniform(uniformNode); if (type === "mat3") return new Matrix3NodeUniform(uniformNode); if (type === "mat4") return new Matrix4NodeUniform(uniformNode); throw new Error(`Uniform "${type}" not declared.`); } createNodeMaterial(type = "NodeMaterial") { throw new Error(`THREE.NodeBuilder: createNodeMaterial() was deprecated. Use new ${type}() instead.`); } format(snippet, fromType, toType) { fromType = this.getVectorType(fromType); toType = this.getVectorType(toType); if (fromType === toType || toType === null || this.isReference(toType)) { return snippet; } const fromTypeLength = this.getTypeLength(fromType); const toTypeLength = this.getTypeLength(toType); if (fromTypeLength === 16 && toTypeLength === 9) { return `${this.getType(toType)}(${snippet}[0].xyz, ${snippet}[1].xyz, ${snippet}[2].xyz)`; } if (fromTypeLength === 9 && toTypeLength === 4) { return `${this.getType(toType)}(${snippet}[0].xy, ${snippet}[1].xy)`; } if (fromTypeLength > 4) { return snippet; } if (toTypeLength > 4 || toTypeLength === 0) { return snippet; } if (fromTypeLength === toTypeLength) { return `${this.getType(toType)}( ${snippet} )`; } if (fromTypeLength > toTypeLength) { return this.format(`${snippet}.${"xyz".slice(0, toTypeLength)}`, this.getTypeFromLength(toTypeLength, this.getComponentType(fromType)), toType); } if (toTypeLength === 4 && fromTypeLength > 1) { return `${this.getType(toType)}( ${this.format(snippet, fromType, "vec3")}, 1.0 )`; } if (fromTypeLength === 2) { return `${this.getType(toType)}( ${this.format(snippet, fromType, "vec2")}, 0.0 )`; } if (fromTypeLength === 1 && toTypeLength > 1 && fromType !== this.getComponentType(toType)) { snippet = `${this.getType(this.getComponentType(toType))}( ${snippet} )`; } return `${this.getType(toType)}( ${snippet} )`; } getSignature() { return `// Three.js r${REVISION2} - Node System `; } }; var NodeFrame = class { constructor() { this.time = 0; this.deltaTime = 0; this.frameId = 0; this.renderId = 0; this.startTime = null; this.updateMap = /* @__PURE__ */ new WeakMap(); this.updateBeforeMap = /* @__PURE__ */ new WeakMap(); this.updateAfterMap = /* @__PURE__ */ new WeakMap(); this.renderer = null; this.material = null; this.camera = null; this.object = null; this.scene = null; } _getMaps(referenceMap, nodeRef) { let maps = referenceMap.get(nodeRef); if (maps === void 0) { maps = { renderMap: /* @__PURE__ */ new WeakMap(), frameMap: /* @__PURE__ */ new WeakMap() }; referenceMap.set(nodeRef, maps); } return maps; } updateBeforeNode(node) { const updateType = node.getUpdateBeforeType(); const reference2 = node.updateReference(this); if (updateType === NodeUpdateType.FRAME) { const { frameMap } = this._getMaps(this.updateBeforeMap, reference2); if (frameMap.get(reference2) !== this.frameId) { if (node.updateBefore(this) !== false) { frameMap.set(reference2, this.frameId); } } } else if (updateType === NodeUpdateType.RENDER) { const { renderMap } = this._getMaps(this.updateBeforeMap, reference2); if (renderMap.get(reference2) !== this.renderId) { if (node.updateBefore(this) !== false) { renderMap.set(reference2, this.renderId); } } } else if (updateType === NodeUpdateType.OBJECT) { node.updateBefore(this); } } updateAfterNode(node) { const updateType = node.getUpdateAfterType(); const reference2 = node.updateReference(this); if (updateType === NodeUpdateType.FRAME) { const { frameMap } = this._getMaps(this.updateAfterMap, reference2); if (frameMap.get(reference2) !== this.frameId) { if (node.updateAfter(this) !== false) { frameMap.set(reference2, this.frameId); } } } else if (updateType === NodeUpdateType.RENDER) { const { renderMap } = this._getMaps(this.updateAfterMap, reference2); if (renderMap.get(reference2) !== this.renderId) { if (node.updateAfter(this) !== false) { renderMap.set(reference2, this.renderId); } } } else if (updateType === NodeUpdateType.OBJECT) { node.updateAfter(this); } } updateNode(node) { const updateType = node.getUpdateType(); const reference2 = node.updateReference(this); if (updateType === NodeUpdateType.FRAME) { const { frameMap } = this._getMaps(this.updateMap, reference2); if (frameMap.get(reference2) !== this.frameId) { if (node.update(this) !== false) { frameMap.set(reference2, this.frameId); } } } else if (updateType === NodeUpdateType.RENDER) { const { renderMap } = this._getMaps(this.updateMap, reference2); if (renderMap.get(reference2) !== this.renderId) { if (node.update(this) !== false) { renderMap.set(reference2, this.renderId); } } } else if (updateType === NodeUpdateType.OBJECT) { node.update(this); } } update() { this.frameId++; if (this.lastTime === void 0) this.lastTime = performance.now(); this.deltaTime = (performance.now() - this.lastTime) / 1e3; this.lastTime = performance.now(); this.time += this.deltaTime; } }; var NodeFunctionInput = class { constructor(type, name, count = null, qualifier = "", isConst = false) { this.type = type; this.name = name; this.count = count; this.qualifier = qualifier; this.isConst = isConst; } }; NodeFunctionInput.isNodeFunctionInput = true; var DirectionalLightNode = class extends AnalyticLightNode { static get type() { return "DirectionalLightNode"; } constructor(light = null) { super(light); } setup(builder) { super.setup(builder); const lightingModel = builder.context.lightingModel; const lightColor = this.colorNode; const lightDirection = lightTargetDirection(this.light); const reflectedLight = builder.context.reflectedLight; lightingModel.direct({ lightDirection, lightColor, reflectedLight }, builder.stack, builder); } }; var _matrix41 = /* @__PURE__ */ new Matrix42(); var _matrix42 = /* @__PURE__ */ new Matrix42(); var ltcLib = null; var RectAreaLightNode = class extends AnalyticLightNode { static get type() { return "RectAreaLightNode"; } constructor(light = null) { super(light); this.halfHeight = uniform(new Vector32()).setGroup(renderGroup); this.halfWidth = uniform(new Vector32()).setGroup(renderGroup); this.updateType = NodeUpdateType.RENDER; } update(frame2) { super.update(frame2); const { light } = this; const viewMatrix = frame2.camera.matrixWorldInverse; _matrix42.identity(); _matrix41.copy(light.matrixWorld); _matrix41.premultiply(viewMatrix); _matrix42.extractRotation(_matrix41); this.halfWidth.value.set(light.width * 0.5, 0, 0); this.halfHeight.value.set(0, light.height * 0.5, 0); this.halfWidth.value.applyMatrix4(_matrix42); this.halfHeight.value.applyMatrix4(_matrix42); } setup(builder) { super.setup(builder); let ltc_1, ltc_2; if (builder.isAvailable("float32Filterable")) { ltc_1 = texture(ltcLib.LTC_FLOAT_1); ltc_2 = texture(ltcLib.LTC_FLOAT_2); } else { ltc_1 = texture(ltcLib.LTC_HALF_1); ltc_2 = texture(ltcLib.LTC_HALF_2); } const { colorNode, light } = this; const lightingModel = builder.context.lightingModel; const lightPosition2 = lightViewPosition(light); const reflectedLight = builder.context.reflectedLight; lightingModel.directRectArea({ lightColor: colorNode, lightPosition: lightPosition2, halfWidth: this.halfWidth, halfHeight: this.halfHeight, reflectedLight, ltc_1, ltc_2 }, builder.stack, builder); } static setLTC(ltc) { ltcLib = ltc; } }; var SpotLightNode = class extends AnalyticLightNode { static get type() { return "SpotLightNode"; } constructor(light = null) { super(light); this.coneCosNode = uniform(0).setGroup(renderGroup); this.penumbraCosNode = uniform(0).setGroup(renderGroup); this.cutoffDistanceNode = uniform(0).setGroup(renderGroup); this.decayExponentNode = uniform(0).setGroup(renderGroup); } update(frame2) { super.update(frame2); const { light } = this; this.coneCosNode.value = Math.cos(light.angle); this.penumbraCosNode.value = Math.cos(light.angle * (1 - light.penumbra)); this.cutoffDistanceNode.value = light.distance; this.decayExponentNode.value = light.decay; } getSpotAttenuation(angleCosine) { const { coneCosNode, penumbraCosNode } = this; return smoothstep2(coneCosNode, penumbraCosNode, angleCosine); } setup(builder) { super.setup(builder); const lightingModel = builder.context.lightingModel; const { colorNode, cutoffDistanceNode, decayExponentNode, light } = this; const lVector = lightViewPosition(light).sub(positionView); const lightDirection = lVector.normalize(); const angleCos = lightDirection.dot(lightTargetDirection(light)); const spotAttenuation = this.getSpotAttenuation(angleCos); const lightDistance = lVector.length(); const lightAttenuation = getDistanceAttenuation({ lightDistance, cutoffDistance: cutoffDistanceNode, decayExponent: decayExponentNode }); const lightColor = colorNode.mul(spotAttenuation).mul(lightAttenuation); const reflectedLight = builder.context.reflectedLight; lightingModel.direct({ lightDirection, lightColor, reflectedLight }, builder.stack, builder); } }; var IESSpotLightNode = class extends SpotLightNode { static get type() { return "IESSpotLightNode"; } getSpotAttenuation(angleCosine) { const iesMap = this.light.iesMap; let spotAttenuation = null; if (iesMap && iesMap.isTexture === true) { const angle = angleCosine.acos().mul(1 / Math.PI); spotAttenuation = texture(iesMap, vec2(angle, 0), 0).r; } else { spotAttenuation = super.getSpotAttenuation(angleCosine); } return spotAttenuation; } }; var AmbientLightNode = class extends AnalyticLightNode { static get type() { return "AmbientLightNode"; } constructor(light = null) { super(light); } setup({ context: context2 }) { context2.irradiance.addAssign(this.colorNode); } }; var HemisphereLightNode = class extends AnalyticLightNode { static get type() { return "HemisphereLightNode"; } constructor(light = null) { super(light); this.lightPositionNode = lightPosition(light); this.lightDirectionNode = this.lightPositionNode.normalize(); this.groundColorNode = uniform(new Color2()).setGroup(renderGroup); } update(frame2) { const { light } = this; super.update(frame2); this.lightPositionNode.object3d = light; this.groundColorNode.value.copy(light.groundColor).multiplyScalar(light.intensity); } setup(builder) { const { colorNode, groundColorNode, lightDirectionNode } = this; const dotNL = normalView.dot(lightDirectionNode); const hemiDiffuseWeight = dotNL.mul(0.5).add(0.5); const irradiance = mix(groundColorNode, colorNode, hemiDiffuseWeight); builder.context.irradiance.addAssign(irradiance); } }; var LightProbeNode = class extends AnalyticLightNode { static get type() { return "LightProbeNode"; } constructor(light = null) { super(light); const array = []; for (let i = 0; i < 9; i++) array.push(new Vector32()); this.lightProbe = uniformArray(array); } update(frame2) { const { light } = this; super.update(frame2); for (let i = 0; i < 9; i++) { this.lightProbe.array[i].copy(light.sh.coefficients[i]).multiplyScalar(light.intensity); } } setup(builder) { const irradiance = getShIrradianceAt(normalWorld, this.lightProbe); builder.context.irradiance.addAssign(irradiance); } }; var NodeParser = class { parseFunction() { console.warn("Abstract function."); } }; var NodeFunction = class { constructor(type, inputs, name = "", precision = "") { this.type = type; this.inputs = inputs; this.name = name; this.precision = precision; } getCode() { console.warn("Abstract function."); } }; NodeFunction.isNodeFunction = true; var declarationRegexp$1 = /^\s*(highp|mediump|lowp)?\s*([a-z_0-9]+)\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)/i; var propertiesRegexp$1 = /[a-z_0-9]+/ig; var pragmaMain = "#pragma main"; var parse$1 = (source) => { source = source.trim(); const pragmaMainIndex = source.indexOf(pragmaMain); const mainCode = pragmaMainIndex !== -1 ? source.slice(pragmaMainIndex + pragmaMain.length) : source; const declaration = mainCode.match(declarationRegexp$1); if (declaration !== null && declaration.length === 5) { const inputsCode = declaration[4]; const propsMatches = []; let nameMatch = null; while ((nameMatch = propertiesRegexp$1.exec(inputsCode)) !== null) { propsMatches.push(nameMatch); } const inputs = []; let i = 0; while (i < propsMatches.length) { const isConst = propsMatches[i][0] === "const"; if (isConst === true) { i++; } let qualifier = propsMatches[i][0]; if (qualifier === "in" || qualifier === "out" || qualifier === "inout") { i++; } else { qualifier = ""; } const type2 = propsMatches[i++][0]; let count = Number.parseInt(propsMatches[i][0]); if (Number.isNaN(count) === false) i++; else count = null; const name2 = propsMatches[i++][0]; inputs.push(new NodeFunctionInput(type2, name2, count, qualifier, isConst)); } const blockCode = mainCode.substring(declaration[0].length); const name = declaration[3] !== void 0 ? declaration[3] : ""; const type = declaration[2]; const precision = declaration[1] !== void 0 ? declaration[1] : ""; const headerCode = pragmaMainIndex !== -1 ? source.slice(0, pragmaMainIndex) : ""; return { type, inputs, name, precision, inputsCode, blockCode, headerCode }; } else { throw new Error("FunctionNode: Function is not a GLSL code."); } }; var GLSLNodeFunction = class extends NodeFunction { constructor(source) { const { type, inputs, name, precision, inputsCode, blockCode, headerCode } = parse$1(source); super(type, inputs, name, precision); this.inputsCode = inputsCode; this.blockCode = blockCode; this.headerCode = headerCode; } getCode(name = this.name) { let code; const blockCode = this.blockCode; if (blockCode !== "") { const { type, inputsCode, headerCode, precision } = this; let declarationCode = `${type} ${name} ( ${inputsCode.trim()} )`; if (precision !== "") { declarationCode = `${precision} ${declarationCode}`; } code = headerCode + declarationCode + blockCode; } else { code = ""; } return code; } }; var GLSLNodeParser = class extends NodeParser { parseFunction(source) { return new GLSLNodeFunction(source); } }; var outputNodeMap = /* @__PURE__ */ new WeakMap(); var Nodes = class extends DataMap { constructor(renderer3, backend) { super(); this.renderer = renderer3; this.backend = backend; this.nodeFrame = new NodeFrame(); this.nodeBuilderCache = /* @__PURE__ */ new Map(); this.callHashCache = new ChainMap(); this.groupsData = new ChainMap(); } updateGroup(nodeUniformsGroup) { const groupNode = nodeUniformsGroup.groupNode; const name = groupNode.name; if (name === objectGroup.name) return true; if (name === renderGroup.name) { const uniformsGroupData = this.get(nodeUniformsGroup); const renderId = this.nodeFrame.renderId; if (uniformsGroupData.renderId !== renderId) { uniformsGroupData.renderId = renderId; return true; } return false; } if (name === frameGroup.name) { const uniformsGroupData = this.get(nodeUniformsGroup); const frameId = this.nodeFrame.frameId; if (uniformsGroupData.frameId !== frameId) { uniformsGroupData.frameId = frameId; return true; } return false; } const groupChain = [groupNode, nodeUniformsGroup]; let groupData = this.groupsData.get(groupChain); if (groupData === void 0) this.groupsData.set(groupChain, groupData = {}); if (groupData.version !== groupNode.version) { groupData.version = groupNode.version; return true; } return false; } getForRenderCacheKey(renderObject) { return renderObject.initialCacheKey; } getForRender(renderObject) { const renderObjectData = this.get(renderObject); let nodeBuilderState = renderObjectData.nodeBuilderState; if (nodeBuilderState === void 0) { const { nodeBuilderCache } = this; const cacheKey = this.getForRenderCacheKey(renderObject); nodeBuilderState = nodeBuilderCache.get(cacheKey); if (nodeBuilderState === void 0) { const nodeBuilder = this.backend.createNodeBuilder(renderObject.object, this.renderer); nodeBuilder.scene = renderObject.scene; nodeBuilder.material = renderObject.material; nodeBuilder.camera = renderObject.camera; nodeBuilder.context.material = renderObject.material; nodeBuilder.lightsNode = renderObject.lightsNode; nodeBuilder.environmentNode = this.getEnvironmentNode(renderObject.scene); nodeBuilder.fogNode = this.getFogNode(renderObject.scene); nodeBuilder.clippingContext = renderObject.clippingContext; nodeBuilder.build(); nodeBuilderState = this._createNodeBuilderState(nodeBuilder); nodeBuilderCache.set(cacheKey, nodeBuilderState); } nodeBuilderState.usedTimes++; renderObjectData.nodeBuilderState = nodeBuilderState; } return nodeBuilderState; } delete(object) { if (object.isRenderObject) { const nodeBuilderState = this.get(object).nodeBuilderState; nodeBuilderState.usedTimes--; if (nodeBuilderState.usedTimes === 0) { this.nodeBuilderCache.delete(this.getForRenderCacheKey(object)); } } return super.delete(object); } getForCompute(computeNode) { const computeData = this.get(computeNode); let nodeBuilderState = computeData.nodeBuilderState; if (nodeBuilderState === void 0) { const nodeBuilder = this.backend.createNodeBuilder(computeNode, this.renderer); nodeBuilder.build(); nodeBuilderState = this._createNodeBuilderState(nodeBuilder); computeData.nodeBuilderState = nodeBuilderState; } return nodeBuilderState; } _createNodeBuilderState(nodeBuilder) { return new NodeBuilderState( nodeBuilder.vertexShader, nodeBuilder.fragmentShader, nodeBuilder.computeShader, nodeBuilder.getAttributesArray(), nodeBuilder.getBindings(), nodeBuilder.updateNodes, nodeBuilder.updateBeforeNodes, nodeBuilder.updateAfterNodes, nodeBuilder.monitor, nodeBuilder.transforms ); } getEnvironmentNode(scene3) { return scene3.environmentNode || this.get(scene3).environmentNode || null; } getBackgroundNode(scene3) { return scene3.backgroundNode || this.get(scene3).backgroundNode || null; } getFogNode(scene3) { return scene3.fogNode || this.get(scene3).fogNode || null; } getCacheKey(scene3, lightsNode) { const chain = [scene3, lightsNode]; const callId = this.renderer.info.calls; let cacheKeyData = this.callHashCache.get(chain); if (cacheKeyData === void 0 || cacheKeyData.callId !== callId) { const environmentNode = this.getEnvironmentNode(scene3); const fogNode = this.getFogNode(scene3); const values = []; if (lightsNode) values.push(lightsNode.getCacheKey(true)); if (environmentNode) values.push(environmentNode.getCacheKey()); if (fogNode) values.push(fogNode.getCacheKey()); values.push(this.renderer.shadowMap.enabled ? 1 : 0); cacheKeyData = { callId, cacheKey: hashArray(values) }; this.callHashCache.set(chain, cacheKeyData); } return cacheKeyData.cacheKey; } updateScene(scene3) { this.updateEnvironment(scene3); this.updateFog(scene3); this.updateBackground(scene3); } get isToneMappingState() { return this.renderer.getRenderTarget() ? false : true; } updateBackground(scene3) { const sceneData = this.get(scene3); const background = scene3.background; if (background) { const forceUpdate = scene3.backgroundBlurriness === 0 && sceneData.backgroundBlurriness > 0 || scene3.backgroundBlurriness > 0 && sceneData.backgroundBlurriness === 0; if (sceneData.background !== background || forceUpdate) { let backgroundNode = null; if (background.isCubeTexture === true || (background.mapping === EquirectangularReflectionMapping2 || background.mapping === EquirectangularRefractionMapping2 || background.mapping === CubeUVReflectionMapping2)) { if (scene3.backgroundBlurriness > 0 || background.mapping === CubeUVReflectionMapping2) { backgroundNode = pmremTexture(background); } else { let envMap; if (background.isCubeTexture === true) { envMap = cubeTexture(background); } else { envMap = texture(background); } backgroundNode = cubeMapNode(envMap); } } else if (background.isTexture === true) { backgroundNode = texture(background, screenUV.flipY()).setUpdateMatrix(true); } else if (background.isColor !== true) { console.error("WebGPUNodes: Unsupported background configuration.", background); } sceneData.backgroundNode = backgroundNode; sceneData.background = background; sceneData.backgroundBlurriness = scene3.backgroundBlurriness; } } else if (sceneData.backgroundNode) { delete sceneData.backgroundNode; delete sceneData.background; } } updateFog(scene3) { const sceneData = this.get(scene3); const fog = scene3.fog; if (fog) { if (sceneData.fog !== fog) { let fogNode = null; if (fog.isFogExp2) { const color2 = reference("color", "color", fog).setGroup(renderGroup); const density = reference("density", "float", fog).setGroup(renderGroup); fogNode = densityFog(color2, density); } else if (fog.isFog) { const color2 = reference("color", "color", fog).setGroup(renderGroup); const near = reference("near", "float", fog).setGroup(renderGroup); const far = reference("far", "float", fog).setGroup(renderGroup); fogNode = rangeFog(color2, near, far); } else { console.error("WebGPUNodes: Unsupported fog configuration.", fog); } sceneData.fogNode = fogNode; sceneData.fog = fog; } } else { delete sceneData.fogNode; delete sceneData.fog; } } updateEnvironment(scene3) { const sceneData = this.get(scene3); const environment = scene3.environment; if (environment) { if (sceneData.environment !== environment) { let environmentNode = null; if (environment.isCubeTexture === true) { environmentNode = cubeTexture(environment); } else if (environment.isTexture === true) { environmentNode = texture(environment); } else { console.error("Nodes: Unsupported environment configuration.", environment); } sceneData.environmentNode = environmentNode; sceneData.environment = environment; } } else if (sceneData.environmentNode) { delete sceneData.environmentNode; delete sceneData.environment; } } getNodeFrame(renderer3 = this.renderer, scene3 = null, object = null, camera3 = null, material = null) { const nodeFrame = this.nodeFrame; nodeFrame.renderer = renderer3; nodeFrame.scene = scene3; nodeFrame.object = object; nodeFrame.camera = camera3; nodeFrame.material = material; return nodeFrame; } getNodeFrameForRender(renderObject) { return this.getNodeFrame(renderObject.renderer, renderObject.scene, renderObject.object, renderObject.camera, renderObject.material); } getOutputCacheKey() { const renderer3 = this.renderer; return renderer3.toneMapping + "," + renderer3.currentColorSpace; } hasOutputChange(outputTarget) { const cacheKey = outputNodeMap.get(outputTarget); return cacheKey !== this.getOutputCacheKey(); } getOutputNode(outputTexture) { const renderer3 = this.renderer; const cacheKey = this.getOutputCacheKey(); const output2 = texture(outputTexture, screenUV).renderOutput(renderer3.toneMapping, renderer3.currentColorSpace); outputNodeMap.set(outputTexture, cacheKey); return output2; } updateBefore(renderObject) { const nodeBuilder = renderObject.getNodeBuilderState(); for (const node of nodeBuilder.updateBeforeNodes) { this.getNodeFrameForRender(renderObject).updateBeforeNode(node); } } updateAfter(renderObject) { const nodeBuilder = renderObject.getNodeBuilderState(); for (const node of nodeBuilder.updateAfterNodes) { this.getNodeFrameForRender(renderObject).updateAfterNode(node); } } updateForCompute(computeNode) { const nodeFrame = this.getNodeFrame(); const nodeBuilder = this.getForCompute(computeNode); for (const node of nodeBuilder.updateNodes) { nodeFrame.updateNode(node); } } updateForRender(renderObject) { const nodeFrame = this.getNodeFrameForRender(renderObject); const nodeBuilder = renderObject.getNodeBuilderState(); for (const node of nodeBuilder.updateNodes) { nodeFrame.updateNode(node); } } needsRefresh(renderObject) { const nodeFrame = this.getNodeFrameForRender(renderObject); const monitor = renderObject.getMonitor(); return monitor.needsRefresh(renderObject, nodeFrame); } dispose() { super.dispose(); this.nodeFrame = new NodeFrame(); this.nodeBuilderCache = /* @__PURE__ */ new Map(); } }; var RenderBundle = class { constructor(scene3, camera3) { this.scene = scene3; this.camera = camera3; } clone() { return Object.assign(new this.constructor(), this); } }; var RenderBundles = class { constructor() { this.lists = new ChainMap(); } get(scene3, camera3) { const lists = this.lists; const keys = [scene3, camera3]; let list = lists.get(keys); if (list === void 0) { list = new RenderBundle(scene3, camera3); lists.set(keys, list); } return list; } dispose() { this.lists = new ChainMap(); } }; var NodeLibrary = class { constructor() { this.lightNodes = /* @__PURE__ */ new WeakMap(); this.materialNodes = /* @__PURE__ */ new Map(); this.toneMappingNodes = /* @__PURE__ */ new Map(); } fromMaterial(material) { if (material.isNodeMaterial) return material; let nodeMaterial = null; const nodeMaterialClass = this.getMaterialNodeClass(material.type); if (nodeMaterialClass !== null) { nodeMaterial = new nodeMaterialClass(); for (const key in material) { nodeMaterial[key] = material[key]; } } return nodeMaterial; } addToneMapping(toneMappingNode, toneMapping2) { this.addType(toneMappingNode, toneMapping2, this.toneMappingNodes); } getToneMappingFunction(toneMapping2) { return this.toneMappingNodes.get(toneMapping2) || null; } getMaterialNodeClass(materialType) { return this.materialNodes.get(materialType) || null; } addMaterial(materialNodeClass, materialClass) { this.addType(materialNodeClass, materialClass.type, this.materialNodes); } getLightNodeClass(light) { return this.lightNodes.get(light) || null; } addLight(lightNodeClass, lightClass) { this.addClass(lightNodeClass, lightClass, this.lightNodes); } addType(nodeClass, type, library) { if (library.has(type)) { console.warn(`Redefinition of node ${type}`); return; } if (typeof nodeClass !== "function") throw new Error(`Node class ${nodeClass.name} is not a class.`); if (typeof type === "function" || typeof type === "object") throw new Error(`Base class ${type} is not a class.`); library.set(type, nodeClass); } addClass(nodeClass, baseClass, library) { if (library.has(baseClass)) { console.warn(`Redefinition of node ${baseClass.name}`); return; } if (typeof nodeClass !== "function") throw new Error(`Node class ${nodeClass.name} is not a class.`); if (typeof baseClass !== "function") throw new Error(`Base class ${baseClass.name} is not a class.`); library.set(baseClass, nodeClass); } }; var _defaultLights = /* @__PURE__ */ new LightsNode(); var Lighting = class extends ChainMap { constructor() { super(); } createNode(lights = []) { return new LightsNode().setLights(lights); } getNode(scene3, camera3) { if (scene3.isQuadMesh) return _defaultLights; const keys = [scene3, camera3]; let node = this.get(keys); if (node === void 0) { node = this.createNode(); this.set(keys, node); } return node; } }; var _scene = /* @__PURE__ */ new Scene2(); var _drawingBufferSize = /* @__PURE__ */ new Vector22(); var _screen = /* @__PURE__ */ new Vector42(); var _frustum = /* @__PURE__ */ new Frustum2(); var _projScreenMatrix = /* @__PURE__ */ new Matrix42(); var _vector4 = /* @__PURE__ */ new Vector42(); var Renderer = class { constructor(backend, parameters = {}) { this.isRenderer = true; const { logarithmicDepthBuffer = false, alpha = true, depth: depth2 = true, stencil = false, antialias = false, samples = 0, getFallback = null } = parameters; this.domElement = backend.getDomElement(); this.backend = backend; this.samples = samples || antialias === true ? 4 : 0; this.autoClear = true; this.autoClearColor = true; this.autoClearDepth = true; this.autoClearStencil = true; this.alpha = alpha; this.logarithmicDepthBuffer = logarithmicDepthBuffer; this.outputColorSpace = SRGBColorSpace2; this.toneMapping = NoToneMapping2; this.toneMappingExposure = 1; this.sortObjects = true; this.depth = depth2; this.stencil = stencil; this.clippingPlanes = []; this.info = new Info(); this.nodes = { modelViewMatrix: null, modelNormalViewMatrix: null }; this.library = new NodeLibrary(); this.lighting = new Lighting(); this._getFallback = getFallback; this._pixelRatio = 1; this._width = this.domElement.width; this._height = this.domElement.height; this._viewport = new Vector42(0, 0, this._width, this._height); this._scissor = new Vector42(0, 0, this._width, this._height); this._scissorTest = false; this._attributes = null; this._geometries = null; this._nodes = null; this._animation = null; this._bindings = null; this._objects = null; this._pipelines = null; this._bundles = null; this._renderLists = null; this._renderContexts = null; this._textures = null; this._background = null; this._quad = new QuadMesh(new NodeMaterial()); this._quad.material.type = "Renderer_output"; this._currentRenderContext = null; this._opaqueSort = null; this._transparentSort = null; this._frameBufferTarget = null; const alphaClear = this.alpha === true ? 0 : 1; this._clearColor = new Color4(0, 0, 0, alphaClear); this._clearDepth = 1; this._clearStencil = 0; this._renderTarget = null; this._activeCubeFace = 0; this._activeMipmapLevel = 0; this._mrt = null; this._renderObjectFunction = null; this._currentRenderObjectFunction = null; this._currentRenderBundle = null; this._handleObjectFunction = this._renderObjectDirect; this._isDeviceLost = false; this.onDeviceLost = this._onDeviceLost; this._initialized = false; this._initPromise = null; this._compilationPromises = null; this.transparent = true; this.opaque = true; this.shadowMap = { enabled: false, type: PCFShadowMap$1 }; this.xr = { enabled: false }; this.debug = { checkShaderErrors: true, onShaderError: null, getShaderAsync: async (scene3, camera3, object) => { await this.compileAsync(scene3, camera3); const renderList = this._renderLists.get(scene3, camera3); const renderContext = this._renderContexts.get(scene3, camera3, this._renderTarget); const material = scene3.overrideMaterial || object.material; const renderObject = this._objects.get(object, material, scene3, camera3, renderList.lightsNode, renderContext); const { fragmentShader, vertexShader } = renderObject.getNodeBuilderState(); return { fragmentShader, vertexShader }; } }; } async init() { if (this._initialized) { throw new Error("Renderer: Backend has already been initialized."); } if (this._initPromise !== null) { return this._initPromise; } this._initPromise = new Promise(async (resolve, reject) => { let backend = this.backend; try { await backend.init(this); } catch (error) { if (this._getFallback !== null) { try { this.backend = backend = this._getFallback(error); await backend.init(this); } catch (error2) { reject(error2); return; } } else { reject(error); return; } } this._nodes = new Nodes(this, backend); this._animation = new Animation(this._nodes, this.info); this._attributes = new Attributes(backend); this._background = new Background(this, this._nodes); this._geometries = new Geometries(this._attributes, this.info); this._textures = new Textures(this, backend, this.info); this._pipelines = new Pipelines(backend, this._nodes); this._bindings = new Bindings(backend, this._nodes, this._textures, this._attributes, this._pipelines, this.info); this._objects = new RenderObjects(this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info); this._renderLists = new RenderLists(this.lighting); this._bundles = new RenderBundles(); this._renderContexts = new RenderContexts(); this._initialized = true; resolve(); }); return this._initPromise; } get coordinateSystem() { return this.backend.coordinateSystem; } async compileAsync(scene3, camera3, targetScene = null) { if (this._isDeviceLost === true) return; if (this._initialized === false) await this.init(); const nodeFrame = this._nodes.nodeFrame; const previousRenderId = nodeFrame.renderId; const previousRenderContext = this._currentRenderContext; const previousRenderObjectFunction = this._currentRenderObjectFunction; const previousCompilationPromises = this._compilationPromises; const sceneRef = scene3.isScene === true ? scene3 : _scene; if (targetScene === null) targetScene = scene3; const renderTarget = this._renderTarget; const renderContext = this._renderContexts.get(targetScene, camera3, renderTarget); const activeMipmapLevel = this._activeMipmapLevel; const compilationPromises = []; this._currentRenderContext = renderContext; this._currentRenderObjectFunction = this.renderObject; this._handleObjectFunction = this._createObjectPipeline; this._compilationPromises = compilationPromises; nodeFrame.renderId++; nodeFrame.update(); renderContext.depth = this.depth; renderContext.stencil = this.stencil; if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); renderContext.clippingContext.updateGlobal(this, camera3); sceneRef.onBeforeRender(this, scene3, camera3, renderTarget); const renderList = this._renderLists.get(scene3, camera3); renderList.begin(); this._projectObject(scene3, camera3, 0, renderList); if (targetScene !== scene3) { targetScene.traverseVisible(function(object) { if (object.isLight && object.layers.test(camera3.layers)) { renderList.pushLight(object); } }); } renderList.finish(); if (renderTarget !== null) { this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); const renderTargetData = this._textures.get(renderTarget); renderContext.textures = renderTargetData.textures; renderContext.depthTexture = renderTargetData.depthTexture; } else { renderContext.textures = null; renderContext.depthTexture = null; } this._nodes.updateScene(sceneRef); this._background.update(sceneRef, renderList, renderContext); const opaqueObjects = renderList.opaque; const transparentObjects = renderList.transparent; const lightsNode = renderList.lightsNode; if (this.opaque === true && opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera3, sceneRef, lightsNode); if (this.transparent === true && transparentObjects.length > 0) this._renderTransparents(transparentObjects, camera3, sceneRef, lightsNode); nodeFrame.renderId = previousRenderId; this._currentRenderContext = previousRenderContext; this._currentRenderObjectFunction = previousRenderObjectFunction; this._compilationPromises = previousCompilationPromises; this._handleObjectFunction = this._renderObjectDirect; await Promise.all(compilationPromises); } async renderAsync(scene3, camera3) { if (this._initialized === false) await this.init(); const renderContext = this._renderScene(scene3, camera3); await this.backend.resolveTimestampAsync(renderContext, "render"); } async waitForGPU() { await this.backend.waitForGPU(); } setMRT(mrt) { this._mrt = mrt; return this; } getMRT() { return this._mrt; } _onDeviceLost(info) { let errorMessage = `THREE.WebGPURenderer: ${info.api} Device Lost: Message: ${info.message}`; if (info.reason) { errorMessage += ` Reason: ${info.reason}`; } console.error(errorMessage); this._isDeviceLost = true; } _renderBundle(bundle, sceneRef, lightsNode) { const { bundleGroup, camera: camera3, renderList } = bundle; const renderContext = this._currentRenderContext; const renderBundle = this._bundles.get(bundleGroup, camera3); const renderBundleData = this.backend.get(renderBundle); if (renderBundleData.renderContexts === void 0) renderBundleData.renderContexts = /* @__PURE__ */ new Set(); const needsUpdate = bundleGroup.version !== renderBundleData.version; const renderBundleNeedsUpdate = renderBundleData.renderContexts.has(renderContext) === false || needsUpdate; renderBundleData.renderContexts.add(renderContext); if (renderBundleNeedsUpdate) { this.backend.beginBundle(renderContext); if (renderBundleData.renderObjects === void 0 || needsUpdate) { renderBundleData.renderObjects = []; } this._currentRenderBundle = renderBundle; const opaqueObjects = renderList.opaque; if (this.opaque === true && opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera3, sceneRef, lightsNode); this._currentRenderBundle = null; this.backend.finishBundle(renderContext, renderBundle); renderBundleData.version = bundleGroup.version; } else { const { renderObjects } = renderBundleData; for (let i = 0, l = renderObjects.length; i < l; i++) { const renderObject = renderObjects[i]; if (this._nodes.needsRefresh(renderObject)) { this._nodes.updateBefore(renderObject); this._nodes.updateForRender(renderObject); this._bindings.updateForRender(renderObject); this._nodes.updateAfter(renderObject); } } } this.backend.addBundle(renderContext, renderBundle); } render(scene3, camera3) { if (this._initialized === false) { console.warn("THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead."); return this.renderAsync(scene3, camera3); } this._renderScene(scene3, camera3); } _getFrameBufferTarget() { const { currentToneMapping, currentColorSpace } = this; const useToneMapping = currentToneMapping !== NoToneMapping2; const useColorSpace = currentColorSpace !== LinearSRGBColorSpace2; if (useToneMapping === false && useColorSpace === false) return null; const { width, height } = this.getDrawingBufferSize(_drawingBufferSize); const { depth: depth2, stencil } = this; let frameBufferTarget = this._frameBufferTarget; if (frameBufferTarget === null) { frameBufferTarget = new RenderTarget2(width, height, { depthBuffer: depth2, stencilBuffer: stencil, type: HalfFloatType2, // FloatType format: RGBAFormat2, colorSpace: LinearSRGBColorSpace2, generateMipmaps: false, minFilter: LinearFilter2, magFilter: LinearFilter2, samples: this.samples }); frameBufferTarget.isPostProcessingRenderTarget = true; this._frameBufferTarget = frameBufferTarget; } frameBufferTarget.depthBuffer = depth2; frameBufferTarget.stencilBuffer = stencil; frameBufferTarget.setSize(width, height); frameBufferTarget.viewport.copy(this._viewport); frameBufferTarget.scissor.copy(this._scissor); frameBufferTarget.viewport.multiplyScalar(this._pixelRatio); frameBufferTarget.scissor.multiplyScalar(this._pixelRatio); frameBufferTarget.scissorTest = this._scissorTest; return frameBufferTarget; } _renderScene(scene3, camera3, useFrameBufferTarget = true) { if (this._isDeviceLost === true) return; const frameBufferTarget = useFrameBufferTarget ? this._getFrameBufferTarget() : null; const nodeFrame = this._nodes.nodeFrame; const previousRenderId = nodeFrame.renderId; const previousRenderContext = this._currentRenderContext; const previousRenderObjectFunction = this._currentRenderObjectFunction; const sceneRef = scene3.isScene === true ? scene3 : _scene; const outputRenderTarget = this._renderTarget; const activeCubeFace = this._activeCubeFace; const activeMipmapLevel = this._activeMipmapLevel; let renderTarget; if (frameBufferTarget !== null) { renderTarget = frameBufferTarget; this.setRenderTarget(renderTarget); } else { renderTarget = outputRenderTarget; } const renderContext = this._renderContexts.get(scene3, camera3, renderTarget); this._currentRenderContext = renderContext; this._currentRenderObjectFunction = this._renderObjectFunction || this.renderObject; this.info.calls++; this.info.render.calls++; this.info.render.frameCalls++; nodeFrame.renderId = this.info.calls; const coordinateSystem = this.coordinateSystem; if (camera3.coordinateSystem !== coordinateSystem) { camera3.coordinateSystem = coordinateSystem; camera3.updateProjectionMatrix(); } if (scene3.matrixWorldAutoUpdate === true) scene3.updateMatrixWorld(); if (camera3.parent === null && camera3.matrixWorldAutoUpdate === true) camera3.updateMatrixWorld(); let viewport2 = this._viewport; let scissor = this._scissor; let pixelRatio = this._pixelRatio; if (renderTarget !== null) { viewport2 = renderTarget.viewport; scissor = renderTarget.scissor; pixelRatio = 1; } this.getDrawingBufferSize(_drawingBufferSize); _screen.set(0, 0, _drawingBufferSize.width, _drawingBufferSize.height); const minDepth = viewport2.minDepth === void 0 ? 0 : viewport2.minDepth; const maxDepth = viewport2.maxDepth === void 0 ? 1 : viewport2.maxDepth; renderContext.viewportValue.copy(viewport2).multiplyScalar(pixelRatio).floor(); renderContext.viewportValue.width >>= activeMipmapLevel; renderContext.viewportValue.height >>= activeMipmapLevel; renderContext.viewportValue.minDepth = minDepth; renderContext.viewportValue.maxDepth = maxDepth; renderContext.viewport = renderContext.viewportValue.equals(_screen) === false; renderContext.scissorValue.copy(scissor).multiplyScalar(pixelRatio).floor(); renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals(_screen) === false; renderContext.scissorValue.width >>= activeMipmapLevel; renderContext.scissorValue.height >>= activeMipmapLevel; if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); renderContext.clippingContext.updateGlobal(this, camera3); sceneRef.onBeforeRender(this, scene3, camera3, renderTarget); _projScreenMatrix.multiplyMatrices(camera3.projectionMatrix, camera3.matrixWorldInverse); _frustum.setFromProjectionMatrix(_projScreenMatrix, coordinateSystem); const renderList = this._renderLists.get(scene3, camera3); renderList.begin(); this._projectObject(scene3, camera3, 0, renderList); renderList.finish(); if (this.sortObjects === true) { renderList.sort(this._opaqueSort, this._transparentSort); } if (renderTarget !== null) { this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); const renderTargetData = this._textures.get(renderTarget); renderContext.textures = renderTargetData.textures; renderContext.depthTexture = renderTargetData.depthTexture; renderContext.width = renderTargetData.width; renderContext.height = renderTargetData.height; renderContext.renderTarget = renderTarget; renderContext.depth = renderTarget.depthBuffer; renderContext.stencil = renderTarget.stencilBuffer; } else { renderContext.textures = null; renderContext.depthTexture = null; renderContext.width = this.domElement.width; renderContext.height = this.domElement.height; renderContext.depth = this.depth; renderContext.stencil = this.stencil; } renderContext.width >>= activeMipmapLevel; renderContext.height >>= activeMipmapLevel; renderContext.activeCubeFace = activeCubeFace; renderContext.activeMipmapLevel = activeMipmapLevel; renderContext.occlusionQueryCount = renderList.occlusionQueryCount; this._nodes.updateScene(sceneRef); this._background.update(sceneRef, renderList, renderContext); this.backend.beginRender(renderContext); const { bundles, lightsNode, transparentDoublePass: transparentDoublePassObjects, transparent: transparentObjects, opaque: opaqueObjects } = renderList; if (bundles.length > 0) this._renderBundles(bundles, sceneRef, lightsNode); if (this.opaque === true && opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera3, sceneRef, lightsNode); if (this.transparent === true && transparentObjects.length > 0) this._renderTransparents(transparentObjects, transparentDoublePassObjects, camera3, sceneRef, lightsNode); this.backend.finishRender(renderContext); nodeFrame.renderId = previousRenderId; this._currentRenderContext = previousRenderContext; this._currentRenderObjectFunction = previousRenderObjectFunction; if (frameBufferTarget !== null) { this.setRenderTarget(outputRenderTarget, activeCubeFace, activeMipmapLevel); const quad = this._quad; if (this._nodes.hasOutputChange(renderTarget.texture)) { quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); quad.material.needsUpdate = true; } this._renderScene(quad, quad.camera, false); } sceneRef.onAfterRender(this, scene3, camera3, renderTarget); return renderContext; } getMaxAnisotropy() { return this.backend.getMaxAnisotropy(); } getActiveCubeFace() { return this._activeCubeFace; } getActiveMipmapLevel() { return this._activeMipmapLevel; } async setAnimationLoop(callback) { if (this._initialized === false) await this.init(); this._animation.setAnimationLoop(callback); } async getArrayBufferAsync(attribute2) { return await this.backend.getArrayBufferAsync(attribute2); } getContext() { return this.backend.getContext(); } getPixelRatio() { return this._pixelRatio; } getDrawingBufferSize(target) { return target.set(this._width * this._pixelRatio, this._height * this._pixelRatio).floor(); } getSize(target) { return target.set(this._width, this._height); } setPixelRatio(value = 1) { if (this._pixelRatio === value) return; this._pixelRatio = value; this.setSize(this._width, this._height, false); } setDrawingBufferSize(width, height, pixelRatio) { this._width = width; this._height = height; this._pixelRatio = pixelRatio; this.domElement.width = Math.floor(width * pixelRatio); this.domElement.height = Math.floor(height * pixelRatio); this.setViewport(0, 0, width, height); if (this._initialized) this.backend.updateSize(); } setSize(width, height, updateStyle = true) { this._width = width; this._height = height; this.domElement.width = Math.floor(width * this._pixelRatio); this.domElement.height = Math.floor(height * this._pixelRatio); if (updateStyle === true) { this.domElement.style.width = width + "px"; this.domElement.style.height = height + "px"; } this.setViewport(0, 0, width, height); if (this._initialized) this.backend.updateSize(); } setOpaqueSort(method) { this._opaqueSort = method; } setTransparentSort(method) { this._transparentSort = method; } getScissor(target) { const scissor = this._scissor; target.x = scissor.x; target.y = scissor.y; target.width = scissor.width; target.height = scissor.height; return target; } setScissor(x2, y2, width, height) { const scissor = this._scissor; if (x2.isVector4) { scissor.copy(x2); } else { scissor.set(x2, y2, width, height); } } getScissorTest() { return this._scissorTest; } setScissorTest(boolean) { this._scissorTest = boolean; this.backend.setScissorTest(boolean); } getViewport(target) { return target.copy(this._viewport); } setViewport(x2, y2, width, height, minDepth = 0, maxDepth = 1) { const viewport2 = this._viewport; if (x2.isVector4) { viewport2.copy(x2); } else { viewport2.set(x2, y2, width, height); } viewport2.minDepth = minDepth; viewport2.maxDepth = maxDepth; } getClearColor(target) { return target.copy(this._clearColor); } setClearColor(color2, alpha = 1) { this._clearColor.set(color2); this._clearColor.a = alpha; } getClearAlpha() { return this._clearColor.a; } setClearAlpha(alpha) { this._clearColor.a = alpha; } getClearDepth() { return this._clearDepth; } setClearDepth(depth2) { this._clearDepth = depth2; } getClearStencil() { return this._clearStencil; } setClearStencil(stencil) { this._clearStencil = stencil; } isOccluded(object) { const renderContext = this._currentRenderContext; return renderContext && this.backend.isOccluded(renderContext, object); } clear(color2 = true, depth2 = true, stencil = true) { if (this._initialized === false) { console.warn("THREE.Renderer: .clear() called before the backend is initialized. Try using .clearAsync() instead."); return this.clearAsync(color2, depth2, stencil); } const renderTarget = this._renderTarget || this._getFrameBufferTarget(); let renderTargetData = null; if (renderTarget !== null) { this._textures.updateRenderTarget(renderTarget); renderTargetData = this._textures.get(renderTarget); } this.backend.clear(color2, depth2, stencil, renderTargetData); if (renderTarget !== null && this._renderTarget === null) { const quad = this._quad; if (this._nodes.hasOutputChange(renderTarget.texture)) { quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); quad.material.needsUpdate = true; } this._renderScene(quad, quad.camera, false); } } clearColor() { return this.clear(true, false, false); } clearDepth() { return this.clear(false, true, false); } clearStencil() { return this.clear(false, false, true); } async clearAsync(color2 = true, depth2 = true, stencil = true) { if (this._initialized === false) await this.init(); this.clear(color2, depth2, stencil); } clearColorAsync() { return this.clearAsync(true, false, false); } clearDepthAsync() { return this.clearAsync(false, true, false); } clearStencilAsync() { return this.clearAsync(false, false, true); } get currentToneMapping() { return this._renderTarget !== null ? NoToneMapping2 : this.toneMapping; } get currentColorSpace() { return this._renderTarget !== null ? LinearSRGBColorSpace2 : this.outputColorSpace; } dispose() { this.info.dispose(); this.backend.dispose(); this._animation.dispose(); this._objects.dispose(); this._pipelines.dispose(); this._nodes.dispose(); this._bindings.dispose(); this._renderLists.dispose(); this._renderContexts.dispose(); this._textures.dispose(); this.setRenderTarget(null); this.setAnimationLoop(null); } setRenderTarget(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { this._renderTarget = renderTarget; this._activeCubeFace = activeCubeFace; this._activeMipmapLevel = activeMipmapLevel; } getRenderTarget() { return this._renderTarget; } setRenderObjectFunction(renderObjectFunction) { this._renderObjectFunction = renderObjectFunction; } getRenderObjectFunction() { return this._renderObjectFunction; } compute(computeNodes) { if (this.isDeviceLost === true) return; if (this._initialized === false) { console.warn("THREE.Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead."); return this.computeAsync(computeNodes); } const nodeFrame = this._nodes.nodeFrame; const previousRenderId = nodeFrame.renderId; this.info.calls++; this.info.compute.calls++; this.info.compute.frameCalls++; nodeFrame.renderId = this.info.calls; const backend = this.backend; const pipelines = this._pipelines; const bindings = this._bindings; const nodes = this._nodes; const computeList = Array.isArray(computeNodes) ? computeNodes : [computeNodes]; if (computeList[0] === void 0 || computeList[0].isComputeNode !== true) { throw new Error("THREE.Renderer: .compute() expects a ComputeNode."); } backend.beginCompute(computeNodes); for (const computeNode of computeList) { if (pipelines.has(computeNode) === false) { const dispose = () => { computeNode.removeEventListener("dispose", dispose); pipelines.delete(computeNode); bindings.delete(computeNode); nodes.delete(computeNode); }; computeNode.addEventListener("dispose", dispose); const onInitFn = computeNode.onInitFunction; if (onInitFn !== null) { onInitFn.call(computeNode, { renderer: this }); } } nodes.updateForCompute(computeNode); bindings.updateForCompute(computeNode); const computeBindings = bindings.getForCompute(computeNode); const computePipeline = pipelines.getForCompute(computeNode, computeBindings); backend.compute(computeNodes, computeNode, computeBindings, computePipeline); } backend.finishCompute(computeNodes); nodeFrame.renderId = previousRenderId; } async computeAsync(computeNodes) { if (this._initialized === false) await this.init(); this.compute(computeNodes); await this.backend.resolveTimestampAsync(computeNodes, "compute"); } async hasFeatureAsync(name) { if (this._initialized === false) await this.init(); return this.backend.hasFeature(name); } hasFeature(name) { if (this._initialized === false) { console.warn("THREE.Renderer: .hasFeature() called before the backend is initialized. Try using .hasFeatureAsync() instead."); return false; } return this.backend.hasFeature(name); } copyFramebufferToTexture(framebufferTexture, rectangle = null) { if (rectangle !== null) { if (rectangle.isVector2) { rectangle = _vector4.set(rectangle.x, rectangle.y, framebufferTexture.image.width, framebufferTexture.image.height).floor(); } else if (rectangle.isVector4) { rectangle = _vector4.copy(rectangle).floor(); } else { console.error("THREE.Renderer.copyFramebufferToTexture: Invalid rectangle."); return; } } else { rectangle = _vector4.set(0, 0, framebufferTexture.image.width, framebufferTexture.image.height); } let renderContext = this._currentRenderContext; let renderTarget; if (renderContext !== null) { renderTarget = renderContext.renderTarget; } else { renderTarget = this._renderTarget || this._getFrameBufferTarget(); if (renderTarget !== null) { this._textures.updateRenderTarget(renderTarget); renderContext = this._textures.get(renderTarget); } } this._textures.updateTexture(framebufferTexture, { renderTarget }); this.backend.copyFramebufferToTexture(framebufferTexture, renderContext, rectangle); } copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { this._textures.updateTexture(srcTexture); this._textures.updateTexture(dstTexture); this.backend.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); } readRenderTargetPixelsAsync(renderTarget, x2, y2, width, height, index5 = 0, faceIndex = 0) { return this.backend.copyTextureToBuffer(renderTarget.textures[index5], x2, y2, width, height, faceIndex); } _projectObject(object, camera3, groupOrder, renderList) { if (object.visible === false) return; const visible = object.layers.test(camera3.layers); if (visible) { if (object.isGroup) { groupOrder = object.renderOrder; } else if (object.isLOD) { if (object.autoUpdate === true) object.update(camera3); } else if (object.isLight) { renderList.pushLight(object); } else if (object.isSprite) { if (!object.frustumCulled || _frustum.intersectsSprite(object)) { if (this.sortObjects === true) { _vector4.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); } const { geometry, material } = object; if (material.visible) { renderList.push(object, geometry, material, groupOrder, _vector4.z, null); } } } else if (object.isLineLoop) { console.error("THREE.Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments."); } else if (object.isMesh || object.isLine || object.isPoints) { if (!object.frustumCulled || _frustum.intersectsObject(object)) { const { geometry, material } = object; if (this.sortObjects === true) { if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); _vector4.copy(geometry.boundingSphere.center).applyMatrix4(object.matrixWorld).applyMatrix4(_projScreenMatrix); } 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) { renderList.push(object, geometry, groupMaterial, groupOrder, _vector4.z, group); } } } else if (material.visible) { renderList.push(object, geometry, material, groupOrder, _vector4.z, null); } } } } if (object.isBundleGroup === true && this.backend.beginBundle !== void 0) { const baseRenderList = renderList; renderList = this._renderLists.get(object, camera3); renderList.begin(); baseRenderList.pushBundle({ bundleGroup: object, camera: camera3, renderList }); renderList.finish(); } const children = object.children; for (let i = 0, l = children.length; i < l; i++) { this._projectObject(children[i], camera3, groupOrder, renderList); } } _renderBundles(bundles, sceneRef, lightsNode) { for (const bundle of bundles) { this._renderBundle(bundle, sceneRef, lightsNode); } } _renderTransparents(renderList, doublePassList, camera3, scene3, lightsNode) { if (doublePassList.length > 0) { for (const { material } of doublePassList) { material.side = BackSide2; } this._renderObjects(doublePassList, camera3, scene3, lightsNode, "backSide"); for (const { material } of doublePassList) { material.side = FrontSide2; } this._renderObjects(renderList, camera3, scene3, lightsNode); for (const { material } of doublePassList) { material.side = DoubleSide2; } } else { this._renderObjects(renderList, camera3, scene3, lightsNode); } } _renderObjects(renderList, camera3, scene3, lightsNode, passId = null) { for (let i = 0, il = renderList.length; i < il; i++) { const renderItem = renderList[i]; const { object, geometry, material, group } = renderItem; if (camera3.isArrayCamera) { const cameras = camera3.cameras; for (let j = 0, jl = cameras.length; j < jl; j++) { const camera22 = cameras[j]; if (object.layers.test(camera22.layers)) { const vp = camera22.viewport; const minDepth = vp.minDepth === void 0 ? 0 : vp.minDepth; const maxDepth = vp.maxDepth === void 0 ? 1 : vp.maxDepth; const viewportValue = this._currentRenderContext.viewportValue; viewportValue.copy(vp).multiplyScalar(this._pixelRatio).floor(); viewportValue.minDepth = minDepth; viewportValue.maxDepth = maxDepth; this.backend.updateViewport(this._currentRenderContext); this._currentRenderObjectFunction(object, scene3, camera22, geometry, material, group, lightsNode, passId); } } } else { this._currentRenderObjectFunction(object, scene3, camera3, geometry, material, group, lightsNode, passId); } } } renderObject(object, scene3, camera3, geometry, material, group, lightsNode, passId = null) { let overridePositionNode; let overrideFragmentNode; let overrideDepthNode; object.onBeforeRender(this, scene3, camera3, geometry, material, group); if (scene3.overrideMaterial !== null) { const overrideMaterial = scene3.overrideMaterial; if (material.positionNode && material.positionNode.isNode) { overridePositionNode = overrideMaterial.positionNode; overrideMaterial.positionNode = material.positionNode; } if (overrideMaterial.isShadowNodeMaterial) { overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide; if (material.depthNode && material.depthNode.isNode) { overrideDepthNode = overrideMaterial.depthNode; overrideMaterial.depthNode = material.depthNode; } if (material.shadowNode && material.shadowNode.isNode) { overrideFragmentNode = overrideMaterial.fragmentNode; overrideMaterial.fragmentNode = material.shadowNode; } if (this.localClippingEnabled) { if (material.clipShadows) { if (overrideMaterial.clippingPlanes !== material.clippingPlanes) { overrideMaterial.clippingPlanes = material.clippingPlanes; overrideMaterial.needsUpdate = true; } if (overrideMaterial.clipIntersection !== material.clipIntersection) { overrideMaterial.clipIntersection = material.clipIntersection; } } else if (Array.isArray(overrideMaterial.clippingPlanes)) { overrideMaterial.clippingPlanes = null; overrideMaterial.needsUpdate = true; } } } material = overrideMaterial; } if (material.transparent === true && material.side === DoubleSide2 && material.forceSinglePass === false) { material.side = BackSide2; this._handleObjectFunction(object, material, scene3, camera3, lightsNode, group, "backSide"); material.side = FrontSide2; this._handleObjectFunction(object, material, scene3, camera3, lightsNode, group, passId); material.side = DoubleSide2; } else { this._handleObjectFunction(object, material, scene3, camera3, lightsNode, group, passId); } if (overridePositionNode !== void 0) { scene3.overrideMaterial.positionNode = overridePositionNode; } if (overrideDepthNode !== void 0) { scene3.overrideMaterial.depthNode = overrideDepthNode; } if (overrideFragmentNode !== void 0) { scene3.overrideMaterial.fragmentNode = overrideFragmentNode; } object.onAfterRender(this, scene3, camera3, geometry, material, group); } _renderObjectDirect(object, material, scene3, camera3, lightsNode, group, passId) { const renderObject = this._objects.get(object, material, scene3, camera3, lightsNode, this._currentRenderContext, passId); renderObject.drawRange = object.geometry.drawRange; renderObject.group = group; const needsRefresh = this._nodes.needsRefresh(renderObject); if (needsRefresh) { this._nodes.updateBefore(renderObject); this._geometries.updateForRender(renderObject); this._nodes.updateForRender(renderObject); this._bindings.updateForRender(renderObject); } this._pipelines.updateForRender(renderObject); if (this._currentRenderBundle !== null) { const renderBundleData = this.backend.get(this._currentRenderBundle); renderBundleData.renderObjects.push(renderObject); renderObject.bundle = this._currentRenderBundle.scene; } this.backend.draw(renderObject, this.info); if (needsRefresh) this._nodes.updateAfter(renderObject); } _createObjectPipeline(object, material, scene3, camera3, lightsNode, passId) { const renderObject = this._objects.get(object, material, scene3, camera3, lightsNode, this._currentRenderContext, passId); this._nodes.updateBefore(renderObject); this._geometries.updateForRender(renderObject); this._nodes.updateForRender(renderObject); this._bindings.updateForRender(renderObject); this._pipelines.getForRender(renderObject, this._compilationPromises); this._nodes.updateAfter(renderObject); } get compile() { return this.compileAsync; } }; var Binding = class { constructor(name = "") { this.name = name; this.visibility = 0; } setVisibility(visibility) { this.visibility |= visibility; } clone() { return Object.assign(new this.constructor(), this); } }; function getFloatLength(floatLength) { return floatLength + (GPU_CHUNK_BYTES - floatLength % GPU_CHUNK_BYTES) % GPU_CHUNK_BYTES; } var Buffer2 = class extends Binding { constructor(name, buffer2 = null) { super(name); this.isBuffer = true; this.bytesPerElement = Float32Array.BYTES_PER_ELEMENT; this._buffer = buffer2; } get byteLength() { return getFloatLength(this._buffer.byteLength); } get buffer() { return this._buffer; } update() { return true; } }; var UniformBuffer = class extends Buffer2 { constructor(name, buffer2 = null) { super(name, buffer2); this.isUniformBuffer = true; } }; var _id$4 = 0; var NodeUniformBuffer = class extends UniformBuffer { constructor(nodeUniform, groupNode) { super("UniformBuffer_" + _id$4++, nodeUniform ? nodeUniform.value : null); this.nodeUniform = nodeUniform; this.groupNode = groupNode; } get buffer() { return this.nodeUniform.value; } }; var UniformsGroup = class extends UniformBuffer { constructor(name) { super(name); this.isUniformsGroup = true; this._values = null; this.uniforms = []; } addUniform(uniform2) { this.uniforms.push(uniform2); return this; } removeUniform(uniform2) { const index5 = this.uniforms.indexOf(uniform2); if (index5 !== -1) { this.uniforms.splice(index5, 1); } return this; } get values() { if (this._values === null) { this._values = Array.from(this.buffer); } return this._values; } get buffer() { let buffer2 = this._buffer; if (buffer2 === null) { const byteLength = this.byteLength; buffer2 = new Float32Array(new ArrayBuffer(byteLength)); this._buffer = buffer2; } return buffer2; } get byteLength() { let offset = 0; for (let i = 0, l = this.uniforms.length; i < l; i++) { const uniform2 = this.uniforms[i]; const { boundary, itemSize } = uniform2; const chunkOffset = offset % GPU_CHUNK_BYTES; const remainingSizeInChunk = GPU_CHUNK_BYTES - chunkOffset; if (chunkOffset !== 0 && remainingSizeInChunk - boundary < 0) { offset += GPU_CHUNK_BYTES - chunkOffset; } else if (chunkOffset % boundary !== 0) { offset += chunkOffset % boundary; } uniform2.offset = offset / this.bytesPerElement; offset += itemSize * this.bytesPerElement; } return Math.ceil(offset / GPU_CHUNK_BYTES) * GPU_CHUNK_BYTES; } update() { let updated = false; for (const uniform2 of this.uniforms) { if (this.updateByType(uniform2) === true) { updated = true; } } return updated; } updateByType(uniform2) { if (uniform2.isNumberUniform) return this.updateNumber(uniform2); if (uniform2.isVector2Uniform) return this.updateVector2(uniform2); if (uniform2.isVector3Uniform) return this.updateVector3(uniform2); if (uniform2.isVector4Uniform) return this.updateVector4(uniform2); if (uniform2.isColorUniform) return this.updateColor(uniform2); if (uniform2.isMatrix3Uniform) return this.updateMatrix3(uniform2); if (uniform2.isMatrix4Uniform) return this.updateMatrix4(uniform2); console.error("THREE.WebGPUUniformsGroup: Unsupported uniform type.", uniform2); } updateNumber(uniform2) { let updated = false; const a2 = this.values; const v = uniform2.getValue(); const offset = uniform2.offset; if (a2[offset] !== v) { const b = this.buffer; b[offset] = a2[offset] = v; updated = true; } return updated; } updateVector2(uniform2) { let updated = false; const a2 = this.values; const v = uniform2.getValue(); const offset = uniform2.offset; if (a2[offset + 0] !== v.x || a2[offset + 1] !== v.y) { const b = this.buffer; b[offset + 0] = a2[offset + 0] = v.x; b[offset + 1] = a2[offset + 1] = v.y; updated = true; } return updated; } updateVector3(uniform2) { let updated = false; const a2 = this.values; const v = uniform2.getValue(); const offset = uniform2.offset; if (a2[offset + 0] !== v.x || a2[offset + 1] !== v.y || a2[offset + 2] !== v.z) { const b = this.buffer; b[offset + 0] = a2[offset + 0] = v.x; b[offset + 1] = a2[offset + 1] = v.y; b[offset + 2] = a2[offset + 2] = v.z; updated = true; } return updated; } updateVector4(uniform2) { let updated = false; const a2 = this.values; const v = uniform2.getValue(); const offset = uniform2.offset; if (a2[offset + 0] !== v.x || a2[offset + 1] !== v.y || a2[offset + 2] !== v.z || a2[offset + 4] !== v.w) { const b = this.buffer; b[offset + 0] = a2[offset + 0] = v.x; b[offset + 1] = a2[offset + 1] = v.y; b[offset + 2] = a2[offset + 2] = v.z; b[offset + 3] = a2[offset + 3] = v.w; updated = true; } return updated; } updateColor(uniform2) { let updated = false; const a2 = this.values; const c2 = uniform2.getValue(); const offset = uniform2.offset; if (a2[offset + 0] !== c2.r || a2[offset + 1] !== c2.g || a2[offset + 2] !== c2.b) { const b = this.buffer; b[offset + 0] = a2[offset + 0] = c2.r; b[offset + 1] = a2[offset + 1] = c2.g; b[offset + 2] = a2[offset + 2] = c2.b; updated = true; } return updated; } updateMatrix3(uniform2) { let updated = false; const a2 = this.values; const e = uniform2.getValue().elements; const offset = uniform2.offset; if (a2[offset + 0] !== e[0] || a2[offset + 1] !== e[1] || a2[offset + 2] !== e[2] || a2[offset + 4] !== e[3] || a2[offset + 5] !== e[4] || a2[offset + 6] !== e[5] || a2[offset + 8] !== e[6] || a2[offset + 9] !== e[7] || a2[offset + 10] !== e[8]) { const b = this.buffer; b[offset + 0] = a2[offset + 0] = e[0]; b[offset + 1] = a2[offset + 1] = e[1]; b[offset + 2] = a2[offset + 2] = e[2]; b[offset + 4] = a2[offset + 4] = e[3]; b[offset + 5] = a2[offset + 5] = e[4]; b[offset + 6] = a2[offset + 6] = e[5]; b[offset + 8] = a2[offset + 8] = e[6]; b[offset + 9] = a2[offset + 9] = e[7]; b[offset + 10] = a2[offset + 10] = e[8]; updated = true; } return updated; } updateMatrix4(uniform2) { let updated = false; const a2 = this.values; const e = uniform2.getValue().elements; const offset = uniform2.offset; if (arraysEqual2(a2, e, offset) === false) { const b = this.buffer; b.set(e, offset); setArray(a2, e, offset); updated = true; } return updated; } }; function setArray(a2, b, offset) { for (let i = 0, l = b.length; i < l; i++) { a2[offset + i] = b[i]; } } function arraysEqual2(a2, b, offset) { for (let i = 0, l = b.length; i < l; i++) { if (a2[offset + i] !== b[i]) return false; } return true; } var _id$3 = 0; var NodeUniformsGroup = class extends UniformsGroup { constructor(name, groupNode) { super(name); this.id = _id$3++; this.groupNode = groupNode; this.isNodeUniformsGroup = true; } getNodes() { const nodes = []; for (const uniform2 of this.uniforms) { const node = uniform2.nodeUniform.node; if (!node) throw new Error("NodeUniformsGroup: Uniform has no node."); nodes.push(node); } return nodes; } }; var _id$22 = 0; var SampledTexture = class extends Binding { constructor(name, texture2) { super(name); this.id = _id$22++; this.texture = texture2; this.version = texture2 ? texture2.version : 0; this.store = false; this.generation = null; this.isSampledTexture = true; } needsBindingsUpdate(generation) { const { texture: texture2 } = this; if (generation !== this.generation) { this.generation = generation; return true; } return texture2.isVideoTexture; } update() { const { texture: texture2, version } = this; if (version !== texture2.version) { this.version = texture2.version; return true; } return false; } }; var NodeSampledTexture = class extends SampledTexture { constructor(name, textureNode, groupNode, access = null) { super(name, textureNode ? textureNode.value : null); this.textureNode = textureNode; this.groupNode = groupNode; this.access = access; } needsBindingsUpdate(generation) { return this.textureNode.value !== this.texture || super.needsBindingsUpdate(generation); } update() { const { textureNode } = this; if (this.texture !== textureNode.value) { this.texture = textureNode.value; return true; } return super.update(); } }; var NodeSampledCubeTexture = class extends NodeSampledTexture { constructor(name, textureNode, groupNode, access) { super(name, textureNode, groupNode, access); this.isSampledCubeTexture = true; } }; var NodeSampledTexture3D = class extends NodeSampledTexture { constructor(name, textureNode, groupNode, access) { super(name, textureNode, groupNode, access); this.isSampledTexture3D = true; } }; var glslMethods = { atan2: "atan", textureDimensions: "textureSize", equals: "equal" }; var precisionLib = { low: "lowp", medium: "mediump", high: "highp" }; var supports$1 = { swizzleAssign: true, storageBuffer: false }; var defaultPrecisions = ` precision highp float; precision highp int; precision highp sampler2D; precision highp sampler3D; precision highp samplerCube; precision highp sampler2DArray; precision highp usampler2D; precision highp usampler3D; precision highp usamplerCube; precision highp usampler2DArray; precision highp isampler2D; precision highp isampler3D; precision highp isamplerCube; precision highp isampler2DArray; precision lowp sampler2DShadow; `; var GLSLNodeBuilder = class extends NodeBuilder { constructor(object, renderer3) { super(object, renderer3, new GLSLNodeParser()); this.uniformGroups = {}; this.transforms = []; this.extensions = {}; this.useComparisonMethod = true; } needsColorSpaceToLinearSRGB(texture2) { return texture2.isVideoTexture === true && texture2.colorSpace !== NoColorSpace2; } getMethod(method) { return glslMethods[method] || method; } getOutputStructName() { return ""; } buildFunctionCode(shaderNode) { const layout = shaderNode.layout; const flowData = this.flowShaderNode(shaderNode); const parameters = []; for (const input of layout.inputs) { parameters.push(this.getType(input.type) + " " + input.name); } const code = `${this.getType(layout.type)} ${layout.name}( ${parameters.join(", ")} ) { ${flowData.vars} ${flowData.code} return ${flowData.result}; }`; return code; } setupPBO(storageBufferNode) { const attribute2 = storageBufferNode.value; if (attribute2.pbo === void 0) { const originalArray = attribute2.array; const numElements = attribute2.count * attribute2.itemSize; const { itemSize } = attribute2; const isInteger = attribute2.array.constructor.name.toLowerCase().includes("int"); let format2 = isInteger ? RedIntegerFormat2 : RedFormat2; if (itemSize === 2) { format2 = isInteger ? RGIntegerFormat2 : RGFormat2; } else if (itemSize === 3) { format2 = isInteger ? RGBIntegerFormat : RGBFormat2; } else if (itemSize === 4) { format2 = isInteger ? RGBAIntegerFormat2 : RGBAFormat2; } const typeMap = { Float32Array: FloatType2, Uint8Array: UnsignedByteType2, Uint16Array: UnsignedShortType2, Uint32Array: UnsignedIntType2, Int8Array: ByteType2, Int16Array: ShortType2, Int32Array: IntType2, Uint8ClampedArray: UnsignedByteType2 }; const width = Math.pow(2, Math.ceil(Math.log2(Math.sqrt(numElements / itemSize)))); let height = Math.ceil(numElements / itemSize / width); if (width * height * itemSize < numElements) height++; const newSize = width * height * itemSize; const newArray = new originalArray.constructor(newSize); newArray.set(originalArray, 0); attribute2.array = newArray; const pboTexture = new DataTexture(attribute2.array, width, height, format2, typeMap[attribute2.array.constructor.name] || FloatType2); pboTexture.needsUpdate = true; pboTexture.isPBOTexture = true; const pbo = new TextureNode(pboTexture, null, null); pbo.setPrecision("high"); attribute2.pboNode = pbo; attribute2.pbo = pbo.value; this.getUniformFromNode(attribute2.pboNode, "texture", this.shaderStage, this.context.label); } } getPropertyName(node, shaderStage = this.shaderStage) { if (node.isNodeUniform && node.node.isTextureNode !== true && node.node.isBufferNode !== true) { return shaderStage.charAt(0) + "_" + node.name; } return super.getPropertyName(node, shaderStage); } generatePBO(storageArrayElementNode) { const { node, indexNode } = storageArrayElementNode; const attribute2 = node.value; if (this.renderer.backend.has(attribute2)) { const attributeData = this.renderer.backend.get(attribute2); attributeData.pbo = attribute2.pbo; } const nodeUniform = this.getUniformFromNode(attribute2.pboNode, "texture", this.shaderStage, this.context.label); const textureName = this.getPropertyName(nodeUniform); this.increaseUsage(indexNode); const indexSnippet = indexNode.build(this, "uint"); const elementNodeData = this.getDataFromNode(storageArrayElementNode); let propertyName = elementNodeData.propertyName; if (propertyName === void 0) { const nodeVar = this.getVarFromNode(storageArrayElementNode); propertyName = this.getPropertyName(nodeVar); const bufferNodeData = this.getDataFromNode(node); let propertySizeName = bufferNodeData.propertySizeName; if (propertySizeName === void 0) { propertySizeName = propertyName + "Size"; this.getVarFromNode(node, propertySizeName, "uint"); this.addLineFlowCode(`${propertySizeName} = uint( textureSize( ${textureName}, 0 ).x )`, storageArrayElementNode); bufferNodeData.propertySizeName = propertySizeName; } const { itemSize } = attribute2; const channel = "." + vectorComponents.join("").slice(0, itemSize); const uvSnippet = `ivec2(${indexSnippet} % ${propertySizeName}, ${indexSnippet} / ${propertySizeName})`; const snippet = this.generateTextureLoad(null, textureName, uvSnippet, null, "0"); let prefix = "vec4"; if (attribute2.pbo.type === UnsignedIntType2) { prefix = "uvec4"; } else if (attribute2.pbo.type === IntType2) { prefix = "ivec4"; } this.addLineFlowCode(`${propertyName} = ${prefix}(${snippet})${channel}`, storageArrayElementNode); elementNodeData.propertyName = propertyName; } return propertyName; } generateTextureLoad(texture2, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = "0") { if (depthSnippet) { return `texelFetch( ${textureProperty}, ivec3( ${uvIndexSnippet}, ${depthSnippet} ), ${levelSnippet} )`; } else { return `texelFetch( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; } } generateTexture(texture2, textureProperty, uvSnippet, depthSnippet) { if (texture2.isDepthTexture) { return `texture( ${textureProperty}, ${uvSnippet} ).x`; } else { if (depthSnippet) uvSnippet = `vec3( ${uvSnippet}, ${depthSnippet} )`; return `texture( ${textureProperty}, ${uvSnippet} )`; } } generateTextureLevel(texture2, textureProperty, uvSnippet, levelSnippet) { return `textureLod( ${textureProperty}, ${uvSnippet}, ${levelSnippet} )`; } generateTextureBias(texture2, textureProperty, uvSnippet, biasSnippet) { return `texture( ${textureProperty}, ${uvSnippet}, ${biasSnippet} )`; } generateTextureGrad(texture2, textureProperty, uvSnippet, gradSnippet) { return `textureGrad( ${textureProperty}, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; } generateTextureCompare(texture2, textureProperty, uvSnippet, compareSnippet, depthSnippet, shaderStage = this.shaderStage) { if (shaderStage === "fragment") { return `texture( ${textureProperty}, vec3( ${uvSnippet}, ${compareSnippet} ) )`; } else { console.error(`WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`); } } getVars(shaderStage) { const snippets = []; const vars = this.vars[shaderStage]; if (vars !== void 0) { for (const variable of vars) { snippets.push(`${this.getVar(variable.type, variable.name)};`); } } return snippets.join("\n "); } getUniforms(shaderStage) { const uniforms = this.uniforms[shaderStage]; const bindingSnippets = []; const uniformGroups = {}; for (const uniform2 of uniforms) { let snippet = null; let group = false; if (uniform2.type === "texture") { const texture2 = uniform2.node.value; let typePrefix = ""; if (texture2.isDataTexture === true) { if (texture2.type === UnsignedIntType2) { typePrefix = "u"; } else if (texture2.type === IntType2) { typePrefix = "i"; } } if (texture2.compareFunction) { snippet = `sampler2DShadow ${uniform2.name};`; } else if (texture2.isDataArrayTexture === true || texture2.isCompressedArrayTexture === true) { snippet = `${typePrefix}sampler2DArray ${uniform2.name};`; } else { snippet = `${typePrefix}sampler2D ${uniform2.name};`; } } else if (uniform2.type === "cubeTexture") { snippet = `samplerCube ${uniform2.name};`; } else if (uniform2.type === "texture3D") { snippet = `sampler3D ${uniform2.name};`; } else if (uniform2.type === "buffer") { const bufferNode = uniform2.node; const bufferType = this.getType(bufferNode.bufferType); const bufferCount = bufferNode.bufferCount; const bufferCountSnippet = bufferCount > 0 ? bufferCount : ""; snippet = `${bufferNode.name} { ${bufferType} ${uniform2.name}[${bufferCountSnippet}]; }; `; } else { const vectorType = this.getVectorType(uniform2.type); snippet = `${vectorType} ${this.getPropertyName(uniform2, shaderStage)};`; group = true; } const precision = uniform2.node.precision; if (precision !== null) { snippet = precisionLib[precision] + " " + snippet; } if (group) { snippet = " " + snippet; const groupName = uniform2.groupNode.name; const groupSnippets = uniformGroups[groupName] || (uniformGroups[groupName] = []); groupSnippets.push(snippet); } else { snippet = "uniform " + snippet; bindingSnippets.push(snippet); } } let output2 = ""; for (const name in uniformGroups) { const groupSnippets = uniformGroups[name]; output2 += this._getGLSLUniformStruct(shaderStage + "_" + name, groupSnippets.join("\n")) + "\n"; } output2 += bindingSnippets.join("\n"); return output2; } getTypeFromAttribute(attribute2) { let nodeType = super.getTypeFromAttribute(attribute2); if (/^[iu]/.test(nodeType) && attribute2.gpuType !== IntType2) { let dataAttribute = attribute2; if (attribute2.isInterleavedBufferAttribute) dataAttribute = attribute2.data; const array = dataAttribute.array; if ((array instanceof Uint32Array || array instanceof Int32Array) === false) { nodeType = nodeType.slice(1); } } return nodeType; } getAttributes(shaderStage) { let snippet = ""; if (shaderStage === "vertex" || shaderStage === "compute") { const attributes = this.getAttributesArray(); let location = 0; for (const attribute2 of attributes) { snippet += `layout( location = ${location++} ) in ${attribute2.type} ${attribute2.name}; `; } } return snippet; } getStructMembers(struct) { const snippets = []; const members = struct.getMemberTypes(); for (let i = 0; i < members.length; i++) { const member = members[i]; snippets.push(`layout( location = ${i} ) out ${member} m${i};`); } return snippets.join("\n"); } getStructs(shaderStage) { const snippets = []; const structs = this.structs[shaderStage]; if (structs.length === 0) { return "layout( location = 0 ) out vec4 fragColor;\n"; } for (let index5 = 0, length2 = structs.length; index5 < length2; index5++) { const struct = structs[index5]; let snippet = "\n"; snippet += this.getStructMembers(struct); snippet += "\n"; snippets.push(snippet); } return snippets.join("\n\n"); } getVaryings(shaderStage) { let snippet = ""; const varyings = this.varyings; if (shaderStage === "vertex" || shaderStage === "compute") { for (const varying2 of varyings) { if (shaderStage === "compute") varying2.needsInterpolation = true; const type = varying2.type; const flat = type.includes("int") || type.includes("uv") || type.includes("iv") ? "flat " : ""; snippet += `${flat}${varying2.needsInterpolation ? "out" : "/*out*/"} ${type} ${varying2.name}; `; } } else if (shaderStage === "fragment") { for (const varying2 of varyings) { if (varying2.needsInterpolation) { const type = varying2.type; const flat = type.includes("int") || type.includes("uv") || type.includes("iv") ? "flat " : ""; snippet += `${flat}in ${type} ${varying2.name}; `; } } } return snippet; } getVertexIndex() { return "uint( gl_VertexID )"; } getInstanceIndex() { return "uint( gl_InstanceID )"; } getInvocationLocalIndex() { const workgroupSize = this.object.workgroupSize; const size = workgroupSize.reduce((acc, curr) => acc * curr, 1); return `uint( gl_InstanceID ) % ${size}u`; } getDrawIndex() { const extensions = this.renderer.backend.extensions; if (extensions.has("WEBGL_multi_draw")) { return "uint( gl_DrawID )"; } return null; } getFrontFacing() { return "gl_FrontFacing"; } getFragCoord() { return "gl_FragCoord.xy"; } getFragDepth() { return "gl_FragDepth"; } enableExtension(name, behavior, shaderStage = this.shaderStage) { const map = this.extensions[shaderStage] || (this.extensions[shaderStage] = /* @__PURE__ */ new Map()); if (map.has(name) === false) { map.set(name, { name, behavior }); } } getExtensions(shaderStage) { const snippets = []; if (shaderStage === "vertex") { const ext = this.renderer.backend.extensions; const isBatchedMesh = this.object.isBatchedMesh; if (isBatchedMesh && ext.has("WEBGL_multi_draw")) { this.enableExtension("GL_ANGLE_multi_draw", "require", shaderStage); } } const extensions = this.extensions[shaderStage]; if (extensions !== void 0) { for (const { name, behavior } of extensions.values()) { snippets.push(`#extension ${name} : ${behavior}`); } } return snippets.join("\n"); } isAvailable(name) { let result = supports$1[name]; if (result === void 0) { if (name === "float32Filterable") { const extensions = this.renderer.backend.extensions; if (extensions.has("OES_texture_float_linear")) { extensions.get("OES_texture_float_linear"); result = true; } else { result = false; } } supports$1[name] = result; } return result; } isFlipY() { return true; } registerTransform(varyingName, attributeNode) { this.transforms.push({ varyingName, attributeNode }); } getTransforms() { const transforms = this.transforms; let snippet = ""; for (let i = 0; i < transforms.length; i++) { const transform = transforms[i]; const attributeName = this.getPropertyName(transform.attributeNode); snippet += `${transform.varyingName} = ${attributeName}; `; } return snippet; } _getGLSLUniformStruct(name, vars) { return ` layout( std140 ) uniform ${name} { ${vars} };`; } _getGLSLVertexCode(shaderData) { return `#version 300 es ${this.getSignature()} // extensions ${shaderData.extensions} // precision ${defaultPrecisions} // uniforms ${shaderData.uniforms} // varyings ${shaderData.varyings} // attributes ${shaderData.attributes} // codes ${shaderData.codes} void main() { // vars ${shaderData.vars} // transforms ${shaderData.transforms} // flow ${shaderData.flow} gl_PointSize = 1.0; } `; } _getGLSLFragmentCode(shaderData) { return `#version 300 es ${this.getSignature()} // precision ${defaultPrecisions} // uniforms ${shaderData.uniforms} // varyings ${shaderData.varyings} // codes ${shaderData.codes} ${shaderData.structs} void main() { // vars ${shaderData.vars} // flow ${shaderData.flow} } `; } buildCode() { const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; this.sortBindingGroups(); for (const shaderStage in shadersData) { let flow = "// code\n\n"; flow += this.flowCode[shaderStage]; const flowNodes = this.flowNodes[shaderStage]; const mainNode = flowNodes[flowNodes.length - 1]; for (const node of flowNodes) { const flowSlotData = this.getFlowData( node /*, shaderStage*/ ); const slotName = node.name; if (slotName) { if (flow.length > 0) flow += "\n"; flow += ` // flow -> ${slotName} `; } flow += `${flowSlotData.code} `; if (node === mainNode && shaderStage !== "compute") { flow += "// result\n "; if (shaderStage === "vertex") { flow += "gl_Position = "; flow += `${flowSlotData.result};`; } else if (shaderStage === "fragment") { if (!node.outputNode.isOutputStructNode) { flow += "fragColor = "; flow += `${flowSlotData.result};`; } } } } const stageData = shadersData[shaderStage]; stageData.extensions = this.getExtensions(shaderStage); stageData.uniforms = this.getUniforms(shaderStage); stageData.attributes = this.getAttributes(shaderStage); stageData.varyings = this.getVaryings(shaderStage); stageData.vars = this.getVars(shaderStage); stageData.structs = this.getStructs(shaderStage); stageData.codes = this.getCodes(shaderStage); stageData.transforms = this.getTransforms(shaderStage); stageData.flow = flow; } if (this.material !== null) { this.vertexShader = this._getGLSLVertexCode(shadersData.vertex); this.fragmentShader = this._getGLSLFragmentCode(shadersData.fragment); } else { this.computeShader = this._getGLSLVertexCode(shadersData.compute); } } getUniformFromNode(node, type, shaderStage, name = null) { const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); let uniformGPU = nodeData.uniformGPU; if (uniformGPU === void 0) { const group = node.groupNode; const groupName = group.name; const bindings = this.getBindGroupArray(groupName, shaderStage); if (type === "texture") { uniformGPU = new NodeSampledTexture(uniformNode.name, uniformNode.node, group); bindings.push(uniformGPU); } else if (type === "cubeTexture") { uniformGPU = new NodeSampledCubeTexture(uniformNode.name, uniformNode.node, group); bindings.push(uniformGPU); } else if (type === "texture3D") { uniformGPU = new NodeSampledTexture3D(uniformNode.name, uniformNode.node, group); bindings.push(uniformGPU); } else if (type === "buffer") { node.name = `NodeBuffer_${node.id}`; uniformNode.name = `buffer${node.id}`; const buffer2 = new NodeUniformBuffer(node, group); buffer2.name = node.name; bindings.push(buffer2); uniformGPU = buffer2; } else { const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); let uniformsGroup = uniformsStage[groupName]; if (uniformsGroup === void 0) { uniformsGroup = new NodeUniformsGroup(shaderStage + "_" + groupName, group); uniformsStage[groupName] = uniformsGroup; bindings.push(uniformsGroup); } uniformGPU = this.getNodeUniform(uniformNode, type); uniformsGroup.addUniform(uniformGPU); } nodeData.uniformGPU = uniformGPU; } return uniformNode; } }; var vector2 = null; var vector4 = null; var color4 = null; var Backend = class { constructor(parameters = {}) { this.parameters = Object.assign({}, parameters); this.data = /* @__PURE__ */ new WeakMap(); this.renderer = null; this.domElement = null; } async init(renderer3) { this.renderer = renderer3; } // render context begin() { } finish() { } // render object draw() { } // program createProgram() { } destroyProgram() { } // bindings createBindings() { } updateBindings() { } // pipeline createRenderPipeline() { } createComputePipeline() { } destroyPipeline() { } // cache key needsRenderUpdate() { } // return Boolean ( fast test ) getRenderCacheKey() { } // return String // node builder createNodeBuilder() { } // return NodeBuilder (ADD IT) // textures createSampler() { } createDefaultTexture() { } createTexture() { } copyTextureToBuffer() { } // attributes createAttribute() { } createIndexAttribute() { } updateAttribute() { } destroyAttribute() { } // canvas getContext() { } updateSize() { } // utils resolveTimestampAsync() { } hasFeatureAsync() { } // return Boolean hasFeature() { } // return Boolean getInstanceCount(renderObject) { const { object, geometry } = renderObject; return geometry.isInstancedBufferGeometry ? geometry.instanceCount : object.count > 1 ? object.count : 1; } getDrawingBufferSize() { vector2 = vector2 || new Vector22(); return this.renderer.getDrawingBufferSize(vector2); } getScissor() { vector4 = vector4 || new Vector42(); return this.renderer.getScissor(vector4); } setScissorTest() { } getClearColor() { const renderer3 = this.renderer; color4 = color4 || new Color4(); renderer3.getClearColor(color4); color4.getRGB(color4, this.renderer.currentColorSpace); return color4; } getDomElement() { let domElement = this.domElement; if (domElement === null) { domElement = this.parameters.canvas !== void 0 ? this.parameters.canvas : createCanvasElement2(); if ("setAttribute" in domElement) domElement.setAttribute("data-engine", `three.js r${REVISION2} webgpu`); this.domElement = domElement; } return domElement; } // resource properties set(object, value) { this.data.set(object, value); } get(object) { let map = this.data.get(object); if (map === void 0) { map = {}; this.data.set(object, map); } return map; } has(object) { return this.data.has(object); } delete(object) { this.data.delete(object); } dispose() { } }; var _id$12 = 0; var DualAttributeData = class { constructor(attributeData, dualBuffer) { this.buffers = [attributeData.bufferGPU, dualBuffer]; this.type = attributeData.type; this.bufferType = attributeData.bufferType; this.pbo = attributeData.pbo; this.byteLength = attributeData.byteLength; this.bytesPerElement = attributeData.BYTES_PER_ELEMENT; this.version = attributeData.version; this.isInteger = attributeData.isInteger; this.activeBufferIndex = 0; this.baseId = attributeData.id; } get id() { return `${this.baseId}|${this.activeBufferIndex}`; } get bufferGPU() { return this.buffers[this.activeBufferIndex]; } get transformBuffer() { return this.buffers[this.activeBufferIndex ^ 1]; } switchBuffers() { this.activeBufferIndex ^= 1; } }; var WebGLAttributeUtils = class { constructor(backend) { this.backend = backend; } createAttribute(attribute2, bufferType) { const backend = this.backend; const { gl } = backend; const array = attribute2.array; const usage = attribute2.usage || gl.STATIC_DRAW; const bufferAttribute2 = attribute2.isInterleavedBufferAttribute ? attribute2.data : attribute2; const bufferData = backend.get(bufferAttribute2); let bufferGPU = bufferData.bufferGPU; if (bufferGPU === void 0) { bufferGPU = this._createBuffer(gl, bufferType, array, usage); bufferData.bufferGPU = bufferGPU; bufferData.bufferType = bufferType; bufferData.version = bufferAttribute2.version; } let type; if (array instanceof Float32Array) { type = gl.FLOAT; } else if (array instanceof Uint16Array) { if (attribute2.isFloat16BufferAttribute) { type = gl.HALF_FLOAT; } else { type = gl.UNSIGNED_SHORT; } } else if (array instanceof Int16Array) { type = gl.SHORT; } else if (array instanceof Uint32Array) { type = gl.UNSIGNED_INT; } else if (array instanceof Int32Array) { type = gl.INT; } else if (array instanceof Int8Array) { type = gl.BYTE; } else if (array instanceof Uint8Array) { type = gl.UNSIGNED_BYTE; } else if (array instanceof Uint8ClampedArray) { type = gl.UNSIGNED_BYTE; } else { throw new Error("THREE.WebGLBackend: Unsupported buffer data format: " + array); } let attributeData = { bufferGPU, bufferType, type, byteLength: array.byteLength, bytesPerElement: array.BYTES_PER_ELEMENT, version: attribute2.version, pbo: attribute2.pbo, isInteger: type === gl.INT || type === gl.UNSIGNED_INT || attribute2.gpuType === IntType2, id: _id$12++ }; if (attribute2.isStorageBufferAttribute || attribute2.isStorageInstancedBufferAttribute) { const bufferGPUDual = this._createBuffer(gl, bufferType, array, usage); attributeData = new DualAttributeData(attributeData, bufferGPUDual); } backend.set(attribute2, attributeData); } updateAttribute(attribute2) { const backend = this.backend; const { gl } = backend; const array = attribute2.array; const bufferAttribute2 = attribute2.isInterleavedBufferAttribute ? attribute2.data : attribute2; const bufferData = backend.get(bufferAttribute2); const bufferType = bufferData.bufferType; const updateRanges = attribute2.isInterleavedBufferAttribute ? attribute2.data.updateRanges : attribute2.updateRanges; gl.bindBuffer(bufferType, bufferData.bufferGPU); if (updateRanges.length === 0) { gl.bufferSubData(bufferType, 0, array); } else { for (let i = 0, l = updateRanges.length; i < l; i++) { const range = updateRanges[i]; gl.bufferSubData( bufferType, range.start * array.BYTES_PER_ELEMENT, array, range.start, range.count ); } bufferAttribute2.clearUpdateRanges(); } gl.bindBuffer(bufferType, null); bufferData.version = bufferAttribute2.version; } destroyAttribute(attribute2) { const backend = this.backend; const { gl } = backend; if (attribute2.isInterleavedBufferAttribute) { backend.delete(attribute2.data); } const attributeData = backend.get(attribute2); gl.deleteBuffer(attributeData.bufferGPU); backend.delete(attribute2); } async getArrayBufferAsync(attribute2) { const backend = this.backend; const { gl } = backend; const bufferAttribute2 = attribute2.isInterleavedBufferAttribute ? attribute2.data : attribute2; const { bufferGPU } = backend.get(bufferAttribute2); const array = attribute2.array; const byteLength = array.byteLength; gl.bindBuffer(gl.COPY_READ_BUFFER, bufferGPU); const writeBuffer = gl.createBuffer(); gl.bindBuffer(gl.COPY_WRITE_BUFFER, writeBuffer); gl.bufferData(gl.COPY_WRITE_BUFFER, byteLength, gl.STREAM_READ); gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, byteLength); await backend.utils._clientWaitAsync(); const dstBuffer = new attribute2.array.constructor(array.length); gl.bindBuffer(gl.COPY_WRITE_BUFFER, writeBuffer); gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dstBuffer); gl.deleteBuffer(writeBuffer); gl.bindBuffer(gl.COPY_READ_BUFFER, null); gl.bindBuffer(gl.COPY_WRITE_BUFFER, null); return dstBuffer.buffer; } _createBuffer(gl, bufferType, array, usage) { const bufferGPU = gl.createBuffer(); gl.bindBuffer(bufferType, bufferGPU); gl.bufferData(bufferType, array, usage); gl.bindBuffer(bufferType, null); return bufferGPU; } }; var initialized$1 = false; var equationToGL; var factorToGL; var WebGLState2 = class { constructor(backend) { this.backend = backend; this.gl = this.backend.gl; this.enabled = {}; this.currentFlipSided = null; this.currentCullFace = null; this.currentProgram = null; this.currentBlendingEnabled = false; this.currentBlending = null; this.currentBlendSrc = null; this.currentBlendDst = null; this.currentBlendSrcAlpha = null; this.currentBlendDstAlpha = null; this.currentPremultipledAlpha = null; this.currentPolygonOffsetFactor = null; this.currentPolygonOffsetUnits = null; this.currentColorMask = null; this.currentDepthFunc = null; this.currentDepthMask = null; this.currentStencilFunc = null; this.currentStencilRef = null; this.currentStencilFuncMask = null; this.currentStencilFail = null; this.currentStencilZFail = null; this.currentStencilZPass = null; this.currentStencilMask = null; this.currentLineWidth = null; this.currentBoundFramebuffers = {}; this.currentDrawbuffers = /* @__PURE__ */ new WeakMap(); this.maxTextures = this.gl.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS); this.currentTextureSlot = null; this.currentBoundTextures = {}; this.currentBoundBufferBases = {}; if (initialized$1 === false) { this._init(this.gl); initialized$1 = true; } } _init(gl) { equationToGL = { [AddEquation2]: gl.FUNC_ADD, [SubtractEquation2]: gl.FUNC_SUBTRACT, [ReverseSubtractEquation2]: gl.FUNC_REVERSE_SUBTRACT }; factorToGL = { [ZeroFactor2]: gl.ZERO, [OneFactor2]: gl.ONE, [SrcColorFactor2]: gl.SRC_COLOR, [SrcAlphaFactor2]: gl.SRC_ALPHA, [SrcAlphaSaturateFactor2]: gl.SRC_ALPHA_SATURATE, [DstColorFactor2]: gl.DST_COLOR, [DstAlphaFactor2]: gl.DST_ALPHA, [OneMinusSrcColorFactor2]: gl.ONE_MINUS_SRC_COLOR, [OneMinusSrcAlphaFactor2]: gl.ONE_MINUS_SRC_ALPHA, [OneMinusDstColorFactor2]: gl.ONE_MINUS_DST_COLOR, [OneMinusDstAlphaFactor2]: gl.ONE_MINUS_DST_ALPHA }; } enable(id2) { const { enabled } = this; if (enabled[id2] !== true) { this.gl.enable(id2); enabled[id2] = true; } } disable(id2) { const { enabled } = this; if (enabled[id2] !== false) { this.gl.disable(id2); enabled[id2] = false; } } setFlipSided(flipSided) { if (this.currentFlipSided !== flipSided) { const { gl } = this; if (flipSided) { gl.frontFace(gl.CW); } else { gl.frontFace(gl.CCW); } this.currentFlipSided = flipSided; } } setCullFace(cullFace) { const { gl } = this; if (cullFace !== CullFaceNone2) { this.enable(gl.CULL_FACE); if (cullFace !== this.currentCullFace) { if (cullFace === CullFaceBack2) { gl.cullFace(gl.BACK); } else if (cullFace === CullFaceFront2) { gl.cullFace(gl.FRONT); } else { gl.cullFace(gl.FRONT_AND_BACK); } } } else { this.disable(gl.CULL_FACE); } this.currentCullFace = cullFace; } setLineWidth(width) { const { currentLineWidth, gl } = this; if (width !== currentLineWidth) { gl.lineWidth(width); this.currentLineWidth = width; } } setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha) { const { gl } = this; if (blending === NoBlending2) { if (this.currentBlendingEnabled === true) { this.disable(gl.BLEND); this.currentBlendingEnabled = false; } return; } if (this.currentBlendingEnabled === false) { this.enable(gl.BLEND); this.currentBlendingEnabled = true; } if (blending !== CustomBlending2) { if (blending !== this.currentBlending || premultipliedAlpha !== this.currentPremultipledAlpha) { if (this.currentBlendEquation !== AddEquation2 || this.currentBlendEquationAlpha !== AddEquation2) { gl.blendEquation(gl.FUNC_ADD); this.currentBlendEquation = AddEquation2; this.currentBlendEquationAlpha = AddEquation2; } if (premultipliedAlpha) { switch (blending) { case NormalBlending2: gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); break; case AdditiveBlending2: gl.blendFunc(gl.ONE, gl.ONE); break; case SubtractiveBlending2: gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); break; case MultiplyBlending2: gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA); break; default: console.error("THREE.WebGLState: Invalid blending: ", blending); break; } } else { switch (blending) { case NormalBlending2: gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); break; case AdditiveBlending2: gl.blendFunc(gl.SRC_ALPHA, gl.ONE); break; case SubtractiveBlending2: gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE); break; case MultiplyBlending2: gl.blendFunc(gl.ZERO, gl.SRC_COLOR); break; default: console.error("THREE.WebGLState: Invalid blending: ", blending); break; } } this.currentBlendSrc = null; this.currentBlendDst = null; this.currentBlendSrcAlpha = null; this.currentBlendDstAlpha = null; this.currentBlending = blending; this.currentPremultipledAlpha = premultipliedAlpha; } return; } blendEquationAlpha = blendEquationAlpha || blendEquation; blendSrcAlpha = blendSrcAlpha || blendSrc; blendDstAlpha = blendDstAlpha || blendDst; if (blendEquation !== this.currentBlendEquation || blendEquationAlpha !== this.currentBlendEquationAlpha) { gl.blendEquationSeparate(equationToGL[blendEquation], equationToGL[blendEquationAlpha]); this.currentBlendEquation = blendEquation; this.currentBlendEquationAlpha = blendEquationAlpha; } if (blendSrc !== this.currentBlendSrc || blendDst !== this.currentBlendDst || blendSrcAlpha !== this.currentBlendSrcAlpha || blendDstAlpha !== this.currentBlendDstAlpha) { gl.blendFuncSeparate(factorToGL[blendSrc], factorToGL[blendDst], factorToGL[blendSrcAlpha], factorToGL[blendDstAlpha]); this.currentBlendSrc = blendSrc; this.currentBlendDst = blendDst; this.currentBlendSrcAlpha = blendSrcAlpha; this.currentBlendDstAlpha = blendDstAlpha; } this.currentBlending = blending; this.currentPremultipledAlpha = false; } setColorMask(colorMask) { if (this.currentColorMask !== colorMask) { this.gl.colorMask(colorMask, colorMask, colorMask, colorMask); this.currentColorMask = colorMask; } } setDepthTest(depthTest) { const { gl } = this; if (depthTest) { this.enable(gl.DEPTH_TEST); } else { this.disable(gl.DEPTH_TEST); } } setDepthMask(depthMask) { if (this.currentDepthMask !== depthMask) { this.gl.depthMask(depthMask); this.currentDepthMask = depthMask; } } setDepthFunc(depthFunc) { if (this.currentDepthFunc !== depthFunc) { const { gl } = this; switch (depthFunc) { case NeverDepth2: gl.depthFunc(gl.NEVER); break; case AlwaysDepth2: gl.depthFunc(gl.ALWAYS); break; case LessDepth2: gl.depthFunc(gl.LESS); break; case LessEqualDepth2: gl.depthFunc(gl.LEQUAL); break; case EqualDepth2: gl.depthFunc(gl.EQUAL); break; case GreaterEqualDepth2: gl.depthFunc(gl.GEQUAL); break; case GreaterDepth2: gl.depthFunc(gl.GREATER); break; case NotEqualDepth2: gl.depthFunc(gl.NOTEQUAL); break; default: gl.depthFunc(gl.LEQUAL); } this.currentDepthFunc = depthFunc; } } setStencilTest(stencilTest) { const { gl } = this; if (stencilTest) { this.enable(gl.STENCIL_TEST); } else { this.disable(gl.STENCIL_TEST); } } setStencilMask(stencilMask) { if (this.currentStencilMask !== stencilMask) { this.gl.stencilMask(stencilMask); this.currentStencilMask = stencilMask; } } setStencilFunc(stencilFunc, stencilRef, stencilMask) { if (this.currentStencilFunc !== stencilFunc || this.currentStencilRef !== stencilRef || this.currentStencilFuncMask !== stencilMask) { this.gl.stencilFunc(stencilFunc, stencilRef, stencilMask); this.currentStencilFunc = stencilFunc; this.currentStencilRef = stencilRef; this.currentStencilFuncMask = stencilMask; } } setStencilOp(stencilFail, stencilZFail, stencilZPass) { if (this.currentStencilFail !== stencilFail || this.currentStencilZFail !== stencilZFail || this.currentStencilZPass !== stencilZPass) { this.gl.stencilOp(stencilFail, stencilZFail, stencilZPass); this.currentStencilFail = stencilFail; this.currentStencilZFail = stencilZFail; this.currentStencilZPass = stencilZPass; } } setMaterial(material, frontFaceCW) { const { gl } = this; material.side === DoubleSide2 ? this.disable(gl.CULL_FACE) : this.enable(gl.CULL_FACE); let flipSided = material.side === BackSide2; if (frontFaceCW) flipSided = !flipSided; this.setFlipSided(flipSided); material.blending === NormalBlending2 && material.transparent === false ? this.setBlending(NoBlending2) : this.setBlending(material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha); this.setDepthFunc(material.depthFunc); this.setDepthTest(material.depthTest); this.setDepthMask(material.depthWrite); this.setColorMask(material.colorWrite); const stencilWrite = material.stencilWrite; this.setStencilTest(stencilWrite); if (stencilWrite) { this.setStencilMask(material.stencilWriteMask); this.setStencilFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask); this.setStencilOp(material.stencilFail, material.stencilZFail, material.stencilZPass); } this.setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits); material.alphaToCoverage === true && this.backend.renderer.samples > 1 ? this.enable(gl.SAMPLE_ALPHA_TO_COVERAGE) : this.disable(gl.SAMPLE_ALPHA_TO_COVERAGE); } setPolygonOffset(polygonOffset, factor, units) { const { gl } = this; if (polygonOffset) { this.enable(gl.POLYGON_OFFSET_FILL); if (this.currentPolygonOffsetFactor !== factor || this.currentPolygonOffsetUnits !== units) { gl.polygonOffset(factor, units); this.currentPolygonOffsetFactor = factor; this.currentPolygonOffsetUnits = units; } } else { this.disable(gl.POLYGON_OFFSET_FILL); } } useProgram(program) { if (this.currentProgram !== program) { this.gl.useProgram(program); this.currentProgram = program; return true; } return false; } // framebuffer bindFramebuffer(target, framebuffer) { const { gl, currentBoundFramebuffers } = this; if (currentBoundFramebuffers[target] !== framebuffer) { gl.bindFramebuffer(target, framebuffer); currentBoundFramebuffers[target] = framebuffer; if (target === gl.DRAW_FRAMEBUFFER) { currentBoundFramebuffers[gl.FRAMEBUFFER] = framebuffer; } if (target === gl.FRAMEBUFFER) { currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer; } return true; } return false; } drawBuffers(renderContext, framebuffer) { const { gl } = this; let drawBuffers = []; let needsUpdate = false; if (renderContext.textures !== null) { drawBuffers = this.currentDrawbuffers.get(framebuffer); if (drawBuffers === void 0) { drawBuffers = []; this.currentDrawbuffers.set(framebuffer, drawBuffers); } const textures = renderContext.textures; if (drawBuffers.length !== textures.length || drawBuffers[0] !== gl.COLOR_ATTACHMENT0) { for (let i = 0, il = textures.length; i < il; i++) { drawBuffers[i] = gl.COLOR_ATTACHMENT0 + i; } drawBuffers.length = textures.length; needsUpdate = true; } } else { if (drawBuffers[0] !== gl.BACK) { drawBuffers[0] = gl.BACK; needsUpdate = true; } } if (needsUpdate) { gl.drawBuffers(drawBuffers); } } // texture activeTexture(webglSlot) { const { gl, currentTextureSlot, maxTextures } = this; if (webglSlot === void 0) webglSlot = gl.TEXTURE0 + maxTextures - 1; if (currentTextureSlot !== webglSlot) { gl.activeTexture(webglSlot); this.currentTextureSlot = webglSlot; } } bindTexture(webglType, webglTexture, webglSlot) { const { gl, currentTextureSlot, currentBoundTextures, maxTextures } = this; if (webglSlot === void 0) { if (currentTextureSlot === null) { webglSlot = gl.TEXTURE0 + maxTextures - 1; } else { webglSlot = currentTextureSlot; } } let boundTexture = currentBoundTextures[webglSlot]; if (boundTexture === void 0) { boundTexture = { type: void 0, texture: void 0 }; currentBoundTextures[webglSlot] = boundTexture; } if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) { if (currentTextureSlot !== webglSlot) { gl.activeTexture(webglSlot); this.currentTextureSlot = webglSlot; } gl.bindTexture(webglType, webglTexture); boundTexture.type = webglType; boundTexture.texture = webglTexture; } } bindBufferBase(target, index5, buffer2) { const { gl } = this; const key = `${target}-${index5}`; if (this.currentBoundBufferBases[key] !== buffer2) { gl.bindBufferBase(target, index5, buffer2); this.currentBoundBufferBases[key] = buffer2; return true; } return false; } unbindTexture() { const { gl, currentTextureSlot, currentBoundTextures } = this; 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; } } }; var WebGLUtils2 = class { constructor(backend) { this.backend = backend; this.gl = this.backend.gl; this.extensions = backend.extensions; } convert(p, colorSpace = NoColorSpace2) { const { gl, extensions } = this; let extension; if (p === UnsignedByteType2) return gl.UNSIGNED_BYTE; if (p === UnsignedShort4444Type2) return gl.UNSIGNED_SHORT_4_4_4_4; if (p === UnsignedShort5551Type2) return gl.UNSIGNED_SHORT_5_5_5_1; if (p === UnsignedInt5999Type2) return gl.UNSIGNED_INT_5_9_9_9_REV; if (p === ByteType2) return gl.BYTE; if (p === ShortType2) return gl.SHORT; if (p === UnsignedShortType2) return gl.UNSIGNED_SHORT; if (p === IntType2) return gl.INT; if (p === UnsignedIntType2) return gl.UNSIGNED_INT; if (p === FloatType2) return gl.FLOAT; if (p === HalfFloatType2) { return gl.HALF_FLOAT; } if (p === AlphaFormat2) return gl.ALPHA; if (p === RGBFormat2) return gl.RGB; if (p === RGBAFormat2) return gl.RGBA; if (p === LuminanceFormat2) return gl.LUMINANCE; if (p === LuminanceAlphaFormat2) return gl.LUMINANCE_ALPHA; if (p === DepthFormat2) return gl.DEPTH_COMPONENT; if (p === DepthStencilFormat2) return gl.DEPTH_STENCIL; if (p === RedFormat2) return gl.RED; if (p === RedIntegerFormat2) return gl.RED_INTEGER; if (p === RGFormat2) return gl.RG; if (p === RGIntegerFormat2) return gl.RG_INTEGER; if (p === RGBAIntegerFormat2) return gl.RGBA_INTEGER; if (p === RGB_S3TC_DXT1_Format2 || p === RGBA_S3TC_DXT1_Format2 || p === RGBA_S3TC_DXT3_Format2 || p === RGBA_S3TC_DXT5_Format2) { if (colorSpace === SRGBColorSpace2) { extension = extensions.get("WEBGL_compressed_texture_s3tc_srgb"); if (extension !== null) { if (p === RGB_S3TC_DXT1_Format2) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT; if (p === RGBA_S3TC_DXT1_Format2) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; if (p === RGBA_S3TC_DXT3_Format2) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; if (p === RGBA_S3TC_DXT5_Format2) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; } else { return null; } } else { extension = extensions.get("WEBGL_compressed_texture_s3tc"); if (extension !== null) { if (p === RGB_S3TC_DXT1_Format2) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; if (p === RGBA_S3TC_DXT1_Format2) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; if (p === RGBA_S3TC_DXT3_Format2) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; if (p === RGBA_S3TC_DXT5_Format2) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; } else { return null; } } } if (p === RGB_PVRTC_4BPPV1_Format2 || p === RGB_PVRTC_2BPPV1_Format2 || p === RGBA_PVRTC_4BPPV1_Format2 || p === RGBA_PVRTC_2BPPV1_Format2) { extension = extensions.get("WEBGL_compressed_texture_pvrtc"); if (extension !== null) { if (p === RGB_PVRTC_4BPPV1_Format2) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; if (p === RGB_PVRTC_2BPPV1_Format2) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; if (p === RGBA_PVRTC_4BPPV1_Format2) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; if (p === RGBA_PVRTC_2BPPV1_Format2) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; } else { return null; } } if (p === RGB_ETC1_Format2 || p === RGB_ETC2_Format2 || p === RGBA_ETC2_EAC_Format2) { extension = extensions.get("WEBGL_compressed_texture_etc"); if (extension !== null) { if (p === RGB_ETC1_Format2 || p === RGB_ETC2_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2; if (p === RGBA_ETC2_EAC_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC; } else { return null; } } if (p === RGBA_ASTC_4x4_Format2 || p === RGBA_ASTC_5x4_Format2 || p === RGBA_ASTC_5x5_Format2 || p === RGBA_ASTC_6x5_Format2 || p === RGBA_ASTC_6x6_Format2 || p === RGBA_ASTC_8x5_Format2 || p === RGBA_ASTC_8x6_Format2 || p === RGBA_ASTC_8x8_Format2 || p === RGBA_ASTC_10x5_Format2 || p === RGBA_ASTC_10x6_Format2 || p === RGBA_ASTC_10x8_Format2 || p === RGBA_ASTC_10x10_Format2 || p === RGBA_ASTC_12x10_Format2 || p === RGBA_ASTC_12x12_Format2) { extension = extensions.get("WEBGL_compressed_texture_astc"); if (extension !== null) { if (p === RGBA_ASTC_4x4_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR; if (p === RGBA_ASTC_5x4_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR; if (p === RGBA_ASTC_5x5_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR; if (p === RGBA_ASTC_6x5_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR; if (p === RGBA_ASTC_6x6_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR; if (p === RGBA_ASTC_8x5_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR; if (p === RGBA_ASTC_8x6_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR; if (p === RGBA_ASTC_8x8_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR; if (p === RGBA_ASTC_10x5_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR; if (p === RGBA_ASTC_10x6_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR; if (p === RGBA_ASTC_10x8_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR; if (p === RGBA_ASTC_10x10_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR; if (p === RGBA_ASTC_12x10_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR; if (p === RGBA_ASTC_12x12_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR; } else { return null; } } if (p === RGBA_BPTC_Format2) { extension = extensions.get("EXT_texture_compression_bptc"); if (extension !== null) { if (p === RGBA_BPTC_Format2) return colorSpace === SRGBColorSpace2 ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT; } else { return null; } } if (p === RED_RGTC1_Format2 || p === SIGNED_RED_RGTC1_Format2 || p === RED_GREEN_RGTC2_Format2 || p === SIGNED_RED_GREEN_RGTC2_Format2) { extension = extensions.get("EXT_texture_compression_rgtc"); if (extension !== null) { if (p === RGBA_BPTC_Format2) return extension.COMPRESSED_RED_RGTC1_EXT; if (p === SIGNED_RED_RGTC1_Format2) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT; if (p === RED_GREEN_RGTC2_Format2) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT; if (p === SIGNED_RED_GREEN_RGTC2_Format2) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT; } else { return null; } } if (p === UnsignedInt248Type2) { return gl.UNSIGNED_INT_24_8; } return gl[p] !== void 0 ? gl[p] : null; } _clientWaitAsync() { const { gl } = this; const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0); gl.flush(); return new Promise((resolve, reject) => { function test() { const res = gl.clientWaitSync(sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0); if (res === gl.WAIT_FAILED) { gl.deleteSync(sync); reject(); return; } if (res === gl.TIMEOUT_EXPIRED) { requestAnimationFrame(test); return; } gl.deleteSync(sync); resolve(); } test(); }); } }; var initialized = false; var wrappingToGL; var filterToGL; var compareToGL; var WebGLTextureUtils = class { constructor(backend) { this.backend = backend; this.gl = backend.gl; this.extensions = backend.extensions; this.defaultTextures = {}; if (initialized === false) { this._init(this.gl); initialized = true; } } _init(gl) { wrappingToGL = { [RepeatWrapping2]: gl.REPEAT, [ClampToEdgeWrapping2]: gl.CLAMP_TO_EDGE, [MirroredRepeatWrapping2]: gl.MIRRORED_REPEAT }; filterToGL = { [NearestFilter2]: gl.NEAREST, [NearestMipmapNearestFilter2]: gl.NEAREST_MIPMAP_NEAREST, [NearestMipmapLinearFilter2]: gl.NEAREST_MIPMAP_LINEAR, [LinearFilter2]: gl.LINEAR, [LinearMipmapNearestFilter2]: gl.LINEAR_MIPMAP_NEAREST, [LinearMipmapLinearFilter2]: gl.LINEAR_MIPMAP_LINEAR }; compareToGL = { [NeverCompare2]: gl.NEVER, [AlwaysCompare2]: gl.ALWAYS, [LessCompare2]: gl.LESS, [LessEqualCompare2]: gl.LEQUAL, [EqualCompare2]: gl.EQUAL, [GreaterEqualCompare2]: gl.GEQUAL, [GreaterCompare2]: gl.GREATER, [NotEqualCompare2]: gl.NOTEQUAL }; } filterFallback(f) { const { gl } = this; if (f === NearestFilter2 || f === NearestMipmapNearestFilter2 || f === NearestMipmapLinearFilter2) { return gl.NEAREST; } return gl.LINEAR; } getGLTextureType(texture2) { const { gl } = this; let glTextureType; if (texture2.isCubeTexture === true) { glTextureType = gl.TEXTURE_CUBE_MAP; } else if (texture2.isDataArrayTexture === true || texture2.isCompressedArrayTexture === true) { glTextureType = gl.TEXTURE_2D_ARRAY; } else if (texture2.isData3DTexture === true) { glTextureType = gl.TEXTURE_3D; } else { glTextureType = gl.TEXTURE_2D; } return glTextureType; } getInternalFormat(internalFormatName, glFormat, glType, colorSpace, forceLinearTransfer = false) { const { gl, extensions } = this; 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 === gl.RED) { if (glType === gl.FLOAT) internalFormat = gl.R32F; if (glType === gl.HALF_FLOAT) internalFormat = gl.R16F; if (glType === gl.UNSIGNED_BYTE) internalFormat = gl.R8; if (glType === gl.UNSIGNED_SHORT) internalFormat = gl.R16; if (glType === gl.UNSIGNED_INT) internalFormat = gl.R32UI; if (glType === gl.BYTE) internalFormat = gl.R8I; if (glType === gl.SHORT) internalFormat = gl.R16I; if (glType === gl.INT) internalFormat = gl.R32I; } if (glFormat === gl.RED_INTEGER) { if (glType === gl.UNSIGNED_BYTE) internalFormat = gl.R8UI; if (glType === gl.UNSIGNED_SHORT) internalFormat = gl.R16UI; if (glType === gl.UNSIGNED_INT) internalFormat = gl.R32UI; if (glType === gl.BYTE) internalFormat = gl.R8I; if (glType === gl.SHORT) internalFormat = gl.R16I; if (glType === gl.INT) internalFormat = gl.R32I; } if (glFormat === gl.RG) { if (glType === gl.FLOAT) internalFormat = gl.RG32F; if (glType === gl.HALF_FLOAT) internalFormat = gl.RG16F; if (glType === gl.UNSIGNED_BYTE) internalFormat = gl.RG8; if (glType === gl.UNSIGNED_SHORT) internalFormat = gl.RG16; if (glType === gl.UNSIGNED_INT) internalFormat = gl.RG32UI; if (glType === gl.BYTE) internalFormat = gl.RG8I; if (glType === gl.SHORT) internalFormat = gl.RG16I; if (glType === gl.INT) internalFormat = gl.RG32I; } if (glFormat === gl.RG_INTEGER) { if (glType === gl.UNSIGNED_BYTE) internalFormat = gl.RG8UI; if (glType === gl.UNSIGNED_SHORT) internalFormat = gl.RG16UI; if (glType === gl.UNSIGNED_INT) internalFormat = gl.RG32UI; if (glType === gl.BYTE) internalFormat = gl.RG8I; if (glType === gl.SHORT) internalFormat = gl.RG16I; if (glType === gl.INT) internalFormat = gl.RG32I; } if (glFormat === gl.RGB) { if (glType === gl.FLOAT) internalFormat = gl.RGB32F; if (glType === gl.HALF_FLOAT) internalFormat = gl.RGB16F; if (glType === gl.UNSIGNED_BYTE) internalFormat = gl.RGB8; if (glType === gl.UNSIGNED_SHORT) internalFormat = gl.RGB16; if (glType === gl.UNSIGNED_INT) internalFormat = gl.RGB32UI; if (glType === gl.BYTE) internalFormat = gl.RGB8I; if (glType === gl.SHORT) internalFormat = gl.RGB16I; if (glType === gl.INT) internalFormat = gl.RGB32I; if (glType === gl.UNSIGNED_BYTE) internalFormat = colorSpace === SRGBColorSpace2 && forceLinearTransfer === false ? gl.SRGB8 : gl.RGB8; if (glType === gl.UNSIGNED_SHORT_5_6_5) internalFormat = gl.RGB565; if (glType === gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = gl.RGB5_A1; if (glType === gl.UNSIGNED_SHORT_4_4_4_4) internalFormat = gl.RGB4; if (glType === gl.UNSIGNED_INT_5_9_9_9_REV) internalFormat = gl.RGB9_E5; } if (glFormat === gl.RGB_INTEGER) { if (glType === gl.UNSIGNED_BYTE) internalFormat = gl.RGB8UI; if (glType === gl.UNSIGNED_SHORT) internalFormat = gl.RGB16UI; if (glType === gl.UNSIGNED_INT) internalFormat = gl.RGB32UI; if (glType === gl.BYTE) internalFormat = gl.RGB8I; if (glType === gl.SHORT) internalFormat = gl.RGB16I; if (glType === gl.INT) internalFormat = gl.RGB32I; } if (glFormat === gl.RGBA) { if (glType === gl.FLOAT) internalFormat = gl.RGBA32F; if (glType === gl.HALF_FLOAT) internalFormat = gl.RGBA16F; if (glType === gl.UNSIGNED_BYTE) internalFormat = gl.RGBA8; if (glType === gl.UNSIGNED_SHORT) internalFormat = gl.RGBA16; if (glType === gl.UNSIGNED_INT) internalFormat = gl.RGBA32UI; if (glType === gl.BYTE) internalFormat = gl.RGBA8I; if (glType === gl.SHORT) internalFormat = gl.RGBA16I; if (glType === gl.INT) internalFormat = gl.RGBA32I; if (glType === gl.UNSIGNED_BYTE) internalFormat = colorSpace === SRGBColorSpace2 && forceLinearTransfer === false ? gl.SRGB8_ALPHA8 : gl.RGBA8; if (glType === gl.UNSIGNED_SHORT_4_4_4_4) internalFormat = gl.RGBA4; if (glType === gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = gl.RGB5_A1; } if (glFormat === gl.RGBA_INTEGER) { if (glType === gl.UNSIGNED_BYTE) internalFormat = gl.RGBA8UI; if (glType === gl.UNSIGNED_SHORT) internalFormat = gl.RGBA16UI; if (glType === gl.UNSIGNED_INT) internalFormat = gl.RGBA32UI; if (glType === gl.BYTE) internalFormat = gl.RGBA8I; if (glType === gl.SHORT) internalFormat = gl.RGBA16I; if (glType === gl.INT) internalFormat = gl.RGBA32I; } if (glFormat === gl.DEPTH_COMPONENT) { if (glType === gl.UNSIGNED_INT) internalFormat = gl.DEPTH24_STENCIL8; if (glType === gl.FLOAT) internalFormat = gl.DEPTH_COMPONENT32F; } if (glFormat === gl.DEPTH_STENCIL) { if (glType === gl.UNSIGNED_INT_24_8) internalFormat = gl.DEPTH24_STENCIL8; } if (internalFormat === gl.R16F || internalFormat === gl.R32F || internalFormat === gl.RG16F || internalFormat === gl.RG32F || internalFormat === gl.RGBA16F || internalFormat === gl.RGBA32F) { extensions.get("EXT_color_buffer_float"); } return internalFormat; } setTextureParameters(textureType, texture2) { const { gl, extensions, backend } = this; gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture2.flipY); gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture2.premultiplyAlpha); gl.pixelStorei(gl.UNPACK_ALIGNMENT, texture2.unpackAlignment); gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE); gl.texParameteri(textureType, gl.TEXTURE_WRAP_S, wrappingToGL[texture2.wrapS]); gl.texParameteri(textureType, gl.TEXTURE_WRAP_T, wrappingToGL[texture2.wrapT]); if (textureType === gl.TEXTURE_3D || textureType === gl.TEXTURE_2D_ARRAY) { gl.texParameteri(textureType, gl.TEXTURE_WRAP_R, wrappingToGL[texture2.wrapR]); } gl.texParameteri(textureType, gl.TEXTURE_MAG_FILTER, filterToGL[texture2.magFilter]); const hasMipmaps = texture2.mipmaps !== void 0 && texture2.mipmaps.length > 0; const minFilter = texture2.minFilter === LinearFilter2 && hasMipmaps ? LinearMipmapLinearFilter2 : texture2.minFilter; gl.texParameteri(textureType, gl.TEXTURE_MIN_FILTER, filterToGL[minFilter]); if (texture2.compareFunction) { gl.texParameteri(textureType, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE); gl.texParameteri(textureType, gl.TEXTURE_COMPARE_FUNC, compareToGL[texture2.compareFunction]); } if (extensions.has("EXT_texture_filter_anisotropic") === true) { if (texture2.magFilter === NearestFilter2) return; if (texture2.minFilter !== NearestMipmapLinearFilter2 && texture2.minFilter !== LinearMipmapLinearFilter2) return; if (texture2.type === FloatType2 && extensions.has("OES_texture_float_linear") === false) return; if (texture2.anisotropy > 1) { const extension = extensions.get("EXT_texture_filter_anisotropic"); gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture2.anisotropy, backend.getMaxAnisotropy())); } } } createDefaultTexture(texture2) { const { gl, backend, defaultTextures } = this; const glTextureType = this.getGLTextureType(texture2); let textureGPU = defaultTextures[glTextureType]; if (textureGPU === void 0) { textureGPU = gl.createTexture(); backend.state.bindTexture(glTextureType, textureGPU); gl.texParameteri(glTextureType, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(glTextureType, gl.TEXTURE_MAG_FILTER, gl.NEAREST); defaultTextures[glTextureType] = textureGPU; } backend.set(texture2, { textureGPU, glTextureType, isDefault: true }); } createTexture(texture2, options) { const { gl, backend } = this; const { levels, width, height, depth: depth2 } = options; const glFormat = backend.utils.convert(texture2.format, texture2.colorSpace); const glType = backend.utils.convert(texture2.type); const glInternalFormat = this.getInternalFormat(texture2.internalFormat, glFormat, glType, texture2.colorSpace, texture2.isVideoTexture); const textureGPU = gl.createTexture(); const glTextureType = this.getGLTextureType(texture2); backend.state.bindTexture(glTextureType, textureGPU); this.setTextureParameters(glTextureType, texture2); if (texture2.isDataArrayTexture || texture2.isCompressedArrayTexture) { gl.texStorage3D(gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, width, height, depth2); } else if (texture2.isData3DTexture) { gl.texStorage3D(gl.TEXTURE_3D, levels, glInternalFormat, width, height, depth2); } else if (!texture2.isVideoTexture) { gl.texStorage2D(glTextureType, levels, glInternalFormat, width, height); } backend.set(texture2, { textureGPU, glTextureType, glFormat, glType, glInternalFormat }); } copyBufferToTexture(buffer2, texture2) { const { gl, backend } = this; const { textureGPU, glTextureType, glFormat, glType } = backend.get(texture2); const { width, height } = texture2.source.data; gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buffer2); backend.state.bindTexture(glTextureType, textureGPU); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); gl.texSubImage2D(glTextureType, 0, 0, 0, width, height, glFormat, glType, 0); gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null); backend.state.unbindTexture(); } updateTexture(texture2, options) { const { gl } = this; const { width, height } = options; const { textureGPU, glTextureType, glFormat, glType, glInternalFormat } = this.backend.get(texture2); if (texture2.isRenderTargetTexture || textureGPU === void 0) return; const getImage = (source) => { if (source.isDataTexture) { return source.image.data; } else if (source instanceof ImageBitmap || source instanceof OffscreenCanvas || source instanceof HTMLImageElement || source instanceof HTMLCanvasElement) { return source; } return source.data; }; this.backend.state.bindTexture(glTextureType, textureGPU); this.setTextureParameters(glTextureType, texture2); if (texture2.isCompressedTexture) { const mipmaps = texture2.mipmaps; const image = options.image; for (let i = 0; i < mipmaps.length; i++) { const mipmap = mipmaps[i]; if (texture2.isCompressedArrayTexture) { if (texture2.format !== gl.RGBA) { if (glFormat !== null) { gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data); } else { console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"); } } else { gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data); } } else { if (glFormat !== null) { gl.compressedTexSubImage2D(gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); } else { console.warn("Unsupported compressed texture format"); } } } } else if (texture2.isCubeTexture) { const images = options.images; for (let i = 0; i < 6; i++) { const image = getImage(images[i]); gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, width, height, glFormat, glType, image); } } else if (texture2.isDataArrayTexture) { const image = options.image; gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); } else if (texture2.isData3DTexture) { const image = options.image; gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); } else if (texture2.isVideoTexture) { texture2.update(); gl.texImage2D(glTextureType, 0, glInternalFormat, glFormat, glType, options.image); } else { const image = getImage(options.image); gl.texSubImage2D(glTextureType, 0, 0, 0, width, height, glFormat, glType, image); } } generateMipmaps(texture2) { const { gl, backend } = this; const { textureGPU, glTextureType } = backend.get(texture2); backend.state.bindTexture(glTextureType, textureGPU); gl.generateMipmap(glTextureType); } deallocateRenderBuffers(renderTarget) { const { gl, backend } = this; if (renderTarget) { const renderContextData = backend.get(renderTarget); renderContextData.renderBufferStorageSetup = void 0; if (renderContextData.framebuffers) { for (const cacheKey in renderContextData.framebuffers) { gl.deleteFramebuffer(renderContextData.framebuffers[cacheKey]); } delete renderContextData.framebuffers; } if (renderContextData.depthRenderbuffer) { gl.deleteRenderbuffer(renderContextData.depthRenderbuffer); delete renderContextData.depthRenderbuffer; } if (renderContextData.stencilRenderbuffer) { gl.deleteRenderbuffer(renderContextData.stencilRenderbuffer); delete renderContextData.stencilRenderbuffer; } if (renderContextData.msaaFrameBuffer) { gl.deleteFramebuffer(renderContextData.msaaFrameBuffer); delete renderContextData.msaaFrameBuffer; } if (renderContextData.msaaRenderbuffers) { for (let i = 0; i < renderContextData.msaaRenderbuffers.length; i++) { gl.deleteRenderbuffer(renderContextData.msaaRenderbuffers[i]); } delete renderContextData.msaaRenderbuffers; } } } destroyTexture(texture2) { const { gl, backend } = this; const { textureGPU, renderTarget } = backend.get(texture2); this.deallocateRenderBuffers(renderTarget); gl.deleteTexture(textureGPU); backend.delete(texture2); } copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { const { gl, backend } = this; const { state } = this.backend; const { textureGPU: dstTextureGPU, glTextureType, glType, glFormat } = backend.get(dstTexture); let width, height, minX, minY; let dstX, dstY; if (srcRegion !== null) { width = srcRegion.max.x - srcRegion.min.x; height = srcRegion.max.y - srcRegion.min.y; minX = srcRegion.min.x; minY = srcRegion.min.y; } else { width = srcTexture.image.width; height = srcTexture.image.height; minX = 0; minY = 0; } if (dstPosition !== null) { dstX = dstPosition.x; dstY = dstPosition.y; } else { dstX = 0; dstY = 0; } state.bindTexture(glTextureType, dstTextureGPU); gl.pixelStorei(gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY); gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha); gl.pixelStorei(gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment); const currentUnpackRowLen = gl.getParameter(gl.UNPACK_ROW_LENGTH); const currentUnpackImageHeight = gl.getParameter(gl.UNPACK_IMAGE_HEIGHT); const currentUnpackSkipPixels = gl.getParameter(gl.UNPACK_SKIP_PIXELS); const currentUnpackSkipRows = gl.getParameter(gl.UNPACK_SKIP_ROWS); const currentUnpackSkipImages = gl.getParameter(gl.UNPACK_SKIP_IMAGES); const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[level] : srcTexture.image; gl.pixelStorei(gl.UNPACK_ROW_LENGTH, image.width); gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, image.height); gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, minX); gl.pixelStorei(gl.UNPACK_SKIP_ROWS, minY); if (srcTexture.isRenderTargetTexture || srcTexture.isDepthTexture) { const srcTextureData = backend.get(srcTexture); const dstTextureData = backend.get(dstTexture); const srcRenderContextData = backend.get(srcTextureData.renderTarget); const dstRenderContextData = backend.get(dstTextureData.renderTarget); const srcFramebuffer = srcRenderContextData.framebuffers[srcTextureData.cacheKey]; const dstFramebuffer = dstRenderContextData.framebuffers[dstTextureData.cacheKey]; state.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFramebuffer); state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFramebuffer); let mask = gl.COLOR_BUFFER_BIT; if (srcTexture.isDepthTexture) mask = gl.DEPTH_BUFFER_BIT; gl.blitFramebuffer(minX, minY, width, height, dstX, dstY, width, height, mask, gl.NEAREST); state.bindFramebuffer(gl.READ_FRAMEBUFFER, null); state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); } else { if (srcTexture.isDataTexture) { gl.texSubImage2D(gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image.data); } else { if (srcTexture.isCompressedTexture) { gl.compressedTexSubImage2D(gl.TEXTURE_2D, level, dstX, dstY, image.width, image.height, glFormat, image.data); } else { gl.texSubImage2D(gl.TEXTURE_2D, level, dstX, dstY, width, height, glFormat, glType, image); } } } gl.pixelStorei(gl.UNPACK_ROW_LENGTH, currentUnpackRowLen); gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight); gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels); gl.pixelStorei(gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows); gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages); if (level === 0 && dstTexture.generateMipmaps) gl.generateMipmap(gl.TEXTURE_2D); state.unbindTexture(); } copyFramebufferToTexture(texture2, renderContext, rectangle) { const { gl } = this; const { state } = this.backend; const { textureGPU } = this.backend.get(texture2); const { x: x2, y: y2, z: width, w: height } = rectangle; const requireDrawFrameBuffer = texture2.isDepthTexture === true || renderContext.renderTarget && renderContext.renderTarget.samples > 0; const srcHeight = renderContext.renderTarget ? renderContext.renderTarget.height : this.backend.gerDrawingBufferSize().y; if (requireDrawFrameBuffer) { const partial = x2 !== 0 || y2 !== 0; let mask; let attachment; if (texture2.isDepthTexture === true) { mask = gl.DEPTH_BUFFER_BIT; attachment = gl.DEPTH_ATTACHMENT; if (renderContext.stencil) { mask |= gl.STENCIL_BUFFER_BIT; } } else { mask = gl.COLOR_BUFFER_BIT; attachment = gl.COLOR_ATTACHMENT0; } if (partial) { const renderTargetContextData = this.backend.get(renderContext.renderTarget); const fb = renderTargetContextData.framebuffers[renderContext.getCacheKey()]; const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer; state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb); state.bindFramebuffer(gl.READ_FRAMEBUFFER, msaaFrameBuffer); const flippedY = srcHeight - y2 - height; gl.blitFramebuffer(x2, flippedY, x2 + width, flippedY + height, x2, flippedY, x2 + width, flippedY + height, mask, gl.NEAREST); state.bindFramebuffer(gl.READ_FRAMEBUFFER, fb); state.bindTexture(gl.TEXTURE_2D, textureGPU); gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, x2, flippedY, width, height); state.unbindTexture(); } else { const fb = gl.createFramebuffer(); state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb); gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureGPU, 0); gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, gl.NEAREST); gl.deleteFramebuffer(fb); } } else { state.bindTexture(gl.TEXTURE_2D, textureGPU); gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, x2, srcHeight - height - y2, width, height); state.unbindTexture(); } if (texture2.generateMipmaps) this.generateMipmaps(texture2); this.backend._setFramebuffer(renderContext); } // Setup storage for internal depth/stencil buffers and bind to correct framebuffer setupRenderBufferStorage(renderbuffer, renderContext) { const { gl } = this; const renderTarget = renderContext.renderTarget; const { samples, depthTexture, depthBuffer, stencilBuffer, width, height } = renderTarget; gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); if (depthBuffer && !stencilBuffer) { let glInternalFormat = gl.DEPTH_COMPONENT24; if (samples > 0) { if (depthTexture && depthTexture.isDepthTexture) { if (depthTexture.type === gl.FLOAT) { glInternalFormat = gl.DEPTH_COMPONENT32F; } } gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, glInternalFormat, width, height); } else { gl.renderbufferStorage(gl.RENDERBUFFER, glInternalFormat, width, height); } gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); } else if (depthBuffer && stencilBuffer) { if (samples > 0) { gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, gl.DEPTH24_STENCIL8, width, height); } else { gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); } gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, renderbuffer); } } async copyTextureToBuffer(texture2, x2, y2, width, height, faceIndex) { const { backend, gl } = this; const { textureGPU, glFormat, glType } = this.backend.get(texture2); const fb = gl.createFramebuffer(); gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb); const target = texture2.isCubeTexture ? gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex : gl.TEXTURE_2D; gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, target, textureGPU, 0); const typedArrayType = this._getTypedArrayType(glType); const bytesPerTexel = this._getBytesPerTexel(glType, glFormat); const elementCount = width * height; const byteLength = elementCount * bytesPerTexel; const buffer2 = gl.createBuffer(); gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buffer2); gl.bufferData(gl.PIXEL_PACK_BUFFER, byteLength, gl.STREAM_READ); gl.readPixels(x2, y2, width, height, glFormat, glType, 0); gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); await backend.utils._clientWaitAsync(); const dstBuffer = new typedArrayType(byteLength / typedArrayType.BYTES_PER_ELEMENT); gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buffer2); gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, dstBuffer); gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); gl.deleteFramebuffer(fb); return dstBuffer; } _getTypedArrayType(glType) { const { gl } = this; if (glType === gl.UNSIGNED_BYTE) return Uint8Array; if (glType === gl.UNSIGNED_SHORT_4_4_4_4) return Uint16Array; if (glType === gl.UNSIGNED_SHORT_5_5_5_1) return Uint16Array; if (glType === gl.UNSIGNED_SHORT_5_6_5) return Uint16Array; if (glType === gl.UNSIGNED_SHORT) return Uint16Array; if (glType === gl.UNSIGNED_INT) return Uint32Array; if (glType === gl.HALF_FLOAT) return Uint16Array; if (glType === gl.FLOAT) return Float32Array; throw new Error(`Unsupported WebGL type: ${glType}`); } _getBytesPerTexel(glType, glFormat) { const { gl } = this; let bytesPerComponent = 0; if (glType === gl.UNSIGNED_BYTE) bytesPerComponent = 1; if (glType === gl.UNSIGNED_SHORT_4_4_4_4 || glType === gl.UNSIGNED_SHORT_5_5_5_1 || glType === gl.UNSIGNED_SHORT_5_6_5 || glType === gl.UNSIGNED_SHORT || glType === gl.HALF_FLOAT) bytesPerComponent = 2; if (glType === gl.UNSIGNED_INT || glType === gl.FLOAT) bytesPerComponent = 4; if (glFormat === gl.RGBA) return bytesPerComponent * 4; if (glFormat === gl.RGB) return bytesPerComponent * 3; if (glFormat === gl.ALPHA) return bytesPerComponent; } }; var WebGLExtensions2 = class { constructor(backend) { this.backend = backend; this.gl = this.backend.gl; this.availableExtensions = this.gl.getSupportedExtensions(); this.extensions = {}; } get(name) { let extension = this.extensions[name]; if (extension === void 0) { extension = this.gl.getExtension(name); this.extensions[name] = extension; } return extension; } has(name) { return this.availableExtensions.includes(name); } }; var WebGLCapabilities2 = class { constructor(backend) { this.backend = backend; this.maxAnisotropy = null; } getMaxAnisotropy() { if (this.maxAnisotropy !== null) return this.maxAnisotropy; const gl = this.backend.gl; const extensions = this.backend.extensions; if (extensions.has("EXT_texture_filter_anisotropic") === true) { const extension = extensions.get("EXT_texture_filter_anisotropic"); this.maxAnisotropy = gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT); } else { this.maxAnisotropy = 0; } return this.maxAnisotropy; } }; var GLFeatureName = { "WEBGL_multi_draw": "WEBGL_multi_draw", "WEBGL_compressed_texture_astc": "texture-compression-astc", "WEBGL_compressed_texture_etc": "texture-compression-etc2", "WEBGL_compressed_texture_etc1": "texture-compression-etc1", "WEBGL_compressed_texture_pvrtc": "texture-compression-pvrtc", "WEBKIT_WEBGL_compressed_texture_pvrtc": "texture-compression-pvrtc", "WEBGL_compressed_texture_s3tc": "texture-compression-bc", "EXT_texture_compression_bptc": "texture-compression-bptc", "EXT_disjoint_timer_query_webgl2": "timestamp-query" }; var WebGLBufferRenderer2 = class { constructor(backend) { this.gl = backend.gl; this.extensions = backend.extensions; this.info = backend.renderer.info; this.mode = null; this.index = 0; this.type = null; this.object = null; } render(start, count) { const { gl, mode, object, type, info, index: index5 } = this; if (index5 !== 0) { gl.drawElements(mode, count, type, start); } else { gl.drawArrays(mode, start, count); } info.update(object, count, mode, 1); } renderInstances(start, count, primcount) { const { gl, mode, type, index: index5, object, info } = this; if (primcount === 0) return; if (index5 !== 0) { gl.drawElementsInstanced(mode, count, type, start, primcount); } else { gl.drawArraysInstanced(mode, start, count, primcount); } info.update(object, count, mode, primcount); } renderMultiDraw(starts, counts, drawCount) { const { extensions, mode, object, info } = this; if (drawCount === 0) return; const extension = extensions.get("WEBGL_multi_draw"); if (extension === null) { for (let i = 0; i < drawCount; i++) { this.render(starts[i], counts[i]); } } else { if (this.index !== 0) { extension.multiDrawElementsWEBGL(mode, counts, 0, this.type, starts, 0, drawCount); } else { extension.multiDrawArraysWEBGL(mode, starts, 0, counts, 0, drawCount); } let elementCount = 0; for (let i = 0; i < drawCount; i++) { elementCount += counts[i]; } info.update(object, elementCount, mode, 1); } } renderMultiDrawInstances(starts, counts, drawCount, primcount) { const { extensions, mode, object, info } = this; if (drawCount === 0) return; const extension = extensions.get("WEBGL_multi_draw"); if (extension === null) { for (let i = 0; i < drawCount; i++) { this.renderInstances(starts[i], counts[i], primcount[i]); } } else { if (this.index !== 0) { extension.multiDrawElementsInstancedWEBGL(mode, counts, 0, this.type, starts, 0, primcount, 0, drawCount); } else { extension.multiDrawArraysInstancedWEBGL(mode, starts, 0, counts, 0, primcount, 0, drawCount); } let elementCount = 0; for (let i = 0; i < drawCount; i++) { elementCount += counts[i] * primcount[i]; } info.update(object, elementCount, mode, 1); } } // }; var WebGLBackend = class extends Backend { constructor(parameters = {}) { super(parameters); this.isWebGLBackend = true; } init(renderer3) { super.init(renderer3); const parameters = this.parameters; const glContext = parameters.context !== void 0 ? parameters.context : renderer3.domElement.getContext("webgl2"); function onContextLost(event) { event.preventDefault(); const contextLossInfo = { api: "WebGL", message: event.statusMessage || "Unknown reason", reason: null, originalEvent: event }; renderer3.onDeviceLost(contextLossInfo); } this._onContextLost = onContextLost; renderer3.domElement.addEventListener("webglcontextlost", onContextLost, false); this.gl = glContext; this.extensions = new WebGLExtensions2(this); this.capabilities = new WebGLCapabilities2(this); this.attributeUtils = new WebGLAttributeUtils(this); this.textureUtils = new WebGLTextureUtils(this); this.bufferRenderer = new WebGLBufferRenderer2(this); this.state = new WebGLState2(this); this.utils = new WebGLUtils2(this); this.vaoCache = {}; this.transformFeedbackCache = {}; this.discard = false; this.trackTimestamp = parameters.trackTimestamp === true; this.extensions.get("EXT_color_buffer_float"); this.extensions.get("WEBGL_clip_cull_distance"); this.extensions.get("OES_texture_float_linear"); this.extensions.get("EXT_color_buffer_half_float"); this.extensions.get("WEBGL_multisampled_render_to_texture"); this.extensions.get("WEBGL_render_shared_exponent"); this.extensions.get("WEBGL_multi_draw"); this.disjoint = this.extensions.get("EXT_disjoint_timer_query_webgl2"); this.parallel = this.extensions.get("KHR_parallel_shader_compile"); this._knownBindings = /* @__PURE__ */ new WeakSet(); this._currentContext = null; } get coordinateSystem() { return WebGLCoordinateSystem2; } async getArrayBufferAsync(attribute2) { return await this.attributeUtils.getArrayBufferAsync(attribute2); } async waitForGPU() { await this.utils._clientWaitAsync(); } initTimestampQuery(renderContext) { if (!this.disjoint || !this.trackTimestamp) return; const renderContextData = this.get(renderContext); if (this.queryRunning) { if (!renderContextData.queryQueue) renderContextData.queryQueue = []; renderContextData.queryQueue.push(renderContext); return; } if (renderContextData.activeQuery) { this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); renderContextData.activeQuery = null; } renderContextData.activeQuery = this.gl.createQuery(); if (renderContextData.activeQuery !== null) { this.gl.beginQuery(this.disjoint.TIME_ELAPSED_EXT, renderContextData.activeQuery); this.queryRunning = true; } } // timestamp utils prepareTimestampBuffer(renderContext) { if (!this.disjoint || !this.trackTimestamp) return; const renderContextData = this.get(renderContext); if (renderContextData.activeQuery) { this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; renderContextData.gpuQueries.push({ query: renderContextData.activeQuery }); renderContextData.activeQuery = null; this.queryRunning = false; if (renderContextData.queryQueue && renderContextData.queryQueue.length > 0) { const nextRenderContext = renderContextData.queryQueue.shift(); this.initTimestampQuery(nextRenderContext); } } } async resolveTimestampAsync(renderContext, type = "render") { if (!this.disjoint || !this.trackTimestamp) return; const renderContextData = this.get(renderContext); if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; for (let i = 0; i < renderContextData.gpuQueries.length; i++) { const queryInfo = renderContextData.gpuQueries[i]; const available = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT_AVAILABLE); const disjoint = this.gl.getParameter(this.disjoint.GPU_DISJOINT_EXT); if (available && !disjoint) { const elapsed = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT); const duration = Number(elapsed) / 1e6; this.gl.deleteQuery(queryInfo.query); renderContextData.gpuQueries.splice(i, 1); i--; this.renderer.info.updateTimestamp(type, duration); } } } getContext() { return this.gl; } beginRender(renderContext) { const { gl } = this; const renderContextData = this.get(renderContext); this.initTimestampQuery(renderContext); renderContextData.previousContext = this._currentContext; this._currentContext = renderContext; this._setFramebuffer(renderContext); this.clear(renderContext.clearColor, renderContext.clearDepth, renderContext.clearStencil, renderContext, false); if (renderContext.viewport) { this.updateViewport(renderContext); } else { gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); } if (renderContext.scissor) { const { x: x2, y: y2, width, height } = renderContext.scissorValue; gl.scissor(x2, renderContext.height - height - y2, width, height); } const occlusionQueryCount = renderContext.occlusionQueryCount; if (occlusionQueryCount > 0) { renderContextData.currentOcclusionQueries = renderContextData.occlusionQueries; renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; renderContextData.lastOcclusionObject = null; renderContextData.occlusionQueries = new Array(occlusionQueryCount); renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); renderContextData.occlusionQueryIndex = 0; } } finishRender(renderContext) { const { gl, state } = this; const renderContextData = this.get(renderContext); const previousContext = renderContextData.previousContext; const occlusionQueryCount = renderContext.occlusionQueryCount; if (occlusionQueryCount > 0) { if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { gl.endQuery(gl.ANY_SAMPLES_PASSED); } this.resolveOccludedAsync(renderContext); } const textures = renderContext.textures; if (textures !== null) { for (let i = 0; i < textures.length; i++) { const texture2 = textures[i]; if (texture2.generateMipmaps) { this.generateMipmaps(texture2); } } } this._currentContext = previousContext; if (renderContext.textures !== null && renderContext.renderTarget) { const renderTargetContextData = this.get(renderContext.renderTarget); const { samples } = renderContext.renderTarget; if (samples > 0) { const fb = renderTargetContextData.framebuffers[renderContext.getCacheKey()]; const mask = gl.COLOR_BUFFER_BIT; const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer; const textures2 = renderContext.textures; state.bindFramebuffer(gl.READ_FRAMEBUFFER, msaaFrameBuffer); state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb); for (let i = 0; i < textures2.length; i++) { if (renderContext.scissor) { const { x: x2, y: y2, width, height } = renderContext.scissorValue; const viewY = renderContext.height - height - y2; gl.blitFramebuffer(x2, viewY, x2 + width, viewY + height, x2, viewY, x2 + width, viewY + height, mask, gl.NEAREST); gl.invalidateSubFramebuffer(gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray, x2, viewY, width, height); } else { gl.blitFramebuffer(0, 0, renderContext.width, renderContext.height, 0, 0, renderContext.width, renderContext.height, mask, gl.NEAREST); gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray); } } } } if (previousContext !== null) { this._setFramebuffer(previousContext); if (previousContext.viewport) { this.updateViewport(previousContext); } else { gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); } } this.prepareTimestampBuffer(renderContext); } resolveOccludedAsync(renderContext) { const renderContextData = this.get(renderContext); const { currentOcclusionQueries, currentOcclusionQueryObjects } = renderContextData; if (currentOcclusionQueries && currentOcclusionQueryObjects) { const occluded = /* @__PURE__ */ new WeakSet(); const { gl } = this; renderContextData.currentOcclusionQueryObjects = null; renderContextData.currentOcclusionQueries = null; const check = () => { let completed = 0; for (let i = 0; i < currentOcclusionQueries.length; i++) { const query = currentOcclusionQueries[i]; if (query === null) continue; if (gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) { if (gl.getQueryParameter(query, gl.QUERY_RESULT) > 0) occluded.add(currentOcclusionQueryObjects[i]); currentOcclusionQueries[i] = null; gl.deleteQuery(query); completed++; } } if (completed < currentOcclusionQueries.length) { requestAnimationFrame(check); } else { renderContextData.occluded = occluded; } }; check(); } } isOccluded(renderContext, object) { const renderContextData = this.get(renderContext); return renderContextData.occluded && renderContextData.occluded.has(object); } updateViewport(renderContext) { const gl = this.gl; const { x: x2, y: y2, width, height } = renderContext.viewportValue; gl.viewport(x2, renderContext.height - height - y2, width, height); } setScissorTest(boolean) { const gl = this.gl; if (boolean) { gl.enable(gl.SCISSOR_TEST); } else { gl.disable(gl.SCISSOR_TEST); } } clear(color2, depth2, stencil, descriptor = null, setFrameBuffer = true) { const { gl } = this; if (descriptor === null) { const clearColor = this.getClearColor(); clearColor.r *= clearColor.a; clearColor.g *= clearColor.a; clearColor.b *= clearColor.a; descriptor = { textures: null, clearColorValue: clearColor }; } let clear = 0; if (color2) clear |= gl.COLOR_BUFFER_BIT; if (depth2) clear |= gl.DEPTH_BUFFER_BIT; if (stencil) clear |= gl.STENCIL_BUFFER_BIT; if (clear !== 0) { let clearColor; if (descriptor.clearColorValue) { clearColor = descriptor.clearColorValue; } else { clearColor = this.getClearColor(); clearColor.r *= clearColor.a; clearColor.g *= clearColor.a; clearColor.b *= clearColor.a; } if (depth2) this.state.setDepthMask(true); if (descriptor.textures === null) { gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); gl.clear(clear); } else { if (setFrameBuffer) this._setFramebuffer(descriptor); if (color2) { for (let i = 0; i < descriptor.textures.length; i++) { gl.clearBufferfv(gl.COLOR, i, [clearColor.r, clearColor.g, clearColor.b, clearColor.a]); } } if (depth2 && stencil) { gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 1, 0); } else if (depth2) { gl.clearBufferfv(gl.DEPTH, 0, [1]); } else if (stencil) { gl.clearBufferiv(gl.STENCIL, 0, [0]); } } } } beginCompute(computeGroup) { const { state, gl } = this; state.bindFramebuffer(gl.FRAMEBUFFER, null); this.initTimestampQuery(computeGroup); } compute(computeGroup, computeNode, bindings, pipeline) { const { state, gl } = this; if (!this.discard) { gl.enable(gl.RASTERIZER_DISCARD); this.discard = true; } const { programGPU, transformBuffers, attributes } = this.get(pipeline); const vaoKey = this._getVaoKey(null, attributes); const vaoGPU = this.vaoCache[vaoKey]; if (vaoGPU === void 0) { this._createVao(null, attributes); } else { gl.bindVertexArray(vaoGPU); } state.useProgram(programGPU); this._bindUniforms(bindings); const transformFeedbackGPU = this._getTransformFeedback(transformBuffers); gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); gl.beginTransformFeedback(gl.POINTS); if (attributes[0].isStorageInstancedBufferAttribute) { gl.drawArraysInstanced(gl.POINTS, 0, 1, computeNode.count); } else { gl.drawArrays(gl.POINTS, 0, computeNode.count); } gl.endTransformFeedback(); gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); for (let i = 0; i < transformBuffers.length; i++) { const dualAttributeData = transformBuffers[i]; if (dualAttributeData.pbo) { this.textureUtils.copyBufferToTexture(dualAttributeData.transformBuffer, dualAttributeData.pbo); } dualAttributeData.switchBuffers(); } } finishCompute(computeGroup) { const gl = this.gl; this.discard = false; gl.disable(gl.RASTERIZER_DISCARD); this.prepareTimestampBuffer(computeGroup); if (this._currentContext) { this._setFramebuffer(this._currentContext); } } draw(renderObject) { const { object, pipeline, material, context: context2 } = renderObject; const { programGPU } = this.get(pipeline); const { gl, state } = this; const contextData = this.get(context2); const drawParams = renderObject.getDrawParameters(); if (drawParams === null) return; this._bindUniforms(renderObject.getBindings()); const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; state.setMaterial(material, frontFaceCW); state.useProgram(programGPU); let vaoGPU = renderObject.staticVao; if (vaoGPU === void 0) { const vaoKey = this._getVaoKey(renderObject.getIndex(), renderObject.getAttributes()); vaoGPU = this.vaoCache[vaoKey]; if (vaoGPU === void 0) { let staticVao; ({ vaoGPU, staticVao } = this._createVao(renderObject.getIndex(), renderObject.getAttributes())); if (staticVao) renderObject.staticVao = vaoGPU; } } gl.bindVertexArray(vaoGPU); const index5 = renderObject.getIndex(); const lastObject = contextData.lastOcclusionObject; if (lastObject !== object && lastObject !== void 0) { if (lastObject !== null && lastObject.occlusionTest === true) { gl.endQuery(gl.ANY_SAMPLES_PASSED); contextData.occlusionQueryIndex++; } if (object.occlusionTest === true) { const query = gl.createQuery(); gl.beginQuery(gl.ANY_SAMPLES_PASSED, query); contextData.occlusionQueries[contextData.occlusionQueryIndex] = query; contextData.occlusionQueryObjects[contextData.occlusionQueryIndex] = object; } contextData.lastOcclusionObject = object; } const renderer3 = this.bufferRenderer; if (object.isPoints) renderer3.mode = gl.POINTS; else if (object.isLineSegments) renderer3.mode = gl.LINES; else if (object.isLine) renderer3.mode = gl.LINE_STRIP; else if (object.isLineLoop) renderer3.mode = gl.LINE_LOOP; else { if (material.wireframe === true) { state.setLineWidth(material.wireframeLinewidth * this.renderer.getPixelRatio()); renderer3.mode = gl.LINES; } else { renderer3.mode = gl.TRIANGLES; } } const { vertexCount, instanceCount } = drawParams; let { firstVertex } = drawParams; renderer3.object = object; if (index5 !== null) { firstVertex *= index5.array.BYTES_PER_ELEMENT; const indexData = this.get(index5); renderer3.index = index5.count; renderer3.type = indexData.type; } else { renderer3.index = 0; } if (object.isBatchedMesh) { if (object._multiDrawInstances !== null) { renderer3.renderMultiDrawInstances(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount, object._multiDrawInstances); } else if (!this.hasFeature("WEBGL_multi_draw")) { warnOnce2("THREE.WebGLRenderer: WEBGL_multi_draw not supported."); } else { renderer3.renderMultiDraw(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount); } } else if (instanceCount > 1) { renderer3.renderInstances(firstVertex, vertexCount, instanceCount); } else { renderer3.render(firstVertex, vertexCount); } gl.bindVertexArray(null); } needsRenderUpdate() { return false; } getRenderCacheKey() { return ""; } // textures createDefaultTexture(texture2) { this.textureUtils.createDefaultTexture(texture2); } createTexture(texture2, options) { this.textureUtils.createTexture(texture2, options); } updateTexture(texture2, options) { this.textureUtils.updateTexture(texture2, options); } generateMipmaps(texture2) { this.textureUtils.generateMipmaps(texture2); } destroyTexture(texture2) { this.textureUtils.destroyTexture(texture2); } copyTextureToBuffer(texture2, x2, y2, width, height, faceIndex) { return this.textureUtils.copyTextureToBuffer(texture2, x2, y2, width, height, faceIndex); } createSampler() { } destroySampler() { } // node builder createNodeBuilder(object, renderer3) { return new GLSLNodeBuilder(object, renderer3); } // program createProgram(program) { const gl = this.gl; const { stage, code } = program; const shader = stage === "fragment" ? gl.createShader(gl.FRAGMENT_SHADER) : gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(shader, code); gl.compileShader(shader); this.set(program, { shaderGPU: shader }); } destroyProgram() { console.warn("Abstract class."); } createRenderPipeline(renderObject, promises) { const gl = this.gl; const pipeline = renderObject.pipeline; const { fragmentProgram, vertexProgram } = pipeline; const programGPU = gl.createProgram(); const fragmentShader = this.get(fragmentProgram).shaderGPU; const vertexShader = this.get(vertexProgram).shaderGPU; gl.attachShader(programGPU, fragmentShader); gl.attachShader(programGPU, vertexShader); gl.linkProgram(programGPU); this.set(pipeline, { programGPU, fragmentShader, vertexShader }); if (promises !== null && this.parallel) { const p = new Promise((resolve) => { const parallel = this.parallel; const checkStatus = () => { if (gl.getProgramParameter(programGPU, parallel.COMPLETION_STATUS_KHR)) { this._completeCompile(renderObject, pipeline); resolve(); } else { requestAnimationFrame(checkStatus); } }; checkStatus(); }); promises.push(p); return; } this._completeCompile(renderObject, pipeline); } _handleSource(string, errorLine) { const lines = string.split("\n"); const lines2 = []; const from = Math.max(errorLine - 6, 0); const to = Math.min(errorLine + 6, lines.length); for (let i = from; i < to; i++) { const line = i + 1; lines2.push(`${line === errorLine ? ">" : " "} ${line}: ${lines[i]}`); } return lines2.join("\n"); } _getShaderErrors(gl, shader, type) { const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); const errors = gl.getShaderInfoLog(shader).trim(); if (status && errors === "") return ""; const errorMatches = /ERROR: 0:(\d+)/.exec(errors); if (errorMatches) { const errorLine = parseInt(errorMatches[1]); return type.toUpperCase() + "\n\n" + errors + "\n\n" + this._handleSource(gl.getShaderSource(shader), errorLine); } else { return errors; } } _logProgramError(programGPU, glFragmentShader, glVertexShader) { if (this.renderer.debug.checkShaderErrors) { const gl = this.gl; const programLog = gl.getProgramInfoLog(programGPU).trim(); if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { if (typeof this.renderer.debug.onShaderError === "function") { this.renderer.debug.onShaderError(gl, programGPU, glVertexShader, glFragmentShader); } else { const vertexErrors = this._getShaderErrors(gl, glVertexShader, "vertex"); const fragmentErrors = this._getShaderErrors(gl, glFragmentShader, "fragment"); console.error( "THREE.WebGLProgram: Shader Error " + gl.getError() + " - VALIDATE_STATUS " + gl.getProgramParameter(programGPU, gl.VALIDATE_STATUS) + "\n\nProgram Info Log: " + programLog + "\n" + vertexErrors + "\n" + fragmentErrors ); } } else if (programLog !== "") { console.warn("THREE.WebGLProgram: Program Info Log:", programLog); } } } _completeCompile(renderObject, pipeline) { const { state, gl } = this; const pipelineData = this.get(pipeline); const { programGPU, fragmentShader, vertexShader } = pipelineData; if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { this._logProgramError(programGPU, fragmentShader, vertexShader); } state.useProgram(programGPU); const bindings = renderObject.getBindings(); this._setupBindings(bindings, programGPU); this.set(pipeline, { programGPU }); } createComputePipeline(computePipeline, bindings) { const { state, gl } = this; const fragmentProgram = { stage: "fragment", code: "#version 300 es\nprecision highp float;\nvoid main() {}" }; this.createProgram(fragmentProgram); const { computeProgram } = computePipeline; const programGPU = gl.createProgram(); const fragmentShader = this.get(fragmentProgram).shaderGPU; const vertexShader = this.get(computeProgram).shaderGPU; const transforms = computeProgram.transforms; const transformVaryingNames = []; const transformAttributeNodes = []; for (let i = 0; i < transforms.length; i++) { const transform = transforms[i]; transformVaryingNames.push(transform.varyingName); transformAttributeNodes.push(transform.attributeNode); } gl.attachShader(programGPU, fragmentShader); gl.attachShader(programGPU, vertexShader); gl.transformFeedbackVaryings( programGPU, transformVaryingNames, gl.SEPARATE_ATTRIBS ); gl.linkProgram(programGPU); if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { this._logProgramError(programGPU, fragmentShader, vertexShader); } state.useProgram(programGPU); this._setupBindings(bindings, programGPU); const attributeNodes = computeProgram.attributes; const attributes = []; const transformBuffers = []; for (let i = 0; i < attributeNodes.length; i++) { const attribute2 = attributeNodes[i].node.attribute; attributes.push(attribute2); if (!this.has(attribute2)) this.attributeUtils.createAttribute(attribute2, gl.ARRAY_BUFFER); } for (let i = 0; i < transformAttributeNodes.length; i++) { const attribute2 = transformAttributeNodes[i].attribute; if (!this.has(attribute2)) this.attributeUtils.createAttribute(attribute2, gl.ARRAY_BUFFER); const attributeData = this.get(attribute2); transformBuffers.push(attributeData); } this.set(computePipeline, { programGPU, transformBuffers, attributes }); } createBindings(bindGroup, bindings) { if (this._knownBindings.has(bindings) === false) { this._knownBindings.add(bindings); let uniformBuffers = 0; let textures = 0; for (const bindGroup2 of bindings) { this.set(bindGroup2, { textures, uniformBuffers }); for (const binding of bindGroup2.bindings) { if (binding.isUniformBuffer) uniformBuffers++; if (binding.isSampledTexture) textures++; } } } this.updateBindings(bindGroup, bindings); } updateBindings(bindGroup) { const { gl } = this; const bindGroupData = this.get(bindGroup); let i = bindGroupData.uniformBuffers; let t = bindGroupData.textures; for (const binding of bindGroup.bindings) { if (binding.isUniformsGroup || binding.isUniformBuffer) { const data = binding.buffer; const bufferGPU = gl.createBuffer(); gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); this.set(binding, { index: i++, bufferGPU }); } else if (binding.isSampledTexture) { const { textureGPU, glTextureType } = this.get(binding.texture); this.set(binding, { index: t++, textureGPU, glTextureType }); } } } updateBinding(binding) { const gl = this.gl; if (binding.isUniformsGroup || binding.isUniformBuffer) { const bindingData = this.get(binding); const bufferGPU = bindingData.bufferGPU; const data = binding.buffer; gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); } } // attributes createIndexAttribute(attribute2) { const gl = this.gl; this.attributeUtils.createAttribute(attribute2, gl.ELEMENT_ARRAY_BUFFER); } createAttribute(attribute2) { if (this.has(attribute2)) return; const gl = this.gl; this.attributeUtils.createAttribute(attribute2, gl.ARRAY_BUFFER); } createStorageAttribute(attribute2) { if (this.has(attribute2)) return; const gl = this.gl; this.attributeUtils.createAttribute(attribute2, gl.ARRAY_BUFFER); } updateAttribute(attribute2) { this.attributeUtils.updateAttribute(attribute2); } destroyAttribute(attribute2) { this.attributeUtils.destroyAttribute(attribute2); } updateSize() { } hasFeature(name) { const keysMatching = Object.keys(GLFeatureName).filter((key) => GLFeatureName[key] === name); const extensions = this.extensions; for (let i = 0; i < keysMatching.length; i++) { if (extensions.has(keysMatching[i])) return true; } return false; } getMaxAnisotropy() { return this.capabilities.getMaxAnisotropy(); } copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level) { this.textureUtils.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); } copyFramebufferToTexture(texture2, renderContext, rectangle) { this.textureUtils.copyFramebufferToTexture(texture2, renderContext, rectangle); } _setFramebuffer(descriptor) { const { gl, state } = this; let currentFrameBuffer = null; if (descriptor.textures !== null) { const renderTarget = descriptor.renderTarget; const renderTargetContextData = this.get(renderTarget); const { samples, depthBuffer, stencilBuffer } = renderTarget; const isCube = renderTarget.isWebGLCubeRenderTarget === true; let msaaFb = renderTargetContextData.msaaFrameBuffer; let depthRenderbuffer = renderTargetContextData.depthRenderbuffer; const cacheKey = getCacheKey(descriptor); let fb; if (isCube) { renderTargetContextData.cubeFramebuffers || (renderTargetContextData.cubeFramebuffers = {}); fb = renderTargetContextData.cubeFramebuffers[cacheKey]; } else { renderTargetContextData.framebuffers || (renderTargetContextData.framebuffers = {}); fb = renderTargetContextData.framebuffers[cacheKey]; } if (fb === void 0) { fb = gl.createFramebuffer(); state.bindFramebuffer(gl.FRAMEBUFFER, fb); const textures = descriptor.textures; if (isCube) { renderTargetContextData.cubeFramebuffers[cacheKey] = fb; const { textureGPU } = this.get(textures[0]); const cubeFace = this.renderer._activeCubeFace; gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, textureGPU, 0); } else { renderTargetContextData.framebuffers[cacheKey] = fb; for (let i = 0; i < textures.length; i++) { const texture2 = textures[i]; const textureData = this.get(texture2); textureData.renderTarget = descriptor.renderTarget; textureData.cacheKey = cacheKey; const attachment = gl.COLOR_ATTACHMENT0 + i; gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0); } state.drawBuffers(descriptor, fb); } if (descriptor.depthTexture !== null) { const textureData = this.get(descriptor.depthTexture); const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; textureData.renderTarget = descriptor.renderTarget; textureData.cacheKey = cacheKey; gl.framebufferTexture2D(gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0); } } if (samples > 0) { if (msaaFb === void 0) { const invalidationArray = []; msaaFb = gl.createFramebuffer(); state.bindFramebuffer(gl.FRAMEBUFFER, msaaFb); const msaaRenderbuffers = []; const textures = descriptor.textures; for (let i = 0; i < textures.length; i++) { msaaRenderbuffers[i] = gl.createRenderbuffer(); gl.bindRenderbuffer(gl.RENDERBUFFER, msaaRenderbuffers[i]); invalidationArray.push(gl.COLOR_ATTACHMENT0 + i); if (depthBuffer) { const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; invalidationArray.push(depthStyle); } const texture2 = descriptor.textures[i]; const textureData = this.get(texture2); gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, textureData.glInternalFormat, descriptor.width, descriptor.height); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.RENDERBUFFER, msaaRenderbuffers[i]); } renderTargetContextData.msaaFrameBuffer = msaaFb; renderTargetContextData.msaaRenderbuffers = msaaRenderbuffers; if (depthRenderbuffer === void 0) { depthRenderbuffer = gl.createRenderbuffer(); this.textureUtils.setupRenderBufferStorage(depthRenderbuffer, descriptor); renderTargetContextData.depthRenderbuffer = depthRenderbuffer; const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; invalidationArray.push(depthStyle); } renderTargetContextData.invalidationArray = invalidationArray; } currentFrameBuffer = renderTargetContextData.msaaFrameBuffer; } else { currentFrameBuffer = fb; } } state.bindFramebuffer(gl.FRAMEBUFFER, currentFrameBuffer); } _getVaoKey(index5, attributes) { let key = []; if (index5 !== null) { const indexData = this.get(index5); key += ":" + indexData.id; } for (let i = 0; i < attributes.length; i++) { const attributeData = this.get(attributes[i]); key += ":" + attributeData.id; } return key; } _createVao(index5, attributes) { const { gl } = this; const vaoGPU = gl.createVertexArray(); let key = ""; let staticVao = true; gl.bindVertexArray(vaoGPU); if (index5 !== null) { const indexData = this.get(index5); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexData.bufferGPU); key += ":" + indexData.id; } for (let i = 0; i < attributes.length; i++) { const attribute2 = attributes[i]; const attributeData = this.get(attribute2); key += ":" + attributeData.id; gl.bindBuffer(gl.ARRAY_BUFFER, attributeData.bufferGPU); gl.enableVertexAttribArray(i); if (attribute2.isStorageBufferAttribute || attribute2.isStorageInstancedBufferAttribute) staticVao = false; let stride, offset; if (attribute2.isInterleavedBufferAttribute === true) { stride = attribute2.data.stride * attributeData.bytesPerElement; offset = attribute2.offset * attributeData.bytesPerElement; } else { stride = 0; offset = 0; } if (attributeData.isInteger) { gl.vertexAttribIPointer(i, attribute2.itemSize, attributeData.type, stride, offset); } else { gl.vertexAttribPointer(i, attribute2.itemSize, attributeData.type, attribute2.normalized, stride, offset); } if (attribute2.isInstancedBufferAttribute && !attribute2.isInterleavedBufferAttribute) { gl.vertexAttribDivisor(i, attribute2.meshPerAttribute); } else if (attribute2.isInterleavedBufferAttribute && attribute2.data.isInstancedInterleavedBuffer) { gl.vertexAttribDivisor(i, attribute2.data.meshPerAttribute); } } gl.bindBuffer(gl.ARRAY_BUFFER, null); this.vaoCache[key] = vaoGPU; return { vaoGPU, staticVao }; } _getTransformFeedback(transformBuffers) { let key = ""; for (let i = 0; i < transformBuffers.length; i++) { key += ":" + transformBuffers[i].id; } let transformFeedbackGPU = this.transformFeedbackCache[key]; if (transformFeedbackGPU !== void 0) { return transformFeedbackGPU; } const { gl } = this; transformFeedbackGPU = gl.createTransformFeedback(); gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); for (let i = 0; i < transformBuffers.length; i++) { const attributeData = transformBuffers[i]; gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, i, attributeData.transformBuffer); } gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); this.transformFeedbackCache[key] = transformFeedbackGPU; return transformFeedbackGPU; } _setupBindings(bindings, programGPU) { const gl = this.gl; for (const bindGroup of bindings) { for (const binding of bindGroup.bindings) { const bindingData = this.get(binding); const index5 = bindingData.index; if (binding.isUniformsGroup || binding.isUniformBuffer) { const location = gl.getUniformBlockIndex(programGPU, binding.name); gl.uniformBlockBinding(programGPU, location, index5); } else if (binding.isSampledTexture) { const location = gl.getUniformLocation(programGPU, binding.name); gl.uniform1i(location, index5); } } } } _bindUniforms(bindings) { const { gl, state } = this; for (const bindGroup of bindings) { for (const binding of bindGroup.bindings) { const bindingData = this.get(binding); const index5 = bindingData.index; if (binding.isUniformsGroup || binding.isUniformBuffer) { state.bindBufferBase(gl.UNIFORM_BUFFER, index5, bindingData.bufferGPU); } else if (binding.isSampledTexture) { state.bindTexture(bindingData.glTextureType, bindingData.textureGPU, gl.TEXTURE0 + index5); } } } } dispose() { this.renderer.domElement.removeEventListener("webglcontextlost", this._onContextLost); } }; var Sampler = class extends Binding { constructor(name, texture2) { super(name); this.texture = texture2; this.version = texture2 ? texture2.version : 0; this.isSampler = true; } }; var NodeSampler = class extends Sampler { constructor(name, textureNode, groupNode) { super(name, textureNode ? textureNode.value : null); this.textureNode = textureNode; this.groupNode = groupNode; } update() { this.texture = this.textureNode.value; } }; var StorageBuffer = class extends Buffer2 { constructor(name, attribute2) { super(name, attribute2 ? attribute2.array : null); this.attribute = attribute2; this.isStorageBuffer = true; } }; var _id = 0; var NodeStorageBuffer = class extends StorageBuffer { constructor(nodeUniform, groupNode) { super("StorageBuffer_" + _id++, nodeUniform ? nodeUniform.value : null); this.nodeUniform = nodeUniform; this.access = nodeUniform ? nodeUniform.access : GPUBufferBindingType.Storage; this.groupNode = groupNode; } get buffer() { return this.nodeUniform.value; } }; var WebGPUTexturePassUtils = class extends DataMap { constructor(device) { super(); this.device = device; const mipmapVertexSource = ` struct VarysStruct { @builtin( position ) Position: vec4<f32>, @location( 0 ) vTex : vec2<f32> }; @vertex fn main( @builtin( vertex_index ) vertexIndex : u32 ) -> VarysStruct { var Varys : VarysStruct; var pos = array< vec2<f32>, 4 >( vec2<f32>( -1.0, 1.0 ), vec2<f32>( 1.0, 1.0 ), vec2<f32>( -1.0, -1.0 ), vec2<f32>( 1.0, -1.0 ) ); var tex = array< vec2<f32>, 4 >( vec2<f32>( 0.0, 0.0 ), vec2<f32>( 1.0, 0.0 ), vec2<f32>( 0.0, 1.0 ), vec2<f32>( 1.0, 1.0 ) ); Varys.vTex = tex[ vertexIndex ]; Varys.Position = vec4<f32>( pos[ vertexIndex ], 0.0, 1.0 ); return Varys; } `; const mipmapFragmentSource = ` @group( 0 ) @binding( 0 ) var imgSampler : sampler; @group( 0 ) @binding( 1 ) var img : texture_2d<f32>; @fragment fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> { return textureSample( img, imgSampler, vTex ); } `; const flipYFragmentSource = ` @group( 0 ) @binding( 0 ) var imgSampler : sampler; @group( 0 ) @binding( 1 ) var img : texture_2d<f32>; @fragment fn main( @location( 0 ) vTex : vec2<f32> ) -> @location( 0 ) vec4<f32> { return textureSample( img, imgSampler, vec2( vTex.x, 1.0 - vTex.y ) ); } `; this.mipmapSampler = device.createSampler({ minFilter: GPUFilterMode.Linear }); this.flipYSampler = device.createSampler({ minFilter: GPUFilterMode.Nearest }); this.transferPipelines = {}; this.flipYPipelines = {}; this.mipmapVertexShaderModule = device.createShaderModule({ label: "mipmapVertex", code: mipmapVertexSource }); this.mipmapFragmentShaderModule = device.createShaderModule({ label: "mipmapFragment", code: mipmapFragmentSource }); this.flipYFragmentShaderModule = device.createShaderModule({ label: "flipYFragment", code: flipYFragmentSource }); } getTransferPipeline(format2) { let pipeline = this.transferPipelines[format2]; if (pipeline === void 0) { pipeline = this.device.createRenderPipeline({ label: `mipmap-${format2}`, vertex: { module: this.mipmapVertexShaderModule, entryPoint: "main" }, fragment: { module: this.mipmapFragmentShaderModule, entryPoint: "main", targets: [{ format: format2 }] }, primitive: { topology: GPUPrimitiveTopology.TriangleStrip, stripIndexFormat: GPUIndexFormat.Uint32 }, layout: "auto" }); this.transferPipelines[format2] = pipeline; } return pipeline; } getFlipYPipeline(format2) { let pipeline = this.flipYPipelines[format2]; if (pipeline === void 0) { pipeline = this.device.createRenderPipeline({ label: `flipY-${format2}`, vertex: { module: this.mipmapVertexShaderModule, entryPoint: "main" }, fragment: { module: this.flipYFragmentShaderModule, entryPoint: "main", targets: [{ format: format2 }] }, primitive: { topology: GPUPrimitiveTopology.TriangleStrip, stripIndexFormat: GPUIndexFormat.Uint32 }, layout: "auto" }); this.flipYPipelines[format2] = pipeline; } return pipeline; } flipY(textureGPU, textureGPUDescriptor, baseArrayLayer = 0) { const format2 = textureGPUDescriptor.format; const { width, height } = textureGPUDescriptor.size; const transferPipeline = this.getTransferPipeline(format2); const flipYPipeline = this.getFlipYPipeline(format2); const tempTexture = this.device.createTexture({ size: { width, height, depthOrArrayLayers: 1 }, format: format2, usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING }); const srcView = textureGPU.createView({ baseMipLevel: 0, mipLevelCount: 1, dimension: GPUTextureViewDimension.TwoD, baseArrayLayer }); const dstView = tempTexture.createView({ baseMipLevel: 0, mipLevelCount: 1, dimension: GPUTextureViewDimension.TwoD, baseArrayLayer: 0 }); const commandEncoder = this.device.createCommandEncoder({}); const pass = (pipeline, sourceView, destinationView) => { const bindGroupLayout = pipeline.getBindGroupLayout(0); const bindGroup = this.device.createBindGroup({ layout: bindGroupLayout, entries: [{ binding: 0, resource: this.flipYSampler }, { binding: 1, resource: sourceView }] }); const passEncoder = commandEncoder.beginRenderPass({ colorAttachments: [{ view: destinationView, loadOp: GPULoadOp.Clear, storeOp: GPUStoreOp.Store, clearValue: [0, 0, 0, 0] }] }); passEncoder.setPipeline(pipeline); passEncoder.setBindGroup(0, bindGroup); passEncoder.draw(4, 1, 0, 0); passEncoder.end(); }; pass(transferPipeline, srcView, dstView); pass(flipYPipeline, dstView, srcView); this.device.queue.submit([commandEncoder.finish()]); tempTexture.destroy(); } generateMipmaps(textureGPU, textureGPUDescriptor, baseArrayLayer = 0) { const textureData = this.get(textureGPU); if (textureData.useCount === void 0) { textureData.useCount = 0; textureData.layers = []; } const passes = textureData.layers[baseArrayLayer] || this._mipmapCreateBundles(textureGPU, textureGPUDescriptor, baseArrayLayer); const commandEncoder = this.device.createCommandEncoder({}); this._mipmapRunBundles(commandEncoder, passes); this.device.queue.submit([commandEncoder.finish()]); if (textureData.useCount !== 0) textureData.layers[baseArrayLayer] = passes; textureData.useCount++; } _mipmapCreateBundles(textureGPU, textureGPUDescriptor, baseArrayLayer) { const pipeline = this.getTransferPipeline(textureGPUDescriptor.format); const bindGroupLayout = pipeline.getBindGroupLayout(0); let srcView = textureGPU.createView({ baseMipLevel: 0, mipLevelCount: 1, dimension: GPUTextureViewDimension.TwoD, baseArrayLayer }); const passes = []; for (let i = 1; i < textureGPUDescriptor.mipLevelCount; i++) { const bindGroup = this.device.createBindGroup({ layout: bindGroupLayout, entries: [{ binding: 0, resource: this.mipmapSampler }, { binding: 1, resource: srcView }] }); const dstView = textureGPU.createView({ baseMipLevel: i, mipLevelCount: 1, dimension: GPUTextureViewDimension.TwoD, baseArrayLayer }); const passDescriptor = { colorAttachments: [{ view: dstView, loadOp: GPULoadOp.Clear, storeOp: GPUStoreOp.Store, clearValue: [0, 0, 0, 0] }] }; const passEncoder = this.device.createRenderBundleEncoder({ colorFormats: [textureGPUDescriptor.format] }); passEncoder.setPipeline(pipeline); passEncoder.setBindGroup(0, bindGroup); passEncoder.draw(4, 1, 0, 0); passes.push({ renderBundles: [passEncoder.finish()], passDescriptor }); srcView = dstView; } return passes; } _mipmapRunBundles(commandEncoder, passes) { const levels = passes.length; for (let i = 0; i < levels; i++) { const pass = passes[i]; const passEncoder = commandEncoder.beginRenderPass(pass.passDescriptor); passEncoder.executeBundles(pass.renderBundles); passEncoder.end(); } } }; var _compareToWebGPU = { [NeverCompare2]: "never", [LessCompare2]: "less", [EqualCompare2]: "equal", [LessEqualCompare2]: "less-equal", [GreaterCompare2]: "greater", [GreaterEqualCompare2]: "greater-equal", [AlwaysCompare2]: "always", [NotEqualCompare2]: "not-equal" }; var _flipMap = [0, 1, 3, 2, 4, 5]; var WebGPUTextureUtils = class { constructor(backend) { this.backend = backend; this._passUtils = null; this.defaultTexture = {}; this.defaultCubeTexture = {}; this.defaultVideoFrame = null; this.colorBuffer = null; this.depthTexture = new DepthTexture2(); this.depthTexture.name = "depthBuffer"; } createSampler(texture2) { const backend = this.backend; const device = backend.device; const textureGPU = backend.get(texture2); const samplerDescriptorGPU = { addressModeU: this._convertAddressMode(texture2.wrapS), addressModeV: this._convertAddressMode(texture2.wrapT), addressModeW: this._convertAddressMode(texture2.wrapR), magFilter: this._convertFilterMode(texture2.magFilter), minFilter: this._convertFilterMode(texture2.minFilter), mipmapFilter: this._convertFilterMode(texture2.minFilter), maxAnisotropy: 1 }; if (samplerDescriptorGPU.magFilter === GPUFilterMode.Linear && samplerDescriptorGPU.minFilter === GPUFilterMode.Linear && samplerDescriptorGPU.mipmapFilter === GPUFilterMode.Linear) { samplerDescriptorGPU.maxAnisotropy = texture2.anisotropy; } if (texture2.isDepthTexture && texture2.compareFunction !== null) { samplerDescriptorGPU.compare = _compareToWebGPU[texture2.compareFunction]; } textureGPU.sampler = device.createSampler(samplerDescriptorGPU); } createDefaultTexture(texture2) { let textureGPU; const format2 = getFormat2(texture2); if (texture2.isCubeTexture) { textureGPU = this._getDefaultCubeTextureGPU(format2); } else if (texture2.isVideoTexture) { this.backend.get(texture2).externalTexture = this._getDefaultVideoFrame(); } else { textureGPU = this._getDefaultTextureGPU(format2); } this.backend.get(texture2).texture = textureGPU; } createTexture(texture2, options = {}) { const backend = this.backend; const textureData = backend.get(texture2); if (textureData.initialized) { throw new Error("WebGPUTextureUtils: Texture already initialized."); } if (options.needsMipmaps === void 0) options.needsMipmaps = false; if (options.levels === void 0) options.levels = 1; if (options.depth === void 0) options.depth = 1; const { width, height, depth: depth2, levels } = options; if (texture2.isFramebufferTexture) { if (options.renderTarget) { options.format = this.backend.utils.getCurrentColorFormat(options.renderTarget); } else { options.format = this.backend.utils.getPreferredCanvasFormat(); } } const dimension = this._getDimension(texture2); const format2 = texture2.internalFormat || options.format || getFormat2(texture2, backend.device); textureData.format = format2; let sampleCount = options.sampleCount !== void 0 ? options.sampleCount : 1; sampleCount = backend.utils.getSampleCount(sampleCount); const primarySampleCount = texture2.isRenderTargetTexture && !texture2.isMultisampleRenderTargetTexture ? 1 : sampleCount; let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC; if (texture2.isStorageTexture === true) { usage |= GPUTextureUsage.STORAGE_BINDING; } if (texture2.isCompressedTexture !== true && texture2.isCompressedArrayTexture !== true) { usage |= GPUTextureUsage.RENDER_ATTACHMENT; } const textureDescriptorGPU = { label: texture2.name, size: { width, height, depthOrArrayLayers: depth2 }, mipLevelCount: levels, sampleCount: primarySampleCount, dimension, format: format2, usage }; if (texture2.isVideoTexture) { const video = texture2.source.data; const videoFrame = new VideoFrame(video); textureDescriptorGPU.size.width = videoFrame.displayWidth; textureDescriptorGPU.size.height = videoFrame.displayHeight; videoFrame.close(); textureData.externalTexture = video; } else { if (format2 === void 0) { console.warn("WebGPURenderer: Texture format not supported."); return this.createDefaultTexture(texture2); } textureData.texture = backend.device.createTexture(textureDescriptorGPU); } if (texture2.isRenderTargetTexture && sampleCount > 1 && !texture2.isMultisampleRenderTargetTexture) { const msaaTextureDescriptorGPU = Object.assign({}, textureDescriptorGPU); msaaTextureDescriptorGPU.label = msaaTextureDescriptorGPU.label + "-msaa"; msaaTextureDescriptorGPU.sampleCount = sampleCount; textureData.msaaTexture = backend.device.createTexture(msaaTextureDescriptorGPU); } textureData.initialized = true; textureData.textureDescriptorGPU = textureDescriptorGPU; } destroyTexture(texture2) { const backend = this.backend; const textureData = backend.get(texture2); textureData.texture.destroy(); if (textureData.msaaTexture !== void 0) textureData.msaaTexture.destroy(); backend.delete(texture2); } destroySampler(texture2) { const backend = this.backend; const textureData = backend.get(texture2); delete textureData.sampler; } generateMipmaps(texture2) { const textureData = this.backend.get(texture2); if (texture2.isCubeTexture) { for (let i = 0; i < 6; i++) { this._generateMipmaps(textureData.texture, textureData.textureDescriptorGPU, i); } } else { const depth2 = texture2.image.depth || 1; for (let i = 0; i < depth2; i++) { this._generateMipmaps(textureData.texture, textureData.textureDescriptorGPU, i); } } } getColorBuffer() { if (this.colorBuffer) this.colorBuffer.destroy(); const backend = this.backend; const { width, height } = backend.getDrawingBufferSize(); this.colorBuffer = backend.device.createTexture({ label: "colorBuffer", size: { width, height, depthOrArrayLayers: 1 }, sampleCount: backend.utils.getSampleCount(backend.renderer.samples), format: backend.utils.getPreferredCanvasFormat(), usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC }); return this.colorBuffer; } getDepthBuffer(depth2 = true, stencil = false) { const backend = this.backend; const { width, height } = backend.getDrawingBufferSize(); const depthTexture = this.depthTexture; const depthTextureGPU = backend.get(depthTexture).texture; let format2, type; if (stencil) { format2 = DepthStencilFormat2; type = UnsignedInt248Type2; } else if (depth2) { format2 = DepthFormat2; type = UnsignedIntType2; } if (depthTextureGPU !== void 0) { if (depthTexture.image.width === width && depthTexture.image.height === height && depthTexture.format === format2 && depthTexture.type === type) { return depthTextureGPU; } this.destroyTexture(depthTexture); } depthTexture.name = "depthBuffer"; depthTexture.format = format2; depthTexture.type = type; depthTexture.image.width = width; depthTexture.image.height = height; this.createTexture(depthTexture, { sampleCount: backend.utils.getSampleCount(backend.renderer.samples), width, height }); return backend.get(depthTexture).texture; } updateTexture(texture2, options) { const textureData = this.backend.get(texture2); const { textureDescriptorGPU } = textureData; if (texture2.isRenderTargetTexture || textureDescriptorGPU === void 0) return; if (texture2.isDataTexture) { this._copyBufferToTexture(options.image, textureData.texture, textureDescriptorGPU, 0, texture2.flipY); } else if (texture2.isDataArrayTexture || texture2.isData3DTexture) { for (let i = 0; i < options.image.depth; i++) { this._copyBufferToTexture(options.image, textureData.texture, textureDescriptorGPU, i, texture2.flipY, i); } } else if (texture2.isCompressedTexture || texture2.isCompressedArrayTexture) { this._copyCompressedBufferToTexture(texture2.mipmaps, textureData.texture, textureDescriptorGPU); } else if (texture2.isCubeTexture) { this._copyCubeMapToTexture(options.images, textureData.texture, textureDescriptorGPU, texture2.flipY); } else if (texture2.isVideoTexture) { const video = texture2.source.data; textureData.externalTexture = video; } else { this._copyImageToTexture(options.image, textureData.texture, textureDescriptorGPU, 0, texture2.flipY); } textureData.version = texture2.version; if (texture2.onUpdate) texture2.onUpdate(texture2); } async copyTextureToBuffer(texture2, x2, y2, width, height, faceIndex) { const device = this.backend.device; const textureData = this.backend.get(texture2); const textureGPU = textureData.texture; const format2 = textureData.textureDescriptorGPU.format; const bytesPerTexel = this._getBytesPerTexel(format2); let bytesPerRow = width * bytesPerTexel; bytesPerRow = Math.ceil(bytesPerRow / 256) * 256; const readBuffer = device.createBuffer( { size: width * height * bytesPerTexel, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ } ); const encoder = device.createCommandEncoder(); encoder.copyTextureToBuffer( { texture: textureGPU, origin: { x: x2, y: y2, z: faceIndex } }, { buffer: readBuffer, bytesPerRow }, { width, height } ); const typedArrayType = this._getTypedArrayType(format2); device.queue.submit([encoder.finish()]); await readBuffer.mapAsync(GPUMapMode.READ); const buffer2 = readBuffer.getMappedRange(); return new typedArrayType(buffer2); } _isEnvironmentTexture(texture2) { const mapping = texture2.mapping; return mapping === EquirectangularReflectionMapping2 || mapping === EquirectangularRefractionMapping2 || (mapping === CubeReflectionMapping2 || mapping === CubeRefractionMapping2); } _getDefaultTextureGPU(format2) { let defaultTexture = this.defaultTexture[format2]; if (defaultTexture === void 0) { const texture2 = new Texture2(); texture2.minFilter = NearestFilter2; texture2.magFilter = NearestFilter2; this.createTexture(texture2, { width: 1, height: 1, format: format2 }); this.defaultTexture[format2] = defaultTexture = texture2; } return this.backend.get(defaultTexture).texture; } _getDefaultCubeTextureGPU(format2) { let defaultCubeTexture = this.defaultTexture[format2]; if (defaultCubeTexture === void 0) { const texture2 = new CubeTexture2(); texture2.minFilter = NearestFilter2; texture2.magFilter = NearestFilter2; this.createTexture(texture2, { width: 1, height: 1, depth: 6 }); this.defaultCubeTexture[format2] = defaultCubeTexture = texture2; } return this.backend.get(defaultCubeTexture).texture; } _getDefaultVideoFrame() { let defaultVideoFrame = this.defaultVideoFrame; if (defaultVideoFrame === null) { const init4 = { timestamp: 0, codedWidth: 1, codedHeight: 1, format: "RGBA" }; this.defaultVideoFrame = defaultVideoFrame = new VideoFrame(new Uint8Array([0, 0, 0, 255]), init4); } return defaultVideoFrame; } _copyCubeMapToTexture(images, textureGPU, textureDescriptorGPU, flipY) { for (let i = 0; i < 6; i++) { const image = images[i]; const flipIndex = flipY === true ? _flipMap[i] : i; if (image.isDataTexture) { this._copyBufferToTexture(image.image, textureGPU, textureDescriptorGPU, flipIndex, flipY); } else { this._copyImageToTexture(image, textureGPU, textureDescriptorGPU, flipIndex, flipY); } } } _copyImageToTexture(image, textureGPU, textureDescriptorGPU, originDepth, flipY) { const device = this.backend.device; device.queue.copyExternalImageToTexture( { source: image }, { texture: textureGPU, mipLevel: 0, origin: { x: 0, y: 0, z: originDepth } }, { width: image.width, height: image.height, depthOrArrayLayers: 1 } ); if (flipY === true) { this._flipY(textureGPU, textureDescriptorGPU, originDepth); } } _getPassUtils() { let passUtils = this._passUtils; if (passUtils === null) { this._passUtils = passUtils = new WebGPUTexturePassUtils(this.backend.device); } return passUtils; } _generateMipmaps(textureGPU, textureDescriptorGPU, baseArrayLayer = 0) { this._getPassUtils().generateMipmaps(textureGPU, textureDescriptorGPU, baseArrayLayer); } _flipY(textureGPU, textureDescriptorGPU, originDepth = 0) { this._getPassUtils().flipY(textureGPU, textureDescriptorGPU, originDepth); } _copyBufferToTexture(image, textureGPU, textureDescriptorGPU, originDepth, flipY, depth2 = 0) { const device = this.backend.device; const data = image.data; const bytesPerTexel = this._getBytesPerTexel(textureDescriptorGPU.format); const bytesPerRow = image.width * bytesPerTexel; device.queue.writeTexture( { texture: textureGPU, mipLevel: 0, origin: { x: 0, y: 0, z: originDepth } }, data, { offset: image.width * image.height * bytesPerTexel * depth2, bytesPerRow }, { width: image.width, height: image.height, depthOrArrayLayers: 1 } ); if (flipY === true) { this._flipY(textureGPU, textureDescriptorGPU, originDepth); } } _copyCompressedBufferToTexture(mipmaps, textureGPU, textureDescriptorGPU) { const device = this.backend.device; const blockData = this._getBlockData(textureDescriptorGPU.format); const isTextureArray = textureDescriptorGPU.size.depthOrArrayLayers > 1; for (let i = 0; i < mipmaps.length; i++) { const mipmap = mipmaps[i]; const width = mipmap.width; const height = mipmap.height; const depth2 = isTextureArray ? textureDescriptorGPU.size.depthOrArrayLayers : 1; const bytesPerRow = Math.ceil(width / blockData.width) * blockData.byteLength; const bytesPerImage = bytesPerRow * Math.ceil(height / blockData.height); for (let j = 0; j < depth2; j++) { device.queue.writeTexture( { texture: textureGPU, mipLevel: i, origin: { x: 0, y: 0, z: j } }, mipmap.data, { offset: j * bytesPerImage, bytesPerRow, rowsPerImage: Math.ceil(height / blockData.height) }, { width: Math.ceil(width / blockData.width) * blockData.width, height: Math.ceil(height / blockData.height) * blockData.height, depthOrArrayLayers: 1 } ); } } } _getBlockData(format2) { if (format2 === GPUTextureFormat.BC1RGBAUnorm || format2 === GPUTextureFormat.BC1RGBAUnormSRGB) return { byteLength: 8, width: 4, height: 4 }; if (format2 === GPUTextureFormat.BC2RGBAUnorm || format2 === GPUTextureFormat.BC2RGBAUnormSRGB) return { byteLength: 16, width: 4, height: 4 }; if (format2 === GPUTextureFormat.BC3RGBAUnorm || format2 === GPUTextureFormat.BC3RGBAUnormSRGB) return { byteLength: 16, width: 4, height: 4 }; if (format2 === GPUTextureFormat.BC4RUnorm || format2 === GPUTextureFormat.BC4RSNorm) return { byteLength: 8, width: 4, height: 4 }; if (format2 === GPUTextureFormat.BC5RGUnorm || format2 === GPUTextureFormat.BC5RGSnorm) return { byteLength: 16, width: 4, height: 4 }; if (format2 === GPUTextureFormat.BC6HRGBUFloat || format2 === GPUTextureFormat.BC6HRGBFloat) return { byteLength: 16, width: 4, height: 4 }; if (format2 === GPUTextureFormat.BC7RGBAUnorm || format2 === GPUTextureFormat.BC7RGBAUnormSRGB) return { byteLength: 16, width: 4, height: 4 }; if (format2 === GPUTextureFormat.ETC2RGB8Unorm || format2 === GPUTextureFormat.ETC2RGB8UnormSRGB) return { byteLength: 8, width: 4, height: 4 }; if (format2 === GPUTextureFormat.ETC2RGB8A1Unorm || format2 === GPUTextureFormat.ETC2RGB8A1UnormSRGB) return { byteLength: 8, width: 4, height: 4 }; if (format2 === GPUTextureFormat.ETC2RGBA8Unorm || format2 === GPUTextureFormat.ETC2RGBA8UnormSRGB) return { byteLength: 16, width: 4, height: 4 }; if (format2 === GPUTextureFormat.EACR11Unorm) return { byteLength: 8, width: 4, height: 4 }; if (format2 === GPUTextureFormat.EACR11Snorm) return { byteLength: 8, width: 4, height: 4 }; if (format2 === GPUTextureFormat.EACRG11Unorm) return { byteLength: 16, width: 4, height: 4 }; if (format2 === GPUTextureFormat.EACRG11Snorm) return { byteLength: 16, width: 4, height: 4 }; if (format2 === GPUTextureFormat.ASTC4x4Unorm || format2 === GPUTextureFormat.ASTC4x4UnormSRGB) return { byteLength: 16, width: 4, height: 4 }; if (format2 === GPUTextureFormat.ASTC5x4Unorm || format2 === GPUTextureFormat.ASTC5x4UnormSRGB) return { byteLength: 16, width: 5, height: 4 }; if (format2 === GPUTextureFormat.ASTC5x5Unorm || format2 === GPUTextureFormat.ASTC5x5UnormSRGB) return { byteLength: 16, width: 5, height: 5 }; if (format2 === GPUTextureFormat.ASTC6x5Unorm || format2 === GPUTextureFormat.ASTC6x5UnormSRGB) return { byteLength: 16, width: 6, height: 5 }; if (format2 === GPUTextureFormat.ASTC6x6Unorm || format2 === GPUTextureFormat.ASTC6x6UnormSRGB) return { byteLength: 16, width: 6, height: 6 }; if (format2 === GPUTextureFormat.ASTC8x5Unorm || format2 === GPUTextureFormat.ASTC8x5UnormSRGB) return { byteLength: 16, width: 8, height: 5 }; if (format2 === GPUTextureFormat.ASTC8x6Unorm || format2 === GPUTextureFormat.ASTC8x6UnormSRGB) return { byteLength: 16, width: 8, height: 6 }; if (format2 === GPUTextureFormat.ASTC8x8Unorm || format2 === GPUTextureFormat.ASTC8x8UnormSRGB) return { byteLength: 16, width: 8, height: 8 }; if (format2 === GPUTextureFormat.ASTC10x5Unorm || format2 === GPUTextureFormat.ASTC10x5UnormSRGB) return { byteLength: 16, width: 10, height: 5 }; if (format2 === GPUTextureFormat.ASTC10x6Unorm || format2 === GPUTextureFormat.ASTC10x6UnormSRGB) return { byteLength: 16, width: 10, height: 6 }; if (format2 === GPUTextureFormat.ASTC10x8Unorm || format2 === GPUTextureFormat.ASTC10x8UnormSRGB) return { byteLength: 16, width: 10, height: 8 }; if (format2 === GPUTextureFormat.ASTC10x10Unorm || format2 === GPUTextureFormat.ASTC10x10UnormSRGB) return { byteLength: 16, width: 10, height: 10 }; if (format2 === GPUTextureFormat.ASTC12x10Unorm || format2 === GPUTextureFormat.ASTC12x10UnormSRGB) return { byteLength: 16, width: 12, height: 10 }; if (format2 === GPUTextureFormat.ASTC12x12Unorm || format2 === GPUTextureFormat.ASTC12x12UnormSRGB) return { byteLength: 16, width: 12, height: 12 }; } _convertAddressMode(value) { let addressMode = GPUAddressMode.ClampToEdge; if (value === RepeatWrapping2) { addressMode = GPUAddressMode.Repeat; } else if (value === MirroredRepeatWrapping2) { addressMode = GPUAddressMode.MirrorRepeat; } return addressMode; } _convertFilterMode(value) { let filterMode = GPUFilterMode.Linear; if (value === NearestFilter2 || value === NearestMipmapNearestFilter2 || value === NearestMipmapLinearFilter2) { filterMode = GPUFilterMode.Nearest; } return filterMode; } _getBytesPerTexel(format2) { if (format2 === GPUTextureFormat.R8Unorm || format2 === GPUTextureFormat.R8Snorm || format2 === GPUTextureFormat.R8Uint || format2 === GPUTextureFormat.R8Sint) return 1; if (format2 === GPUTextureFormat.R16Uint || format2 === GPUTextureFormat.R16Sint || format2 === GPUTextureFormat.R16Float || format2 === GPUTextureFormat.RG8Unorm || format2 === GPUTextureFormat.RG8Snorm || format2 === GPUTextureFormat.RG8Uint || format2 === GPUTextureFormat.RG8Sint) return 2; if (format2 === GPUTextureFormat.R32Uint || format2 === GPUTextureFormat.R32Sint || format2 === GPUTextureFormat.R32Float || format2 === GPUTextureFormat.RG16Uint || format2 === GPUTextureFormat.RG16Sint || format2 === GPUTextureFormat.RG16Float || format2 === GPUTextureFormat.RGBA8Unorm || format2 === GPUTextureFormat.RGBA8UnormSRGB || format2 === GPUTextureFormat.RGBA8Snorm || format2 === GPUTextureFormat.RGBA8Uint || format2 === GPUTextureFormat.RGBA8Sint || format2 === GPUTextureFormat.BGRA8Unorm || format2 === GPUTextureFormat.BGRA8UnormSRGB || // Packed 32-bit formats format2 === GPUTextureFormat.RGB9E5UFloat || format2 === GPUTextureFormat.RGB10A2Unorm || format2 === GPUTextureFormat.RG11B10UFloat || format2 === GPUTextureFormat.Depth32Float || format2 === GPUTextureFormat.Depth24Plus || format2 === GPUTextureFormat.Depth24PlusStencil8 || format2 === GPUTextureFormat.Depth32FloatStencil8) return 4; if (format2 === GPUTextureFormat.RG32Uint || format2 === GPUTextureFormat.RG32Sint || format2 === GPUTextureFormat.RG32Float || format2 === GPUTextureFormat.RGBA16Uint || format2 === GPUTextureFormat.RGBA16Sint || format2 === GPUTextureFormat.RGBA16Float) return 8; if (format2 === GPUTextureFormat.RGBA32Uint || format2 === GPUTextureFormat.RGBA32Sint || format2 === GPUTextureFormat.RGBA32Float) return 16; } _getTypedArrayType(format2) { if (format2 === GPUTextureFormat.R8Uint) return Uint8Array; if (format2 === GPUTextureFormat.R8Sint) return Int8Array; if (format2 === GPUTextureFormat.R8Unorm) return Uint8Array; if (format2 === GPUTextureFormat.R8Snorm) return Int8Array; if (format2 === GPUTextureFormat.RG8Uint) return Uint8Array; if (format2 === GPUTextureFormat.RG8Sint) return Int8Array; if (format2 === GPUTextureFormat.RG8Unorm) return Uint8Array; if (format2 === GPUTextureFormat.RG8Snorm) return Int8Array; if (format2 === GPUTextureFormat.RGBA8Uint) return Uint8Array; if (format2 === GPUTextureFormat.RGBA8Sint) return Int8Array; if (format2 === GPUTextureFormat.RGBA8Unorm) return Uint8Array; if (format2 === GPUTextureFormat.RGBA8Snorm) return Int8Array; if (format2 === GPUTextureFormat.R16Uint) return Uint16Array; if (format2 === GPUTextureFormat.R16Sint) return Int16Array; if (format2 === GPUTextureFormat.RG16Uint) return Uint16Array; if (format2 === GPUTextureFormat.RG16Sint) return Int16Array; if (format2 === GPUTextureFormat.RGBA16Uint) return Uint16Array; if (format2 === GPUTextureFormat.RGBA16Sint) return Int16Array; if (format2 === GPUTextureFormat.R16Float) return Uint16Array; if (format2 === GPUTextureFormat.RG16Float) return Uint16Array; if (format2 === GPUTextureFormat.RGBA16Float) return Uint16Array; if (format2 === GPUTextureFormat.R32Uint) return Uint32Array; if (format2 === GPUTextureFormat.R32Sint) return Int32Array; if (format2 === GPUTextureFormat.R32Float) return Float32Array; if (format2 === GPUTextureFormat.RG32Uint) return Uint32Array; if (format2 === GPUTextureFormat.RG32Sint) return Int32Array; if (format2 === GPUTextureFormat.RG32Float) return Float32Array; if (format2 === GPUTextureFormat.RGBA32Uint) return Uint32Array; if (format2 === GPUTextureFormat.RGBA32Sint) return Int32Array; if (format2 === GPUTextureFormat.RGBA32Float) return Float32Array; if (format2 === GPUTextureFormat.BGRA8Unorm) return Uint8Array; if (format2 === GPUTextureFormat.BGRA8UnormSRGB) return Uint8Array; if (format2 === GPUTextureFormat.RGB10A2Unorm) return Uint32Array; if (format2 === GPUTextureFormat.RGB9E5UFloat) return Uint32Array; if (format2 === GPUTextureFormat.RG11B10UFloat) return Uint32Array; if (format2 === GPUTextureFormat.Depth32Float) return Float32Array; if (format2 === GPUTextureFormat.Depth24Plus) return Uint32Array; if (format2 === GPUTextureFormat.Depth24PlusStencil8) return Uint32Array; if (format2 === GPUTextureFormat.Depth32FloatStencil8) return Float32Array; } _getDimension(texture2) { let dimension; if (texture2.isData3DTexture) { dimension = GPUTextureDimension.ThreeD; } else { dimension = GPUTextureDimension.TwoD; } return dimension; } }; function getFormat2(texture2, device = null) { const format2 = texture2.format; const type = texture2.type; const colorSpace = texture2.colorSpace; let formatGPU; if (texture2.isCompressedTexture === true || texture2.isCompressedArrayTexture === true) { switch (format2) { case RGBA_S3TC_DXT1_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.BC1RGBAUnormSRGB : GPUTextureFormat.BC1RGBAUnorm; break; case RGBA_S3TC_DXT3_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.BC2RGBAUnormSRGB : GPUTextureFormat.BC2RGBAUnorm; break; case RGBA_S3TC_DXT5_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.BC3RGBAUnormSRGB : GPUTextureFormat.BC3RGBAUnorm; break; case RGB_ETC2_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ETC2RGB8UnormSRGB : GPUTextureFormat.ETC2RGB8Unorm; break; case RGBA_ETC2_EAC_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ETC2RGBA8UnormSRGB : GPUTextureFormat.ETC2RGBA8Unorm; break; case RGBA_ASTC_4x4_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC4x4UnormSRGB : GPUTextureFormat.ASTC4x4Unorm; break; case RGBA_ASTC_5x4_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC5x4UnormSRGB : GPUTextureFormat.ASTC5x4Unorm; break; case RGBA_ASTC_5x5_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC5x5UnormSRGB : GPUTextureFormat.ASTC5x5Unorm; break; case RGBA_ASTC_6x5_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC6x5UnormSRGB : GPUTextureFormat.ASTC6x5Unorm; break; case RGBA_ASTC_6x6_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC6x6UnormSRGB : GPUTextureFormat.ASTC6x6Unorm; break; case RGBA_ASTC_8x5_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC8x5UnormSRGB : GPUTextureFormat.ASTC8x5Unorm; break; case RGBA_ASTC_8x6_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC8x6UnormSRGB : GPUTextureFormat.ASTC8x6Unorm; break; case RGBA_ASTC_8x8_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC8x8UnormSRGB : GPUTextureFormat.ASTC8x8Unorm; break; case RGBA_ASTC_10x5_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC10x5UnormSRGB : GPUTextureFormat.ASTC10x5Unorm; break; case RGBA_ASTC_10x6_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC10x6UnormSRGB : GPUTextureFormat.ASTC10x6Unorm; break; case RGBA_ASTC_10x8_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC10x8UnormSRGB : GPUTextureFormat.ASTC10x8Unorm; break; case RGBA_ASTC_10x10_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC10x10UnormSRGB : GPUTextureFormat.ASTC10x10Unorm; break; case RGBA_ASTC_12x10_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC12x10UnormSRGB : GPUTextureFormat.ASTC12x10Unorm; break; case RGBA_ASTC_12x12_Format2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.ASTC12x12UnormSRGB : GPUTextureFormat.ASTC12x12Unorm; break; default: console.error("WebGPURenderer: Unsupported texture format.", format2); } } else { switch (format2) { case RGBAFormat2: switch (type) { case ByteType2: formatGPU = GPUTextureFormat.RGBA8Snorm; break; case ShortType2: formatGPU = GPUTextureFormat.RGBA16Sint; break; case UnsignedShortType2: formatGPU = GPUTextureFormat.RGBA16Uint; break; case UnsignedIntType2: formatGPU = GPUTextureFormat.RGBA32Uint; break; case IntType2: formatGPU = GPUTextureFormat.RGBA32Sint; break; case UnsignedByteType2: formatGPU = colorSpace === SRGBColorSpace2 ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm; break; case HalfFloatType2: formatGPU = GPUTextureFormat.RGBA16Float; break; case FloatType2: formatGPU = GPUTextureFormat.RGBA32Float; break; default: console.error("WebGPURenderer: Unsupported texture type with RGBAFormat.", type); } break; case RGBFormat2: switch (type) { case UnsignedInt5999Type2: formatGPU = GPUTextureFormat.RGB9E5UFloat; break; default: console.error("WebGPURenderer: Unsupported texture type with RGBFormat.", type); } break; case RedFormat2: switch (type) { case ByteType2: formatGPU = GPUTextureFormat.R8Snorm; break; case ShortType2: formatGPU = GPUTextureFormat.R16Sint; break; case UnsignedShortType2: formatGPU = GPUTextureFormat.R16Uint; break; case UnsignedIntType2: formatGPU = GPUTextureFormat.R32Uint; break; case IntType2: formatGPU = GPUTextureFormat.R32Sint; break; case UnsignedByteType2: formatGPU = GPUTextureFormat.R8Unorm; break; case HalfFloatType2: formatGPU = GPUTextureFormat.R16Float; break; case FloatType2: formatGPU = GPUTextureFormat.R32Float; break; default: console.error("WebGPURenderer: Unsupported texture type with RedFormat.", type); } break; case RGFormat2: switch (type) { case ByteType2: formatGPU = GPUTextureFormat.RG8Snorm; break; case ShortType2: formatGPU = GPUTextureFormat.RG16Sint; break; case UnsignedShortType2: formatGPU = GPUTextureFormat.RG16Uint; break; case UnsignedIntType2: formatGPU = GPUTextureFormat.RG32Uint; break; case IntType2: formatGPU = GPUTextureFormat.RG32Sint; break; case UnsignedByteType2: formatGPU = GPUTextureFormat.RG8Unorm; break; case HalfFloatType2: formatGPU = GPUTextureFormat.RG16Float; break; case FloatType2: formatGPU = GPUTextureFormat.RG32Float; break; default: console.error("WebGPURenderer: Unsupported texture type with RGFormat.", type); } break; case DepthFormat2: switch (type) { case UnsignedShortType2: formatGPU = GPUTextureFormat.Depth16Unorm; break; case UnsignedIntType2: formatGPU = GPUTextureFormat.Depth24Plus; break; case FloatType2: formatGPU = GPUTextureFormat.Depth32Float; break; default: console.error("WebGPURenderer: Unsupported texture type with DepthFormat.", type); } break; case DepthStencilFormat2: switch (type) { case UnsignedInt248Type2: formatGPU = GPUTextureFormat.Depth24PlusStencil8; break; case FloatType2: if (device && device.features.has(GPUFeatureName.Depth32FloatStencil8) === false) { console.error('WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.'); } formatGPU = GPUTextureFormat.Depth32FloatStencil8; break; default: console.error("WebGPURenderer: Unsupported texture type with DepthStencilFormat.", type); } break; case RedIntegerFormat2: switch (type) { case IntType2: formatGPU = GPUTextureFormat.R32Sint; break; case UnsignedIntType2: formatGPU = GPUTextureFormat.R32Uint; break; default: console.error("WebGPURenderer: Unsupported texture type with RedIntegerFormat.", type); } break; case RGIntegerFormat2: switch (type) { case IntType2: formatGPU = GPUTextureFormat.RG32Sint; break; case UnsignedIntType2: formatGPU = GPUTextureFormat.RG32Uint; break; default: console.error("WebGPURenderer: Unsupported texture type with RGIntegerFormat.", type); } break; case RGBAIntegerFormat2: switch (type) { case IntType2: formatGPU = GPUTextureFormat.RGBA32Sint; break; case UnsignedIntType2: formatGPU = GPUTextureFormat.RGBA32Uint; break; default: console.error("WebGPURenderer: Unsupported texture type with RGBAIntegerFormat.", type); } break; default: console.error("WebGPURenderer: Unsupported texture format.", format2); } } return formatGPU; } var declarationRegexp = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\-\>]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i; var propertiesRegexp = /([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/ig; var wgslTypeLib$1 = { "f32": "float", "i32": "int", "u32": "uint", "bool": "bool", "vec2<f32>": "vec2", "vec2<i32>": "ivec2", "vec2<u32>": "uvec2", "vec2<bool>": "bvec2", "vec2f": "vec2", "vec2i": "ivec2", "vec2u": "uvec2", "vec2b": "bvec2", "vec3<f32>": "vec3", "vec3<i32>": "ivec3", "vec3<u32>": "uvec3", "vec3<bool>": "bvec3", "vec3f": "vec3", "vec3i": "ivec3", "vec3u": "uvec3", "vec3b": "bvec3", "vec4<f32>": "vec4", "vec4<i32>": "ivec4", "vec4<u32>": "uvec4", "vec4<bool>": "bvec4", "vec4f": "vec4", "vec4i": "ivec4", "vec4u": "uvec4", "vec4b": "bvec4", "mat2x2<f32>": "mat2", "mat2x2f": "mat2", "mat3x3<f32>": "mat3", "mat3x3f": "mat3", "mat4x4<f32>": "mat4", "mat4x4f": "mat4", "sampler": "sampler", "texture_1d": "texture", "texture_2d": "texture", "texture_2d_array": "texture", "texture_multisampled_2d": "cubeTexture", "texture_depth_2d": "depthTexture", "texture_3d": "texture3D", "texture_cube": "cubeTexture", "texture_cube_array": "cubeTexture", "texture_storage_1d": "storageTexture", "texture_storage_2d": "storageTexture", "texture_storage_2d_array": "storageTexture", "texture_storage_3d": "storageTexture" }; var parse = (source) => { source = source.trim(); const declaration = source.match(declarationRegexp); if (declaration !== null && declaration.length === 4) { const inputsCode = declaration[2]; const propsMatches = []; let match = null; while ((match = propertiesRegexp.exec(inputsCode)) !== null) { propsMatches.push({ name: match[1], type: match[2] }); } const inputs = []; for (let i = 0; i < propsMatches.length; i++) { const { name: name2, type: type2 } = propsMatches[i]; let resolvedType = type2; if (resolvedType.startsWith("ptr")) { resolvedType = "pointer"; } else { if (resolvedType.startsWith("texture")) { resolvedType = type2.split("<")[0]; } resolvedType = wgslTypeLib$1[resolvedType]; } inputs.push(new NodeFunctionInput(resolvedType, name2)); } const blockCode = source.substring(declaration[0].length); const outputType = declaration[3] || "void"; const name = declaration[1] !== void 0 ? declaration[1] : ""; const type = wgslTypeLib$1[outputType] || outputType; return { type, inputs, name, inputsCode, blockCode, outputType }; } else { throw new Error("FunctionNode: Function is not a WGSL code."); } }; var WGSLNodeFunction = class extends NodeFunction { constructor(source) { const { type, inputs, name, inputsCode, blockCode, outputType } = parse(source); super(type, inputs, name); this.inputsCode = inputsCode; this.blockCode = blockCode; this.outputType = outputType; } getCode(name = this.name) { const outputType = this.outputType !== "void" ? "-> " + this.outputType : ""; return `fn ${name} ( ${this.inputsCode.trim()} ) ${outputType}` + this.blockCode; } }; var WGSLNodeParser = class extends NodeParser { parseFunction(source) { return new WGSLNodeFunction(source); } }; var GPUShaderStage = self.GPUShaderStage; var gpuShaderStageLib = { "vertex": GPUShaderStage ? GPUShaderStage.VERTEX : 1, "fragment": GPUShaderStage ? GPUShaderStage.FRAGMENT : 2, "compute": GPUShaderStage ? GPUShaderStage.COMPUTE : 4 }; var supports = { instance: true, swizzleAssign: false, storageBuffer: true }; var wgslFnOpLib = { "^^": "tsl_xor" }; var wgslTypeLib = { float: "f32", int: "i32", uint: "u32", bool: "bool", color: "vec3<f32>", vec2: "vec2<f32>", ivec2: "vec2<i32>", uvec2: "vec2<u32>", bvec2: "vec2<bool>", vec3: "vec3<f32>", ivec3: "vec3<i32>", uvec3: "vec3<u32>", bvec3: "vec3<bool>", vec4: "vec4<f32>", ivec4: "vec4<i32>", uvec4: "vec4<u32>", bvec4: "vec4<bool>", mat2: "mat2x2<f32>", mat3: "mat3x3<f32>", mat4: "mat4x4<f32>" }; var wgslPolyfill = { tsl_xor: new CodeNode("fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }"), mod_float: new CodeNode("fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }"), mod_vec2: new CodeNode("fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }"), mod_vec3: new CodeNode("fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }"), mod_vec4: new CodeNode("fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }"), equals_bool: new CodeNode("fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }"), equals_bvec2: new CodeNode("fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2<bool> { return vec2<bool>( a.x == b.x, a.y == b.y ); }"), equals_bvec3: new CodeNode("fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3<bool> { return vec3<bool>( a.x == b.x, a.y == b.y, a.z == b.z ); }"), equals_bvec4: new CodeNode("fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4<bool> { return vec4<bool>( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }"), repeatWrapping: new CodeNode( /* wgsl */ ` fn tsl_repeatWrapping( uv : vec2<f32>, dimension : vec2<u32> ) -> vec2<u32> { let uvScaled = vec2<u32>( uv * vec2<f32>( dimension ) ); return ( ( uvScaled % dimension ) + dimension ) % dimension; } ` ), biquadraticTexture: new CodeNode( /* wgsl */ ` fn tsl_biquadraticTexture( map : texture_2d<f32>, coord : vec2f, level : i32 ) -> vec4f { let iRes = vec2i( textureDimensions( map, level ) ); let res = vec2f( iRes ); let uvScaled = coord * res; let uvWrapping = ( ( uvScaled % res ) + res ) % res; // https://www.shadertoy.com/view/WtyXRy let uv = uvWrapping - 0.5; let iuv = floor( uv ); let f = fract( uv ); let rg1 = textureLoad( map, vec2i( iuv + vec2( 0.5, 0.5 ) ) % iRes, level ); let rg2 = textureLoad( map, vec2i( iuv + vec2( 1.5, 0.5 ) ) % iRes, level ); let rg3 = textureLoad( map, vec2i( iuv + vec2( 0.5, 1.5 ) ) % iRes, level ); let rg4 = textureLoad( map, vec2i( iuv + vec2( 1.5, 1.5 ) ) % iRes, level ); return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y ); } ` ) }; var wgslMethods = { dFdx: "dpdx", dFdy: "- dpdy", mod_float: "tsl_mod_float", mod_vec2: "tsl_mod_vec2", mod_vec3: "tsl_mod_vec3", mod_vec4: "tsl_mod_vec4", equals_bool: "tsl_equals_bool", equals_bvec2: "tsl_equals_bvec2", equals_bvec3: "tsl_equals_bvec3", equals_bvec4: "tsl_equals_bvec4", inversesqrt: "inverseSqrt", bitcast: "bitcast<f32>" }; if (/Windows/g.test(navigator.userAgent)) { wgslPolyfill.pow_float = new CodeNode("fn tsl_pow_float( a : f32, b : f32 ) -> f32 { return select( -pow( -a, b ), pow( a, b ), a > 0.0 ); }"); wgslPolyfill.pow_vec2 = new CodeNode("fn tsl_pow_vec2( a : vec2f, b : vec2f ) -> vec2f { return vec2f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ) ); }", [wgslPolyfill.pow_float]); wgslPolyfill.pow_vec3 = new CodeNode("fn tsl_pow_vec3( a : vec3f, b : vec3f ) -> vec3f { return vec3f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ) ); }", [wgslPolyfill.pow_float]); wgslPolyfill.pow_vec4 = new CodeNode("fn tsl_pow_vec4( a : vec4f, b : vec4f ) -> vec4f { return vec4f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ), tsl_pow_float( a.w, b.w ) ); }", [wgslPolyfill.pow_float]); wgslMethods.pow_float = "tsl_pow_float"; wgslMethods.pow_vec2 = "tsl_pow_vec2"; wgslMethods.pow_vec3 = "tsl_pow_vec3"; wgslMethods.pow_vec4 = "tsl_pow_vec4"; } var diagnostics = ""; if (/Firefox|Deno/g.test(navigator.userAgent) !== true) { diagnostics += "diagnostic( off, derivative_uniformity );\n"; } var WGSLNodeBuilder = class extends NodeBuilder { constructor(object, renderer3) { super(object, renderer3, new WGSLNodeParser()); this.uniformGroups = {}; this.builtins = {}; this.directives = {}; this.scopedArrays = /* @__PURE__ */ new Map(); } needsToWorkingColorSpace(texture2) { return texture2.isVideoTexture === true && texture2.colorSpace !== NoColorSpace2; } _generateTextureSample(texture2, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { if (shaderStage === "fragment") { if (depthSnippet) { return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${depthSnippet} )`; } else { return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet} )`; } } else if (this.isFilteredTexture(texture2)) { return this.generateFilteredTexture(texture2, textureProperty, uvSnippet); } else { return this.generateTextureLod(texture2, textureProperty, uvSnippet, "0"); } } _generateVideoSample(textureProperty, uvSnippet, shaderStage = this.shaderStage) { if (shaderStage === "fragment") { return `textureSampleBaseClampToEdge( ${textureProperty}, ${textureProperty}_sampler, vec2<f32>( ${uvSnippet}.x, 1.0 - ${uvSnippet}.y ) )`; } else { console.error(`WebGPURenderer: THREE.VideoTexture does not support ${shaderStage} shader.`); } } _generateTextureSampleLevel(texture2, textureProperty, uvSnippet, levelSnippet, depthSnippet, shaderStage = this.shaderStage) { if (shaderStage === "fragment" && this.isUnfilterable(texture2) === false) { return `textureSampleLevel( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${levelSnippet} )`; } else if (this.isFilteredTexture(texture2)) { return this.generateFilteredTexture(texture2, textureProperty, uvSnippet, levelSnippet); } else { return this.generateTextureLod(texture2, textureProperty, uvSnippet, levelSnippet); } } generateFilteredTexture(texture2, textureProperty, uvSnippet, levelSnippet = "0") { this._include("biquadraticTexture"); return `tsl_biquadraticTexture( ${textureProperty}, ${uvSnippet}, i32( ${levelSnippet} ) )`; } generateTextureLod(texture2, textureProperty, uvSnippet, levelSnippet = "0") { this._include("repeatWrapping"); const dimension = texture2.isMultisampleRenderTargetTexture === true ? `textureDimensions( ${textureProperty} )` : `textureDimensions( ${textureProperty}, 0 )`; return `textureLoad( ${textureProperty}, tsl_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${levelSnippet} ) )`; } generateTextureLoad(texture2, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = "0u") { if (depthSnippet) { return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${depthSnippet}, ${levelSnippet} )`; } else { return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; } } generateTextureStore(texture2, textureProperty, uvIndexSnippet, valueSnippet) { return `textureStore( ${textureProperty}, ${uvIndexSnippet}, ${valueSnippet} )`; } isUnfilterable(texture2) { return this.getComponentTypeFromTexture(texture2) !== "float" || !this.isAvailable("float32Filterable") && texture2.isDataTexture === true && texture2.type === FloatType2 || texture2.isMultisampleRenderTargetTexture === true; } generateTexture(texture2, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { let snippet = null; if (texture2.isVideoTexture === true) { snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); } else if (this.isUnfilterable(texture2)) { snippet = this.generateTextureLod(texture2, textureProperty, uvSnippet, "0", depthSnippet, shaderStage); } else { snippet = this._generateTextureSample(texture2, textureProperty, uvSnippet, depthSnippet, shaderStage); } return snippet; } generateTextureGrad(texture2, textureProperty, uvSnippet, gradSnippet, depthSnippet, shaderStage = this.shaderStage) { if (shaderStage === "fragment") { return `textureSampleGrad( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; } else { console.error(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${shaderStage} shader.`); } } generateTextureCompare(texture2, textureProperty, uvSnippet, compareSnippet, depthSnippet, shaderStage = this.shaderStage) { if (shaderStage === "fragment") { return `textureSampleCompare( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${compareSnippet} )`; } else { console.error(`WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`); } } generateTextureLevel(texture2, textureProperty, uvSnippet, levelSnippet, depthSnippet, shaderStage = this.shaderStage) { let snippet = null; if (texture2.isVideoTexture === true) { snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); } else { snippet = this._generateTextureSampleLevel(texture2, textureProperty, uvSnippet, levelSnippet, depthSnippet, shaderStage); } return snippet; } generateTextureBias(texture2, textureProperty, uvSnippet, biasSnippet, depthSnippet, shaderStage = this.shaderStage) { if (shaderStage === "fragment") { return `textureSampleBias( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${biasSnippet} )`; } else { console.error(`WebGPURenderer: THREE.TextureNode.biasNode does not support ${shaderStage} shader.`); } } getPropertyName(node, shaderStage = this.shaderStage) { if (node.isNodeVarying === true && node.needsInterpolation === true) { if (shaderStage === "vertex") { return `varyings.${node.name}`; } } else if (node.isNodeUniform === true) { const name = node.name; const type = node.type; if (type === "texture" || type === "cubeTexture" || type === "storageTexture" || type === "texture3D") { return name; } else if (type === "buffer" || type === "storageBuffer" || type === "indirectStorageBuffer") { return `NodeBuffer_${node.id}.${name}`; } else { return node.groupNode.name + "." + name; } } return super.getPropertyName(node); } getOutputStructName() { return "output"; } _getUniformGroupCount(shaderStage) { return Object.keys(this.uniforms[shaderStage]).length; } getFunctionOperator(op) { const fnOp = wgslFnOpLib[op]; if (fnOp !== void 0) { this._include(fnOp); return fnOp; } return null; } getStorageAccess(node) { if (node.isStorageTextureNode) { switch (node.access) { case GPUStorageTextureAccess.ReadOnly: return "read"; case GPUStorageTextureAccess.WriteOnly: return "write"; default: return "read_write"; } } else { switch (node.access) { case GPUBufferBindingType.Storage: return "read_write"; case GPUBufferBindingType.ReadOnlyStorage: return "read"; default: return "write"; } } } getUniformFromNode(node, type, shaderStage, name = null) { const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); if (nodeData.uniformGPU === void 0) { let uniformGPU; const group = node.groupNode; const groupName = group.name; const bindings = this.getBindGroupArray(groupName, shaderStage); if (type === "texture" || type === "cubeTexture" || type === "storageTexture" || type === "texture3D") { let texture2 = null; if (type === "texture" || type === "storageTexture") { texture2 = new NodeSampledTexture(uniformNode.name, uniformNode.node, group, node.access ? node.access : null); } else if (type === "cubeTexture") { texture2 = new NodeSampledCubeTexture(uniformNode.name, uniformNode.node, group, node.access ? node.access : null); } else if (type === "texture3D") { texture2 = new NodeSampledTexture3D(uniformNode.name, uniformNode.node, group, node.access ? node.access : null); } texture2.store = node.isStorageTextureNode === true; texture2.setVisibility(gpuShaderStageLib[shaderStage]); if (shaderStage === "fragment" && this.isUnfilterable(node.value) === false && texture2.store === false) { const sampler = new NodeSampler(`${uniformNode.name}_sampler`, uniformNode.node, group); sampler.setVisibility(gpuShaderStageLib[shaderStage]); bindings.push(sampler, texture2); uniformGPU = [sampler, texture2]; } else { bindings.push(texture2); uniformGPU = [texture2]; } } else if (type === "buffer" || type === "storageBuffer" || type === "indirectStorageBuffer") { const bufferClass = type === "buffer" ? NodeUniformBuffer : NodeStorageBuffer; const buffer2 = new bufferClass(node, group); buffer2.setVisibility(gpuShaderStageLib[shaderStage]); bindings.push(buffer2); uniformGPU = buffer2; } else { const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); let uniformsGroup = uniformsStage[groupName]; if (uniformsGroup === void 0) { uniformsGroup = new NodeUniformsGroup(groupName, group); uniformsGroup.setVisibility(gpuShaderStageLib[shaderStage]); uniformsStage[groupName] = uniformsGroup; bindings.push(uniformsGroup); } uniformGPU = this.getNodeUniform(uniformNode, type); uniformsGroup.addUniform(uniformGPU); } nodeData.uniformGPU = uniformGPU; } return uniformNode; } getBuiltin(name, property2, type, shaderStage = this.shaderStage) { const map = this.builtins[shaderStage] || (this.builtins[shaderStage] = /* @__PURE__ */ new Map()); if (map.has(name) === false) { map.set(name, { name, property: property2, type }); } return property2; } hasBuiltin(name, shaderStage = this.shaderStage) { return this.builtins[shaderStage] !== void 0 && this.builtins[shaderStage].has(name); } getVertexIndex() { if (this.shaderStage === "vertex") { return this.getBuiltin("vertex_index", "vertexIndex", "u32", "attribute"); } return "vertexIndex"; } buildFunctionCode(shaderNode) { const layout = shaderNode.layout; const flowData = this.flowShaderNode(shaderNode); const parameters = []; for (const input of layout.inputs) { parameters.push(input.name + " : " + this.getType(input.type)); } let code = `fn ${layout.name}( ${parameters.join(", ")} ) -> ${this.getType(layout.type)} { ${flowData.vars} ${flowData.code} `; if (flowData.result) { code += ` return ${flowData.result}; `; } code += "\n}\n"; return code; } getInstanceIndex() { if (this.shaderStage === "vertex") { return this.getBuiltin("instance_index", "instanceIndex", "u32", "attribute"); } return "instanceIndex"; } getInvocationLocalIndex() { return this.getBuiltin("local_invocation_index", "invocationLocalIndex", "u32", "attribute"); } getSubgroupSize() { this.enableSubGroups(); return this.getBuiltin("subgroup_size", "subgroupSize", "u32", "attribute"); } getInvocationSubgroupIndex() { this.enableSubGroups(); return this.getBuiltin("subgroup_invocation_id", "invocationSubgroupIndex", "u32", "attribute"); } getSubgroupIndex() { this.enableSubGroups(); return this.getBuiltin("subgroup_id", "subgroupIndex", "u32", "attribute"); } getDrawIndex() { return null; } getFrontFacing() { return this.getBuiltin("front_facing", "isFront", "bool"); } getFragCoord() { return this.getBuiltin("position", "fragCoord", "vec4<f32>") + ".xy"; } getFragDepth() { return "output." + this.getBuiltin("frag_depth", "depth", "f32", "output"); } isFlipY() { return false; } enableDirective(name, shaderStage = this.shaderStage) { const stage = this.directives[shaderStage] || (this.directives[shaderStage] = /* @__PURE__ */ new Set()); stage.add(name); } getDirectives(shaderStage) { const snippets = []; const directives = this.directives[shaderStage]; if (directives !== void 0) { for (const directive of directives) { snippets.push(`enable ${directive};`); } } return snippets.join("\n"); } enableSubGroups() { this.enableDirective("subgroups"); } enableSubgroupsF16() { this.enableDirective("subgroups-f16"); } enableClipDistances() { this.enableDirective("clip_distances"); } enableShaderF16() { this.enableDirective("f16"); } enableDualSourceBlending() { this.enableDirective("dual_source_blending"); } getBuiltins(shaderStage) { const snippets = []; const builtins = this.builtins[shaderStage]; if (builtins !== void 0) { for (const { name, property: property2, type } of builtins.values()) { snippets.push(`@builtin( ${name} ) ${property2} : ${type}`); } } return snippets.join(",\n "); } getScopedArray(name, scope, bufferType, bufferCount) { if (this.scopedArrays.has(name) === false) { this.scopedArrays.set(name, { name, scope, bufferType, bufferCount }); } return name; } getScopedArrays(shaderStage) { if (shaderStage !== "compute") { return; } const snippets = []; for (const { name, scope, bufferType, bufferCount } of this.scopedArrays.values()) { const type = this.getType(bufferType); snippets.push(`var<${scope}> ${name}: array< ${type}, ${bufferCount} >;`); } return snippets.join("\n"); } getAttributes(shaderStage) { const snippets = []; if (shaderStage === "compute") { this.getBuiltin("global_invocation_id", "id", "vec3<u32>", "attribute"); this.getBuiltin("workgroup_id", "workgroupId", "vec3<u32>", "attribute"); this.getBuiltin("local_invocation_id", "localId", "vec3<u32>", "attribute"); this.getBuiltin("num_workgroups", "numWorkgroups", "vec3<u32>", "attribute"); if (this.renderer.hasFeature("subgroups")) { this.enableDirective("subgroups", shaderStage); this.getBuiltin("subgroup_size", "subgroupSize", "u32", "attribute"); } } if (shaderStage === "vertex" || shaderStage === "compute") { const builtins = this.getBuiltins("attribute"); if (builtins) snippets.push(builtins); const attributes = this.getAttributesArray(); for (let index5 = 0, length2 = attributes.length; index5 < length2; index5++) { const attribute2 = attributes[index5]; const name = attribute2.name; const type = this.getType(attribute2.type); snippets.push(`@location( ${index5} ) ${name} : ${type}`); } } return snippets.join(",\n "); } getStructMembers(struct) { const snippets = []; const members = struct.getMemberTypes(); for (let i = 0; i < members.length; i++) { const member = members[i]; snippets.push(` @location( ${i} ) m${i} : ${member}<f32>`); } const builtins = this.getBuiltins("output"); if (builtins) snippets.push(" " + builtins); return snippets.join(",\n"); } getStructs(shaderStage) { const snippets = []; const structs = this.structs[shaderStage]; for (let index5 = 0, length2 = structs.length; index5 < length2; index5++) { const struct = structs[index5]; const name = struct.name; let snippet = `struct ${name} { `; snippet += this.getStructMembers(struct); snippet += "\n}"; snippets.push(snippet); snippets.push(` var<private> output : ${name}; `); } return snippets.join("\n\n"); } getVar(type, name) { return `var ${name} : ${this.getType(type)}`; } getVars(shaderStage) { const snippets = []; const vars = this.vars[shaderStage]; if (vars !== void 0) { for (const variable of vars) { snippets.push(` ${this.getVar(variable.type, variable.name)};`); } } return ` ${snippets.join("\n")} `; } getVaryings(shaderStage) { const snippets = []; if (shaderStage === "vertex") { this.getBuiltin("position", "Vertex", "vec4<f32>", "vertex"); } if (shaderStage === "vertex" || shaderStage === "fragment") { const varyings = this.varyings; const vars = this.vars[shaderStage]; for (let index5 = 0; index5 < varyings.length; index5++) { const varying2 = varyings[index5]; if (varying2.needsInterpolation) { let attributesSnippet = `@location( ${index5} )`; if (/^(int|uint|ivec|uvec)/.test(varying2.type)) { attributesSnippet += " @interpolate( flat )"; } snippets.push(`${attributesSnippet} ${varying2.name} : ${this.getType(varying2.type)}`); } else if (shaderStage === "vertex" && vars.includes(varying2) === false) { vars.push(varying2); } } } const builtins = this.getBuiltins(shaderStage); if (builtins) snippets.push(builtins); const code = snippets.join(",\n "); return shaderStage === "vertex" ? this._getWGSLStruct("VaryingsStruct", " " + code) : code; } getUniforms(shaderStage) { const uniforms = this.uniforms[shaderStage]; const bindingSnippets = []; const bufferSnippets = []; const structSnippets = []; const uniformGroups = {}; for (const uniform2 of uniforms) { const groupName = uniform2.groupNode.name; const uniformIndexes = this.bindingsIndexes[groupName]; if (uniform2.type === "texture" || uniform2.type === "cubeTexture" || uniform2.type === "storageTexture" || uniform2.type === "texture3D") { const texture2 = uniform2.node.value; if (shaderStage === "fragment" && this.isUnfilterable(texture2) === false && uniform2.node.isStorageTextureNode !== true) { if (texture2.isDepthTexture === true && texture2.compareFunction !== null) { bindingSnippets.push(`@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform2.name}_sampler : sampler_comparison;`); } else { bindingSnippets.push(`@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform2.name}_sampler : sampler;`); } } let textureType; let multisampled = ""; if (texture2.isMultisampleRenderTargetTexture === true) { multisampled = "_multisampled"; } if (texture2.isCubeTexture === true) { textureType = "texture_cube<f32>"; } else if (texture2.isDataArrayTexture === true || texture2.isCompressedArrayTexture === true) { textureType = "texture_2d_array<f32>"; } else if (texture2.isDepthTexture === true) { textureType = `texture_depth${multisampled}_2d`; } else if (texture2.isVideoTexture === true) { textureType = "texture_external"; } else if (texture2.isData3DTexture === true) { textureType = "texture_3d<f32>"; } else if (uniform2.node.isStorageTextureNode === true) { const format2 = getFormat2(texture2); const access = this.getStorageAccess(uniform2.node); textureType = `texture_storage_2d<${format2}, ${access}>`; } else { const componentPrefix = this.getComponentTypeFromTexture(texture2).charAt(0); textureType = `texture${multisampled}_2d<${componentPrefix}32>`; } bindingSnippets.push(`@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform2.name} : ${textureType};`); } else if (uniform2.type === "buffer" || uniform2.type === "storageBuffer" || uniform2.type === "indirectStorageBuffer") { const bufferNode = uniform2.node; const bufferType = this.getType(bufferNode.bufferType); const bufferCount = bufferNode.bufferCount; const bufferCountSnippet = bufferCount > 0 && uniform2.type === "buffer" ? ", " + bufferCount : ""; const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${bufferType}>` : `${bufferType}`; const bufferSnippet = ` ${uniform2.name} : array< ${bufferTypeSnippet}${bufferCountSnippet} > `; const bufferAccessMode = bufferNode.isStorageBufferNode ? `storage, ${this.getStorageAccess(bufferNode)}` : "uniform"; bufferSnippets.push(this._getWGSLStructBinding("NodeBuffer_" + bufferNode.id, bufferSnippet, bufferAccessMode, uniformIndexes.binding++, uniformIndexes.group)); } else { const vectorType = this.getType(this.getVectorType(uniform2.type)); const groupName2 = uniform2.groupNode.name; const group = uniformGroups[groupName2] || (uniformGroups[groupName2] = { index: uniformIndexes.binding++, id: uniformIndexes.group, snippets: [] }); group.snippets.push(` ${uniform2.name} : ${vectorType}`); } } for (const name in uniformGroups) { const group = uniformGroups[name]; structSnippets.push(this._getWGSLStructBinding(name, group.snippets.join(",\n"), "uniform", group.index, group.id)); } let code = bindingSnippets.join("\n"); code += bufferSnippets.join("\n"); code += structSnippets.join("\n"); return code; } buildCode() { const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; this.sortBindingGroups(); for (const shaderStage in shadersData) { const stageData = shadersData[shaderStage]; stageData.uniforms = this.getUniforms(shaderStage); stageData.attributes = this.getAttributes(shaderStage); stageData.varyings = this.getVaryings(shaderStage); stageData.structs = this.getStructs(shaderStage); stageData.vars = this.getVars(shaderStage); stageData.codes = this.getCodes(shaderStage); stageData.directives = this.getDirectives(shaderStage); stageData.scopedArrays = this.getScopedArrays(shaderStage); let flow = "// code\n\n"; flow += this.flowCode[shaderStage]; const flowNodes = this.flowNodes[shaderStage]; const mainNode = flowNodes[flowNodes.length - 1]; const outputNode = mainNode.outputNode; const isOutputStruct = outputNode !== void 0 && outputNode.isOutputStructNode === true; for (const node of flowNodes) { const flowSlotData = this.getFlowData( node /*, shaderStage*/ ); const slotName = node.name; if (slotName) { if (flow.length > 0) flow += "\n"; flow += ` // flow -> ${slotName} `; } flow += `${flowSlotData.code} `; if (node === mainNode && shaderStage !== "compute") { flow += "// result\n\n "; if (shaderStage === "vertex") { flow += `varyings.Vertex = ${flowSlotData.result};`; } else if (shaderStage === "fragment") { if (isOutputStruct) { stageData.returnType = outputNode.nodeType; flow += `return ${flowSlotData.result};`; } else { let structSnippet = " @location(0) color: vec4<f32>"; const builtins = this.getBuiltins("output"); if (builtins) structSnippet += ",\n " + builtins; stageData.returnType = "OutputStruct"; stageData.structs += this._getWGSLStruct("OutputStruct", structSnippet); stageData.structs += "\nvar<private> output : OutputStruct;\n\n"; flow += `output.color = ${flowSlotData.result}; return output;`; } } } } stageData.flow = flow; } if (this.material !== null) { this.vertexShader = this._getWGSLVertexCode(shadersData.vertex); this.fragmentShader = this._getWGSLFragmentCode(shadersData.fragment); } else { this.computeShader = this._getWGSLComputeCode(shadersData.compute, (this.object.workgroupSize || [64]).join(", ")); } } getMethod(method, output2 = null) { let wgslMethod; if (output2 !== null) { wgslMethod = this._getWGSLMethod(method + "_" + output2); } if (wgslMethod === void 0) { wgslMethod = this._getWGSLMethod(method); } return wgslMethod || method; } getType(type) { return wgslTypeLib[type] || type; } isAvailable(name) { let result = supports[name]; if (result === void 0) { if (name === "float32Filterable") { result = this.renderer.hasFeature("float32-filterable"); } supports[name] = result; } return result; } _getWGSLMethod(method) { if (wgslPolyfill[method] !== void 0) { this._include(method); } return wgslMethods[method]; } _include(name) { const codeNode = wgslPolyfill[name]; codeNode.build(this); if (this.currentFunctionNode !== null) { this.currentFunctionNode.includes.push(codeNode); } return codeNode; } _getWGSLVertexCode(shaderData) { return `${this.getSignature()} // directives ${shaderData.directives} // uniforms ${shaderData.uniforms} // varyings ${shaderData.varyings} var<private> varyings : VaryingsStruct; // codes ${shaderData.codes} @vertex fn main( ${shaderData.attributes} ) -> VaryingsStruct { // vars ${shaderData.vars} // flow ${shaderData.flow} return varyings; } `; } _getWGSLFragmentCode(shaderData) { return `${this.getSignature()} // global ${diagnostics} // uniforms ${shaderData.uniforms} // structs ${shaderData.structs} // codes ${shaderData.codes} @fragment fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} { // vars ${shaderData.vars} // flow ${shaderData.flow} } `; } _getWGSLComputeCode(shaderData, workgroupSize) { return `${this.getSignature()} // directives ${shaderData.directives} // system var<private> instanceIndex : u32; // locals ${shaderData.scopedArrays} // uniforms ${shaderData.uniforms} // codes ${shaderData.codes} @compute @workgroup_size( ${workgroupSize} ) fn main( ${shaderData.attributes} ) { // system instanceIndex = id.x + id.y * numWorkgroups.x * u32(${workgroupSize}) + id.z * numWorkgroups.x * numWorkgroups.y * u32(${workgroupSize}); // vars ${shaderData.vars} // flow ${shaderData.flow} } `; } _getWGSLStruct(name, vars) { return ` struct ${name} { ${vars} };`; } _getWGSLStructBinding(name, vars, access, binding = 0, group = 0) { const structName = name + "Struct"; const structSnippet = this._getWGSLStruct(structName, vars); return `${structSnippet} @binding( ${binding} ) @group( ${group} ) var<${access}> ${name} : ${structName};`; } }; var WebGPUUtils = class { constructor(backend) { this.backend = backend; } getCurrentDepthStencilFormat(renderContext) { let format2; if (renderContext.depthTexture !== null) { format2 = this.getTextureFormatGPU(renderContext.depthTexture); } else if (renderContext.depth && renderContext.stencil) { format2 = GPUTextureFormat.Depth24PlusStencil8; } else if (renderContext.depth) { format2 = GPUTextureFormat.Depth24Plus; } return format2; } getTextureFormatGPU(texture2) { return this.backend.get(texture2).format; } getCurrentColorFormat(renderContext) { let format2; if (renderContext.textures !== null) { format2 = this.getTextureFormatGPU(renderContext.textures[0]); } else { format2 = this.getPreferredCanvasFormat(); } return format2; } getCurrentColorSpace(renderContext) { if (renderContext.textures !== null) { return renderContext.textures[0].colorSpace; } return this.backend.renderer.outputColorSpace; } getPrimitiveTopology(object, material) { if (object.isPoints) return GPUPrimitiveTopology.PointList; else if (object.isLineSegments || object.isMesh && material.wireframe === true) return GPUPrimitiveTopology.LineList; else if (object.isLine) return GPUPrimitiveTopology.LineStrip; else if (object.isMesh) return GPUPrimitiveTopology.TriangleList; } getSampleCount(sampleCount) { let count = 1; if (sampleCount > 1) { count = Math.pow(2, Math.floor(Math.log2(sampleCount))); if (count === 2) { count = 4; } } return count; } getSampleCountRenderContext(renderContext) { if (renderContext.textures !== null) { return this.getSampleCount(renderContext.sampleCount); } return this.getSampleCount(this.backend.renderer.samples); } getPreferredCanvasFormat() { if (navigator.userAgent.includes("Quest")) { return GPUTextureFormat.BGRA8Unorm; } else { return navigator.gpu.getPreferredCanvasFormat(); } } }; var typedArraysToVertexFormatPrefix = /* @__PURE__ */ new Map([ [Int8Array, ["sint8", "snorm8"]], [Uint8Array, ["uint8", "unorm8"]], [Int16Array, ["sint16", "snorm16"]], [Uint16Array, ["uint16", "unorm16"]], [Int32Array, ["sint32", "snorm32"]], [Uint32Array, ["uint32", "unorm32"]], [Float32Array, ["float32"]] ]); var typedAttributeToVertexFormatPrefix = /* @__PURE__ */ new Map([ [Float16BufferAttribute, ["float16"]] ]); var typeArraysToVertexFormatPrefixForItemSize1 = /* @__PURE__ */ new Map([ [Int32Array, "sint32"], [Int16Array, "sint32"], // patch for INT16 [Uint32Array, "uint32"], [Uint16Array, "uint32"], // patch for UINT16 [Float32Array, "float32"] ]); var WebGPUAttributeUtils = class { constructor(backend) { this.backend = backend; } createAttribute(attribute2, usage) { const bufferAttribute2 = this._getBufferAttribute(attribute2); const backend = this.backend; const bufferData = backend.get(bufferAttribute2); let buffer2 = bufferData.buffer; if (buffer2 === void 0) { const device = backend.device; let array = bufferAttribute2.array; if (attribute2.normalized === false && (array.constructor === Int16Array || array.constructor === Uint16Array)) { const tempArray = new Uint32Array(array.length); for (let i = 0; i < array.length; i++) { tempArray[i] = array[i]; } array = tempArray; } bufferAttribute2.array = array; if ((bufferAttribute2.isStorageBufferAttribute || bufferAttribute2.isStorageInstancedBufferAttribute) && bufferAttribute2.itemSize === 3) { array = new array.constructor(bufferAttribute2.count * 4); for (let i = 0; i < bufferAttribute2.count; i++) { array.set(bufferAttribute2.array.subarray(i * 3, i * 3 + 3), i * 4); } bufferAttribute2.itemSize = 4; bufferAttribute2.array = array; } const size = array.byteLength + (4 - array.byteLength % 4) % 4; buffer2 = device.createBuffer({ label: bufferAttribute2.name, size, usage, mappedAtCreation: true }); new array.constructor(buffer2.getMappedRange()).set(array); buffer2.unmap(); bufferData.buffer = buffer2; } } updateAttribute(attribute2) { const bufferAttribute2 = this._getBufferAttribute(attribute2); const backend = this.backend; const device = backend.device; const buffer2 = backend.get(bufferAttribute2).buffer; const array = bufferAttribute2.array; const updateRanges = bufferAttribute2.updateRanges; if (updateRanges.length === 0) { device.queue.writeBuffer( buffer2, 0, array, 0 ); } else { for (let i = 0, l = updateRanges.length; i < l; i++) { const range = updateRanges[i]; device.queue.writeBuffer( buffer2, 0, array, range.start * array.BYTES_PER_ELEMENT, range.count * array.BYTES_PER_ELEMENT ); } bufferAttribute2.clearUpdateRanges(); } } createShaderVertexBuffers(renderObject) { const attributes = renderObject.getAttributes(); const vertexBuffers = /* @__PURE__ */ new Map(); for (let slot = 0; slot < attributes.length; slot++) { const geometryAttribute = attributes[slot]; const bytesPerElement = geometryAttribute.array.BYTES_PER_ELEMENT; const bufferAttribute2 = this._getBufferAttribute(geometryAttribute); let vertexBufferLayout = vertexBuffers.get(bufferAttribute2); if (vertexBufferLayout === void 0) { let arrayStride, stepMode; if (geometryAttribute.isInterleavedBufferAttribute === true) { arrayStride = geometryAttribute.data.stride * bytesPerElement; stepMode = geometryAttribute.data.isInstancedInterleavedBuffer ? GPUInputStepMode.Instance : GPUInputStepMode.Vertex; } else { arrayStride = geometryAttribute.itemSize * bytesPerElement; stepMode = geometryAttribute.isInstancedBufferAttribute ? GPUInputStepMode.Instance : GPUInputStepMode.Vertex; } if (geometryAttribute.normalized === false && (geometryAttribute.array.constructor === Int16Array || geometryAttribute.array.constructor === Uint16Array)) { arrayStride = 4; } vertexBufferLayout = { arrayStride, attributes: [], stepMode }; vertexBuffers.set(bufferAttribute2, vertexBufferLayout); } const format2 = this._getVertexFormat(geometryAttribute); const offset = geometryAttribute.isInterleavedBufferAttribute === true ? geometryAttribute.offset * bytesPerElement : 0; vertexBufferLayout.attributes.push({ shaderLocation: slot, offset, format: format2 }); } return Array.from(vertexBuffers.values()); } destroyAttribute(attribute2) { const backend = this.backend; const data = backend.get(this._getBufferAttribute(attribute2)); data.buffer.destroy(); backend.delete(attribute2); } async getArrayBufferAsync(attribute2) { const backend = this.backend; const device = backend.device; const data = backend.get(this._getBufferAttribute(attribute2)); const bufferGPU = data.buffer; const size = bufferGPU.size; const readBufferGPU = device.createBuffer({ label: attribute2.name, size, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ }); const cmdEncoder = device.createCommandEncoder({}); cmdEncoder.copyBufferToBuffer( bufferGPU, 0, readBufferGPU, 0, size ); readBufferGPU.unmap(); const gpuCommands = cmdEncoder.finish(); device.queue.submit([gpuCommands]); await readBufferGPU.mapAsync(GPUMapMode.READ); const arrayBuffer = readBufferGPU.getMappedRange(); return arrayBuffer; } _getVertexFormat(geometryAttribute) { const { itemSize, normalized } = geometryAttribute; const ArrayType = geometryAttribute.array.constructor; const AttributeType2 = geometryAttribute.constructor; let format2; if (itemSize == 1) { format2 = typeArraysToVertexFormatPrefixForItemSize1.get(ArrayType); } else { const prefixOptions = typedAttributeToVertexFormatPrefix.get(AttributeType2) || typedArraysToVertexFormatPrefix.get(ArrayType); const prefix = prefixOptions[normalized ? 1 : 0]; if (prefix) { const bytesPerUnit = ArrayType.BYTES_PER_ELEMENT * itemSize; const paddedBytesPerUnit = Math.floor((bytesPerUnit + 3) / 4) * 4; const paddedItemSize = paddedBytesPerUnit / ArrayType.BYTES_PER_ELEMENT; if (paddedItemSize % 1) { throw new Error("THREE.WebGPUAttributeUtils: Bad vertex format item size."); } format2 = `${prefix}x${paddedItemSize}`; } } if (!format2) { console.error("THREE.WebGPUAttributeUtils: Vertex format not supported yet."); } return format2; } _getBufferAttribute(attribute2) { if (attribute2.isInterleavedBufferAttribute) attribute2 = attribute2.data; return attribute2; } }; var WebGPUBindingUtils = class { constructor(backend) { this.backend = backend; this.bindGroupLayoutCache = /* @__PURE__ */ new WeakMap(); } createBindingsLayout(bindGroup) { const backend = this.backend; const device = backend.device; const entries = []; let index5 = 0; for (const binding of bindGroup.bindings) { const bindingGPU = { binding: index5++, visibility: binding.visibility }; if (binding.isUniformBuffer || binding.isStorageBuffer) { const buffer2 = {}; if (binding.isStorageBuffer) { buffer2.type = binding.access; } bindingGPU.buffer = buffer2; } else if (binding.isSampler) { const sampler = {}; if (binding.texture.isDepthTexture) { if (binding.texture.compareFunction !== null) { sampler.type = "comparison"; } } bindingGPU.sampler = sampler; } else if (binding.isSampledTexture && binding.texture.isVideoTexture) { bindingGPU.externalTexture = {}; } else if (binding.isSampledTexture && binding.store) { const format2 = this.backend.get(binding.texture).texture.format; const access = binding.access; bindingGPU.storageTexture = { format: format2, access }; } else if (binding.isSampledTexture) { const texture2 = {}; if (binding.texture.isMultisampleRenderTargetTexture === true) { texture2.multisampled = true; } if (binding.texture.isDepthTexture) { texture2.sampleType = GPUTextureSampleType.Depth; } else if (binding.texture.isDataTexture || binding.texture.isDataArrayTexture || binding.texture.isData3DTexture) { const type = binding.texture.type; if (type === IntType2) { texture2.sampleType = GPUTextureSampleType.SInt; } else if (type === UnsignedIntType2) { texture2.sampleType = GPUTextureSampleType.UInt; } else if (type === FloatType2) { if (this.backend.hasFeature("float32-filterable")) { texture2.sampleType = GPUTextureSampleType.Float; } else { texture2.sampleType = GPUTextureSampleType.UnfilterableFloat; } } } if (binding.isSampledCubeTexture) { texture2.viewDimension = GPUTextureViewDimension.Cube; } else if (binding.texture.isDataArrayTexture || binding.texture.isCompressedArrayTexture) { texture2.viewDimension = GPUTextureViewDimension.TwoDArray; } else if (binding.isSampledTexture3D) { texture2.viewDimension = GPUTextureViewDimension.ThreeD; } bindingGPU.texture = texture2; } else { console.error(`WebGPUBindingUtils: Unsupported binding "${binding}".`); } entries.push(bindingGPU); } return device.createBindGroupLayout({ entries }); } createBindings(bindGroup) { const { backend, bindGroupLayoutCache } = this; const bindingsData = backend.get(bindGroup); let bindLayoutGPU = bindGroupLayoutCache.get(bindGroup.bindingsReference); if (bindLayoutGPU === void 0) { bindLayoutGPU = this.createBindingsLayout(bindGroup); bindGroupLayoutCache.set(bindGroup.bindingsReference, bindLayoutGPU); } const bindGroupGPU = this.createBindGroup(bindGroup, bindLayoutGPU); bindingsData.layout = bindLayoutGPU; bindingsData.group = bindGroupGPU; } updateBinding(binding) { const backend = this.backend; const device = backend.device; const buffer2 = binding.buffer; const bufferGPU = backend.get(binding).buffer; device.queue.writeBuffer(bufferGPU, 0, buffer2, 0); } createBindGroup(bindGroup, layoutGPU) { const backend = this.backend; const device = backend.device; let bindingPoint = 0; const entriesGPU = []; for (const binding of bindGroup.bindings) { if (binding.isUniformBuffer) { const bindingData = backend.get(binding); if (bindingData.buffer === void 0) { const byteLength = binding.byteLength; const usage = GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST; const bufferGPU = device.createBuffer({ label: "bindingBuffer_" + binding.name, size: byteLength, usage }); bindingData.buffer = bufferGPU; } entriesGPU.push({ binding: bindingPoint, resource: { buffer: bindingData.buffer } }); } else if (binding.isStorageBuffer) { const bindingData = backend.get(binding); if (bindingData.buffer === void 0) { const attribute2 = binding.attribute; bindingData.buffer = backend.get(attribute2).buffer; } entriesGPU.push({ binding: bindingPoint, resource: { buffer: bindingData.buffer } }); } else if (binding.isSampler) { const textureGPU = backend.get(binding.texture); entriesGPU.push({ binding: bindingPoint, resource: textureGPU.sampler }); } else if (binding.isSampledTexture) { const textureData = backend.get(binding.texture); let resourceGPU; if (textureData.externalTexture !== void 0) { resourceGPU = device.importExternalTexture({ source: textureData.externalTexture }); } else { const mipLevelCount = binding.store ? 1 : textureData.texture.mipLevelCount; const propertyName = `view-${textureData.texture.width}-${textureData.texture.height}-${mipLevelCount}`; resourceGPU = textureData[propertyName]; if (resourceGPU === void 0) { const aspectGPU = GPUTextureAspect.All; let dimensionViewGPU; if (binding.isSampledCubeTexture) { dimensionViewGPU = GPUTextureViewDimension.Cube; } else if (binding.isSampledTexture3D) { dimensionViewGPU = GPUTextureViewDimension.ThreeD; } else if (binding.texture.isDataArrayTexture || binding.texture.isCompressedArrayTexture) { dimensionViewGPU = GPUTextureViewDimension.TwoDArray; } else { dimensionViewGPU = GPUTextureViewDimension.TwoD; } resourceGPU = textureData[propertyName] = textureData.texture.createView({ aspect: aspectGPU, dimension: dimensionViewGPU, mipLevelCount }); } } entriesGPU.push({ binding: bindingPoint, resource: resourceGPU }); } bindingPoint++; } return device.createBindGroup({ label: "bindGroup_" + bindGroup.name, layout: layoutGPU, entries: entriesGPU }); } }; var WebGPUPipelineUtils = class { constructor(backend) { this.backend = backend; } _getSampleCount(renderObjectContext) { return this.backend.utils.getSampleCountRenderContext(renderObjectContext); } createRenderPipeline(renderObject, promises) { const { object, material, geometry, pipeline } = renderObject; const { vertexProgram, fragmentProgram } = pipeline; const backend = this.backend; const device = backend.device; const utils = backend.utils; const pipelineData = backend.get(pipeline); const bindGroupLayouts = []; for (const bindGroup of renderObject.getBindings()) { const bindingsData = backend.get(bindGroup); bindGroupLayouts.push(bindingsData.layout); } const vertexBuffers = backend.attributeUtils.createShaderVertexBuffers(renderObject); let blending; if (material.transparent === true && material.blending !== NoBlending2) { blending = this._getBlending(material); } let stencilFront = {}; if (material.stencilWrite === true) { stencilFront = { compare: this._getStencilCompare(material), failOp: this._getStencilOperation(material.stencilFail), depthFailOp: this._getStencilOperation(material.stencilZFail), passOp: this._getStencilOperation(material.stencilZPass) }; } const colorWriteMask = this._getColorWriteMask(material); const targets = []; if (renderObject.context.textures !== null) { const textures = renderObject.context.textures; for (let i = 0; i < textures.length; i++) { const colorFormat = utils.getTextureFormatGPU(textures[i]); targets.push({ format: colorFormat, blend: blending, writeMask: colorWriteMask }); } } else { const colorFormat = utils.getCurrentColorFormat(renderObject.context); targets.push({ format: colorFormat, blend: blending, writeMask: colorWriteMask }); } const vertexModule = backend.get(vertexProgram).module; const fragmentModule = backend.get(fragmentProgram).module; const primitiveState = this._getPrimitiveState(object, geometry, material); const depthCompare = this._getDepthCompare(material); const depthStencilFormat = utils.getCurrentDepthStencilFormat(renderObject.context); const sampleCount = this._getSampleCount(renderObject.context); const pipelineDescriptor = { label: `renderPipeline_${material.name || material.type}_${material.id}`, vertex: Object.assign({}, vertexModule, { buffers: vertexBuffers }), fragment: Object.assign({}, fragmentModule, { targets }), primitive: primitiveState, multisample: { count: sampleCount, alphaToCoverageEnabled: material.alphaToCoverage && sampleCount > 1 }, layout: device.createPipelineLayout({ bindGroupLayouts }) }; const depthStencil = {}; const renderDepth = renderObject.context.depth; const renderStencil = renderObject.context.stencil; if (renderDepth === true || renderStencil === true) { if (renderDepth === true) { depthStencil.format = depthStencilFormat; depthStencil.depthWriteEnabled = material.depthWrite; depthStencil.depthCompare = depthCompare; } if (renderStencil === true) { depthStencil.stencilFront = stencilFront; depthStencil.stencilBack = {}; depthStencil.stencilReadMask = material.stencilFuncMask; depthStencil.stencilWriteMask = material.stencilWriteMask; } pipelineDescriptor.depthStencil = depthStencil; } if (promises === null) { pipelineData.pipeline = device.createRenderPipeline(pipelineDescriptor); } else { const p = new Promise((resolve) => { device.createRenderPipelineAsync(pipelineDescriptor).then((pipeline2) => { pipelineData.pipeline = pipeline2; resolve(); }); }); promises.push(p); } } createBundleEncoder(renderContext) { const backend = this.backend; const { utils, device } = backend; const depthStencilFormat = utils.getCurrentDepthStencilFormat(renderContext); const colorFormat = utils.getCurrentColorFormat(renderContext); const sampleCount = this._getSampleCount(renderContext); const descriptor = { label: "renderBundleEncoder", colorFormats: [colorFormat], depthStencilFormat, sampleCount }; return device.createRenderBundleEncoder(descriptor); } createComputePipeline(pipeline, bindings) { const backend = this.backend; const device = backend.device; const computeProgram = backend.get(pipeline.computeProgram).module; const pipelineGPU = backend.get(pipeline); const bindGroupLayouts = []; for (const bindingsGroup of bindings) { const bindingsData = backend.get(bindingsGroup); bindGroupLayouts.push(bindingsData.layout); } pipelineGPU.pipeline = device.createComputePipeline({ compute: computeProgram, layout: device.createPipelineLayout({ bindGroupLayouts }) }); } _getBlending(material) { let color2, alpha; const blending = material.blending; const blendSrc = material.blendSrc; const blendDst = material.blendDst; const blendEquation = material.blendEquation; if (blending === CustomBlending2) { const blendSrcAlpha = material.blendSrcAlpha !== null ? material.blendSrcAlpha : blendSrc; const blendDstAlpha = material.blendDstAlpha !== null ? material.blendDstAlpha : blendDst; const blendEquationAlpha = material.blendEquationAlpha !== null ? material.blendEquationAlpha : blendEquation; color2 = { srcFactor: this._getBlendFactor(blendSrc), dstFactor: this._getBlendFactor(blendDst), operation: this._getBlendOperation(blendEquation) }; alpha = { srcFactor: this._getBlendFactor(blendSrcAlpha), dstFactor: this._getBlendFactor(blendDstAlpha), operation: this._getBlendOperation(blendEquationAlpha) }; } else { const premultipliedAlpha = material.premultipliedAlpha; const setBlend = (srcRGB, dstRGB, srcAlpha, dstAlpha) => { color2 = { srcFactor: srcRGB, dstFactor: dstRGB, operation: GPUBlendOperation.Add }; alpha = { srcFactor: srcAlpha, dstFactor: dstAlpha, operation: GPUBlendOperation.Add }; }; if (premultipliedAlpha) { switch (blending) { case NormalBlending2: setBlend(GPUBlendFactor.One, GPUBlendFactor.OneMinusSrcAlpha, GPUBlendFactor.One, GPUBlendFactor.OneMinusSrcAlpha); break; case AdditiveBlending2: setBlend(GPUBlendFactor.One, GPUBlendFactor.One, GPUBlendFactor.One, GPUBlendFactor.One); break; case SubtractiveBlending2: setBlend(GPUBlendFactor.Zero, GPUBlendFactor.OneMinusSrc, GPUBlendFactor.Zero, GPUBlendFactor.One); break; case MultiplyBlending2: setBlend(GPUBlendFactor.Zero, GPUBlendFactor.Src, GPUBlendFactor.Zero, GPUBlendFactor.SrcAlpha); break; } } else { switch (blending) { case NormalBlending2: setBlend(GPUBlendFactor.SrcAlpha, GPUBlendFactor.OneMinusSrcAlpha, GPUBlendFactor.One, GPUBlendFactor.OneMinusSrcAlpha); break; case AdditiveBlending2: setBlend(GPUBlendFactor.SrcAlpha, GPUBlendFactor.One, GPUBlendFactor.SrcAlpha, GPUBlendFactor.One); break; case SubtractiveBlending2: setBlend(GPUBlendFactor.Zero, GPUBlendFactor.OneMinusSrc, GPUBlendFactor.Zero, GPUBlendFactor.One); break; case MultiplyBlending2: setBlend(GPUBlendFactor.Zero, GPUBlendFactor.Src, GPUBlendFactor.Zero, GPUBlendFactor.Src); break; } } } if (color2 !== void 0 && alpha !== void 0) { return { color: color2, alpha }; } else { console.error("THREE.WebGPURenderer: Invalid blending: ", blending); } } _getBlendFactor(blend) { let blendFactor; switch (blend) { case ZeroFactor2: blendFactor = GPUBlendFactor.Zero; break; case OneFactor2: blendFactor = GPUBlendFactor.One; break; case SrcColorFactor2: blendFactor = GPUBlendFactor.Src; break; case OneMinusSrcColorFactor2: blendFactor = GPUBlendFactor.OneMinusSrc; break; case SrcAlphaFactor2: blendFactor = GPUBlendFactor.SrcAlpha; break; case OneMinusSrcAlphaFactor2: blendFactor = GPUBlendFactor.OneMinusSrcAlpha; break; case DstColorFactor2: blendFactor = GPUBlendFactor.Dst; break; case OneMinusDstColorFactor2: blendFactor = GPUBlendFactor.OneMinusDstColor; break; case DstAlphaFactor2: blendFactor = GPUBlendFactor.DstAlpha; break; case OneMinusDstAlphaFactor2: blendFactor = GPUBlendFactor.OneMinusDstAlpha; break; case SrcAlphaSaturateFactor2: blendFactor = GPUBlendFactor.SrcAlphaSaturated; break; case BlendColorFactor: blendFactor = GPUBlendFactor.Constant; break; case OneMinusBlendColorFactor: blendFactor = GPUBlendFactor.OneMinusConstant; break; default: console.error("THREE.WebGPURenderer: Blend factor not supported.", blend); } return blendFactor; } _getStencilCompare(material) { let stencilCompare; const stencilFunc = material.stencilFunc; switch (stencilFunc) { case NeverStencilFunc: stencilCompare = GPUCompareFunction.Never; break; case AlwaysStencilFunc2: stencilCompare = GPUCompareFunction.Always; break; case LessStencilFunc: stencilCompare = GPUCompareFunction.Less; break; case LessEqualStencilFunc: stencilCompare = GPUCompareFunction.LessEqual; break; case EqualStencilFunc: stencilCompare = GPUCompareFunction.Equal; break; case GreaterEqualStencilFunc: stencilCompare = GPUCompareFunction.GreaterEqual; break; case GreaterStencilFunc: stencilCompare = GPUCompareFunction.Greater; break; case NotEqualStencilFunc: stencilCompare = GPUCompareFunction.NotEqual; break; default: console.error("THREE.WebGPURenderer: Invalid stencil function.", stencilFunc); } return stencilCompare; } _getStencilOperation(op) { let stencilOperation; switch (op) { case KeepStencilOp2: stencilOperation = GPUStencilOperation.Keep; break; case ZeroStencilOp: stencilOperation = GPUStencilOperation.Zero; break; case ReplaceStencilOp: stencilOperation = GPUStencilOperation.Replace; break; case InvertStencilOp: stencilOperation = GPUStencilOperation.Invert; break; case IncrementStencilOp: stencilOperation = GPUStencilOperation.IncrementClamp; break; case DecrementStencilOp: stencilOperation = GPUStencilOperation.DecrementClamp; break; case IncrementWrapStencilOp: stencilOperation = GPUStencilOperation.IncrementWrap; break; case DecrementWrapStencilOp: stencilOperation = GPUStencilOperation.DecrementWrap; break; default: console.error("THREE.WebGPURenderer: Invalid stencil operation.", stencilOperation); } return stencilOperation; } _getBlendOperation(blendEquation) { let blendOperation; switch (blendEquation) { case AddEquation2: blendOperation = GPUBlendOperation.Add; break; case SubtractEquation2: blendOperation = GPUBlendOperation.Subtract; break; case ReverseSubtractEquation2: blendOperation = GPUBlendOperation.ReverseSubtract; break; case MinEquation2: blendOperation = GPUBlendOperation.Min; break; case MaxEquation2: blendOperation = GPUBlendOperation.Max; break; default: console.error("THREE.WebGPUPipelineUtils: Blend equation not supported.", blendEquation); } return blendOperation; } _getPrimitiveState(object, geometry, material) { const descriptor = {}; const utils = this.backend.utils; descriptor.topology = utils.getPrimitiveTopology(object, material); if (geometry.index !== null && object.isLine === true && object.isLineSegments !== true) { descriptor.stripIndexFormat = geometry.index.array instanceof Uint16Array ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; } switch (material.side) { case FrontSide2: descriptor.frontFace = GPUFrontFace.CCW; descriptor.cullMode = GPUCullMode.Back; break; case BackSide2: descriptor.frontFace = GPUFrontFace.CCW; descriptor.cullMode = GPUCullMode.Front; break; case DoubleSide2: descriptor.frontFace = GPUFrontFace.CCW; descriptor.cullMode = GPUCullMode.None; break; default: console.error("THREE.WebGPUPipelineUtils: Unknown material.side value.", material.side); break; } return descriptor; } _getColorWriteMask(material) { return material.colorWrite === true ? GPUColorWriteFlags.All : GPUColorWriteFlags.None; } _getDepthCompare(material) { let depthCompare; if (material.depthTest === false) { depthCompare = GPUCompareFunction.Always; } else { const depthFunc = material.depthFunc; switch (depthFunc) { case NeverDepth2: depthCompare = GPUCompareFunction.Never; break; case AlwaysDepth2: depthCompare = GPUCompareFunction.Always; break; case LessDepth2: depthCompare = GPUCompareFunction.Less; break; case LessEqualDepth2: depthCompare = GPUCompareFunction.LessEqual; break; case EqualDepth2: depthCompare = GPUCompareFunction.Equal; break; case GreaterEqualDepth2: depthCompare = GPUCompareFunction.GreaterEqual; break; case GreaterDepth2: depthCompare = GPUCompareFunction.Greater; break; case NotEqualDepth2: depthCompare = GPUCompareFunction.NotEqual; break; default: console.error("THREE.WebGPUPipelineUtils: Invalid depth function.", depthFunc); } } return depthCompare; } }; var WebGPUBackend = class extends Backend { constructor(parameters = {}) { super(parameters); this.isWebGPUBackend = true; this.parameters.alpha = parameters.alpha === void 0 ? true : parameters.alpha; this.parameters.requiredLimits = parameters.requiredLimits === void 0 ? {} : parameters.requiredLimits; this.trackTimestamp = parameters.trackTimestamp === true; this.device = null; this.context = null; this.colorBuffer = null; this.defaultRenderPassdescriptor = null; this.utils = new WebGPUUtils(this); this.attributeUtils = new WebGPUAttributeUtils(this); this.bindingUtils = new WebGPUBindingUtils(this); this.pipelineUtils = new WebGPUPipelineUtils(this); this.textureUtils = new WebGPUTextureUtils(this); this.occludedResolveCache = /* @__PURE__ */ new Map(); } async init(renderer3) { await super.init(renderer3); const parameters = this.parameters; let device; if (parameters.device === void 0) { const adapterOptions = { powerPreference: parameters.powerPreference }; const adapter = await navigator.gpu.requestAdapter(adapterOptions); if (adapter === null) { throw new Error("WebGPUBackend: Unable to create WebGPU adapter."); } const features = Object.values(GPUFeatureName); const supportedFeatures = []; for (const name of features) { if (adapter.features.has(name)) { supportedFeatures.push(name); } } const deviceDescriptor = { requiredFeatures: supportedFeatures, requiredLimits: parameters.requiredLimits }; device = await adapter.requestDevice(deviceDescriptor); } else { device = parameters.device; } device.lost.then((info) => { const deviceLossInfo = { api: "WebGPU", message: info.message || "Unknown reason", reason: info.reason || null, originalEvent: info }; renderer3.onDeviceLost(deviceLossInfo); }); const context2 = parameters.context !== void 0 ? parameters.context : renderer3.domElement.getContext("webgpu"); this.device = device; this.context = context2; const alphaMode = parameters.alpha ? "premultiplied" : "opaque"; this.trackTimestamp = this.trackTimestamp && this.hasFeature(GPUFeatureName.TimestampQuery); this.context.configure({ device: this.device, format: this.utils.getPreferredCanvasFormat(), usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, alphaMode }); this.updateSize(); } get coordinateSystem() { return WebGPUCoordinateSystem2; } async getArrayBufferAsync(attribute2) { return await this.attributeUtils.getArrayBufferAsync(attribute2); } getContext() { return this.context; } _getDefaultRenderPassDescriptor() { let descriptor = this.defaultRenderPassdescriptor; if (descriptor === null) { const renderer3 = this.renderer; descriptor = { colorAttachments: [{ view: null }] }; if (this.renderer.depth === true || this.renderer.stencil === true) { descriptor.depthStencilAttachment = { view: this.textureUtils.getDepthBuffer(renderer3.depth, renderer3.stencil).createView() }; } const colorAttachment2 = descriptor.colorAttachments[0]; if (this.renderer.samples > 0) { colorAttachment2.view = this.colorBuffer.createView(); } else { colorAttachment2.resolveTarget = void 0; } this.defaultRenderPassdescriptor = descriptor; } const colorAttachment = descriptor.colorAttachments[0]; if (this.renderer.samples > 0) { colorAttachment.resolveTarget = this.context.getCurrentTexture().createView(); } else { colorAttachment.view = this.context.getCurrentTexture().createView(); } return descriptor; } _getRenderPassDescriptor(renderContext) { const renderTarget = renderContext.renderTarget; const renderTargetData = this.get(renderTarget); let descriptors = renderTargetData.descriptors; if (descriptors === void 0 || renderTargetData.width !== renderTarget.width || renderTargetData.height !== renderTarget.height || renderTargetData.activeMipmapLevel !== renderTarget.activeMipmapLevel || renderTargetData.samples !== renderTarget.samples) { descriptors = {}; renderTargetData.descriptors = descriptors; const onDispose = () => { renderTarget.removeEventListener("dispose", onDispose); this.delete(renderTarget); }; renderTarget.addEventListener("dispose", onDispose); } const cacheKey = renderContext.getCacheKey(); let descriptor = descriptors[cacheKey]; if (descriptor === void 0) { const textures = renderContext.textures; const colorAttachments = []; for (let i = 0; i < textures.length; i++) { const textureData = this.get(textures[i]); const textureView = textureData.texture.createView({ baseMipLevel: renderContext.activeMipmapLevel, mipLevelCount: 1, baseArrayLayer: renderContext.activeCubeFace, dimension: GPUTextureViewDimension.TwoD }); let view, resolveTarget; if (textureData.msaaTexture !== void 0) { view = textureData.msaaTexture.createView(); resolveTarget = textureView; } else { view = textureView; resolveTarget = void 0; } colorAttachments.push({ view, resolveTarget, loadOp: GPULoadOp.Load, storeOp: GPUStoreOp.Store }); } descriptor = { colorAttachments }; if (renderContext.depth) { const depthTextureData = this.get(renderContext.depthTexture); const depthStencilAttachment = { view: depthTextureData.texture.createView() }; descriptor.depthStencilAttachment = depthStencilAttachment; } descriptors[cacheKey] = descriptor; renderTargetData.width = renderTarget.width; renderTargetData.height = renderTarget.height; renderTargetData.samples = renderTarget.samples; renderTargetData.activeMipmapLevel = renderTarget.activeMipmapLevel; } return descriptor; } beginRender(renderContext) { const renderContextData = this.get(renderContext); const device = this.device; const occlusionQueryCount = renderContext.occlusionQueryCount; let occlusionQuerySet; if (occlusionQueryCount > 0) { if (renderContextData.currentOcclusionQuerySet) renderContextData.currentOcclusionQuerySet.destroy(); if (renderContextData.currentOcclusionQueryBuffer) renderContextData.currentOcclusionQueryBuffer.destroy(); renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet; renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer; renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; occlusionQuerySet = device.createQuerySet({ type: "occlusion", count: occlusionQueryCount }); renderContextData.occlusionQuerySet = occlusionQuerySet; renderContextData.occlusionQueryIndex = 0; renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); renderContextData.lastOcclusionObject = null; } let descriptor; if (renderContext.textures === null) { descriptor = this._getDefaultRenderPassDescriptor(); } else { descriptor = this._getRenderPassDescriptor(renderContext); } this.initTimestampQuery(renderContext, descriptor); descriptor.occlusionQuerySet = occlusionQuerySet; const depthStencilAttachment = descriptor.depthStencilAttachment; if (renderContext.textures !== null) { const colorAttachments = descriptor.colorAttachments; for (let i = 0; i < colorAttachments.length; i++) { const colorAttachment = colorAttachments[i]; if (renderContext.clearColor) { colorAttachment.clearValue = i === 0 ? renderContext.clearColorValue : { r: 0, g: 0, b: 0, a: 1 }; colorAttachment.loadOp = GPULoadOp.Clear; colorAttachment.storeOp = GPUStoreOp.Store; } else { colorAttachment.loadOp = GPULoadOp.Load; colorAttachment.storeOp = GPUStoreOp.Store; } } } else { const colorAttachment = descriptor.colorAttachments[0]; if (renderContext.clearColor) { colorAttachment.clearValue = renderContext.clearColorValue; colorAttachment.loadOp = GPULoadOp.Clear; colorAttachment.storeOp = GPUStoreOp.Store; } else { colorAttachment.loadOp = GPULoadOp.Load; colorAttachment.storeOp = GPUStoreOp.Store; } } if (renderContext.depth) { if (renderContext.clearDepth) { depthStencilAttachment.depthClearValue = renderContext.clearDepthValue; depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; } else { depthStencilAttachment.depthLoadOp = GPULoadOp.Load; depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; } } if (renderContext.stencil) { if (renderContext.clearStencil) { depthStencilAttachment.stencilClearValue = renderContext.clearStencilValue; depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; } else { depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; } } const encoder = device.createCommandEncoder({ label: "renderContext_" + renderContext.id }); const currentPass = encoder.beginRenderPass(descriptor); renderContextData.descriptor = descriptor; renderContextData.encoder = encoder; renderContextData.currentPass = currentPass; renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; renderContextData.renderBundles = []; if (renderContext.viewport) { this.updateViewport(renderContext); } if (renderContext.scissor) { const { x: x2, y: y2, width, height } = renderContext.scissorValue; currentPass.setScissorRect(x2, y2, width, height); } } finishRender(renderContext) { const renderContextData = this.get(renderContext); const occlusionQueryCount = renderContext.occlusionQueryCount; if (renderContextData.renderBundles.length > 0) { renderContextData.currentPass.executeBundles(renderContextData.renderBundles); } if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { renderContextData.currentPass.endOcclusionQuery(); } renderContextData.currentPass.end(); if (occlusionQueryCount > 0) { const bufferSize = occlusionQueryCount * 8; let queryResolveBuffer = this.occludedResolveCache.get(bufferSize); if (queryResolveBuffer === void 0) { queryResolveBuffer = this.device.createBuffer( { size: bufferSize, usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC } ); this.occludedResolveCache.set(bufferSize, queryResolveBuffer); } const readBuffer = this.device.createBuffer( { size: bufferSize, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ } ); renderContextData.encoder.resolveQuerySet(renderContextData.occlusionQuerySet, 0, occlusionQueryCount, queryResolveBuffer, 0); renderContextData.encoder.copyBufferToBuffer(queryResolveBuffer, 0, readBuffer, 0, bufferSize); renderContextData.occlusionQueryBuffer = readBuffer; this.resolveOccludedAsync(renderContext); } this.prepareTimestampBuffer(renderContext, renderContextData.encoder); this.device.queue.submit([renderContextData.encoder.finish()]); if (renderContext.textures !== null) { const textures = renderContext.textures; for (let i = 0; i < textures.length; i++) { const texture2 = textures[i]; if (texture2.generateMipmaps === true) { this.textureUtils.generateMipmaps(texture2); } } } } isOccluded(renderContext, object) { const renderContextData = this.get(renderContext); return renderContextData.occluded && renderContextData.occluded.has(object); } async resolveOccludedAsync(renderContext) { const renderContextData = this.get(renderContext); const { currentOcclusionQueryBuffer, currentOcclusionQueryObjects } = renderContextData; if (currentOcclusionQueryBuffer && currentOcclusionQueryObjects) { const occluded = /* @__PURE__ */ new WeakSet(); renderContextData.currentOcclusionQueryObjects = null; renderContextData.currentOcclusionQueryBuffer = null; await currentOcclusionQueryBuffer.mapAsync(GPUMapMode.READ); const buffer2 = currentOcclusionQueryBuffer.getMappedRange(); const results = new BigUint64Array(buffer2); for (let i = 0; i < currentOcclusionQueryObjects.length; i++) { if (results[i] !== BigInt(0)) { occluded.add(currentOcclusionQueryObjects[i]); } } currentOcclusionQueryBuffer.destroy(); renderContextData.occluded = occluded; } } updateViewport(renderContext) { const { currentPass } = this.get(renderContext); const { x: x2, y: y2, width, height, minDepth, maxDepth } = renderContext.viewportValue; currentPass.setViewport(x2, y2, width, height, minDepth, maxDepth); } clear(color2, depth2, stencil, renderTargetData = null) { const device = this.device; const renderer3 = this.renderer; let colorAttachments = []; let depthStencilAttachment; let clearValue; let supportsDepth; let supportsStencil; if (color2) { const clearColor = this.getClearColor(); if (this.renderer.alpha === true) { const a2 = clearColor.a; clearValue = { r: clearColor.r * a2, g: clearColor.g * a2, b: clearColor.b * a2, a: a2 }; } else { clearValue = { r: clearColor.r, g: clearColor.g, b: clearColor.b, a: clearColor.a }; } } if (renderTargetData === null) { supportsDepth = renderer3.depth; supportsStencil = renderer3.stencil; const descriptor = this._getDefaultRenderPassDescriptor(); if (color2) { colorAttachments = descriptor.colorAttachments; const colorAttachment = colorAttachments[0]; colorAttachment.clearValue = clearValue; colorAttachment.loadOp = GPULoadOp.Clear; colorAttachment.storeOp = GPUStoreOp.Store; } if (supportsDepth || supportsStencil) { depthStencilAttachment = descriptor.depthStencilAttachment; } } else { supportsDepth = renderTargetData.depth; supportsStencil = renderTargetData.stencil; if (color2) { for (const texture2 of renderTargetData.textures) { const textureData = this.get(texture2); const textureView = textureData.texture.createView(); let view, resolveTarget; if (textureData.msaaTexture !== void 0) { view = textureData.msaaTexture.createView(); resolveTarget = textureView; } else { view = textureView; resolveTarget = void 0; } colorAttachments.push({ view, resolveTarget, clearValue, loadOp: GPULoadOp.Clear, storeOp: GPUStoreOp.Store }); } } if (supportsDepth || supportsStencil) { const depthTextureData = this.get(renderTargetData.depthTexture); depthStencilAttachment = { view: depthTextureData.texture.createView() }; } } if (supportsDepth) { if (depth2) { depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; depthStencilAttachment.depthClearValue = renderer3.getClearDepth(); depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; } else { depthStencilAttachment.depthLoadOp = GPULoadOp.Load; depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; } } if (supportsStencil) { if (stencil) { depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; depthStencilAttachment.stencilClearValue = renderer3.getClearStencil(); depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; } else { depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; } } const encoder = device.createCommandEncoder({}); const currentPass = encoder.beginRenderPass({ colorAttachments, depthStencilAttachment }); currentPass.end(); device.queue.submit([encoder.finish()]); } // compute beginCompute(computeGroup) { const groupGPU = this.get(computeGroup); const descriptor = {}; this.initTimestampQuery(computeGroup, descriptor); groupGPU.cmdEncoderGPU = this.device.createCommandEncoder(); groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass(descriptor); } compute(computeGroup, computeNode, bindings, pipeline) { const { passEncoderGPU } = this.get(computeGroup); const pipelineGPU = this.get(pipeline).pipeline; passEncoderGPU.setPipeline(pipelineGPU); for (let i = 0, l = bindings.length; i < l; i++) { const bindGroup = bindings[i]; const bindingsData = this.get(bindGroup); passEncoderGPU.setBindGroup(i, bindingsData.group); } const maxComputeWorkgroupsPerDimension = this.device.limits.maxComputeWorkgroupsPerDimension; const computeNodeData = this.get(computeNode); if (computeNodeData.dispatchSize === void 0) computeNodeData.dispatchSize = { x: 0, y: 1, z: 1 }; const { dispatchSize } = computeNodeData; if (computeNode.dispatchCount > maxComputeWorkgroupsPerDimension) { dispatchSize.x = Math.min(computeNode.dispatchCount, maxComputeWorkgroupsPerDimension); dispatchSize.y = Math.ceil(computeNode.dispatchCount / maxComputeWorkgroupsPerDimension); } else { dispatchSize.x = computeNode.dispatchCount; } passEncoderGPU.dispatchWorkgroups( dispatchSize.x, dispatchSize.y, dispatchSize.z ); } finishCompute(computeGroup) { const groupData = this.get(computeGroup); groupData.passEncoderGPU.end(); this.prepareTimestampBuffer(computeGroup, groupData.cmdEncoderGPU); this.device.queue.submit([groupData.cmdEncoderGPU.finish()]); } async waitForGPU() { await this.device.queue.onSubmittedWorkDone(); } // render object draw(renderObject, info) { const { object, context: context2, pipeline } = renderObject; const bindings = renderObject.getBindings(); const renderContextData = this.get(context2); const pipelineGPU = this.get(pipeline).pipeline; const currentSets = renderContextData.currentSets; const passEncoderGPU = renderContextData.currentPass; const drawParams = renderObject.getDrawParameters(); if (drawParams === null) return; if (currentSets.pipeline !== pipelineGPU) { passEncoderGPU.setPipeline(pipelineGPU); currentSets.pipeline = pipelineGPU; } const currentBindingGroups = currentSets.bindingGroups; for (let i = 0, l = bindings.length; i < l; i++) { const bindGroup = bindings[i]; const bindingsData = this.get(bindGroup); if (currentBindingGroups[bindGroup.index] !== bindGroup.id) { passEncoderGPU.setBindGroup(bindGroup.index, bindingsData.group); currentBindingGroups[bindGroup.index] = bindGroup.id; } } const index5 = renderObject.getIndex(); const hasIndex = index5 !== null; if (hasIndex === true) { if (currentSets.index !== index5) { const buffer2 = this.get(index5).buffer; const indexFormat = index5.array instanceof Uint16Array ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; passEncoderGPU.setIndexBuffer(buffer2, indexFormat); currentSets.index = index5; } } const vertexBuffers = renderObject.getVertexBuffers(); for (let i = 0, l = vertexBuffers.length; i < l; i++) { const vertexBuffer = vertexBuffers[i]; if (currentSets.attributes[i] !== vertexBuffer) { const buffer2 = this.get(vertexBuffer).buffer; passEncoderGPU.setVertexBuffer(i, buffer2); currentSets.attributes[i] = vertexBuffer; } } if (renderContextData.occlusionQuerySet !== void 0) { const lastObject = renderContextData.lastOcclusionObject; if (lastObject !== object) { if (lastObject !== null && lastObject.occlusionTest === true) { passEncoderGPU.endOcclusionQuery(); renderContextData.occlusionQueryIndex++; } if (object.occlusionTest === true) { passEncoderGPU.beginOcclusionQuery(renderContextData.occlusionQueryIndex); renderContextData.occlusionQueryObjects[renderContextData.occlusionQueryIndex] = object; } renderContextData.lastOcclusionObject = object; } } if (object.isBatchedMesh === true) { const starts = object._multiDrawStarts; const counts = object._multiDrawCounts; const drawCount = object._multiDrawCount; const drawInstances = object._multiDrawInstances; const bytesPerElement = hasIndex ? index5.array.BYTES_PER_ELEMENT : 1; for (let i = 0; i < drawCount; i++) { const count = drawInstances ? drawInstances[i] : 1; const firstInstance = count > 1 ? 0 : i; passEncoderGPU.drawIndexed(counts[i], count, starts[i] / bytesPerElement, 0, firstInstance); } } else if (hasIndex === true) { const { vertexCount: indexCount, instanceCount, firstVertex: firstIndex } = drawParams; const indirect = renderObject.getIndirect(); if (indirect !== null) { const buffer2 = this.get(indirect).buffer; passEncoderGPU.drawIndexedIndirect(buffer2, 0); } else { passEncoderGPU.drawIndexed(indexCount, instanceCount, firstIndex, 0, 0); } info.update(object, indexCount, instanceCount); } else { const { vertexCount, instanceCount, firstVertex } = drawParams; const indirect = renderObject.getIndirect(); if (indirect !== null) { const buffer2 = this.get(indirect).buffer; passEncoderGPU.drawIndirect(buffer2, 0); } else { passEncoderGPU.draw(vertexCount, instanceCount, firstVertex, 0); } info.update(object, vertexCount, instanceCount); } } // cache key needsRenderUpdate(renderObject) { const data = this.get(renderObject); const { object, material } = renderObject; const utils = this.utils; const sampleCount = utils.getSampleCountRenderContext(renderObject.context); const colorSpace = utils.getCurrentColorSpace(renderObject.context); const colorFormat = utils.getCurrentColorFormat(renderObject.context); const depthStencilFormat = utils.getCurrentDepthStencilFormat(renderObject.context); const primitiveTopology = utils.getPrimitiveTopology(object, material); let needsUpdate = false; if (data.material !== material || data.materialVersion !== material.version || data.transparent !== material.transparent || data.blending !== material.blending || data.premultipliedAlpha !== material.premultipliedAlpha || data.blendSrc !== material.blendSrc || data.blendDst !== material.blendDst || data.blendEquation !== material.blendEquation || data.blendSrcAlpha !== material.blendSrcAlpha || data.blendDstAlpha !== material.blendDstAlpha || data.blendEquationAlpha !== material.blendEquationAlpha || data.colorWrite !== material.colorWrite || data.depthWrite !== material.depthWrite || data.depthTest !== material.depthTest || data.depthFunc !== material.depthFunc || data.stencilWrite !== material.stencilWrite || data.stencilFunc !== material.stencilFunc || data.stencilFail !== material.stencilFail || data.stencilZFail !== material.stencilZFail || data.stencilZPass !== material.stencilZPass || data.stencilFuncMask !== material.stencilFuncMask || data.stencilWriteMask !== material.stencilWriteMask || data.side !== material.side || data.alphaToCoverage !== material.alphaToCoverage || data.sampleCount !== sampleCount || data.colorSpace !== colorSpace || data.colorFormat !== colorFormat || data.depthStencilFormat !== depthStencilFormat || data.primitiveTopology !== primitiveTopology || data.clippingContextCacheKey !== renderObject.clippingContext.cacheKey) { data.material = material; data.materialVersion = material.version; data.transparent = material.transparent; data.blending = material.blending; data.premultipliedAlpha = material.premultipliedAlpha; data.blendSrc = material.blendSrc; data.blendDst = material.blendDst; data.blendEquation = material.blendEquation; data.blendSrcAlpha = material.blendSrcAlpha; data.blendDstAlpha = material.blendDstAlpha; data.blendEquationAlpha = material.blendEquationAlpha; data.colorWrite = material.colorWrite; data.depthWrite = material.depthWrite; data.depthTest = material.depthTest; data.depthFunc = material.depthFunc; data.stencilWrite = material.stencilWrite; data.stencilFunc = material.stencilFunc; data.stencilFail = material.stencilFail; data.stencilZFail = material.stencilZFail; data.stencilZPass = material.stencilZPass; data.stencilFuncMask = material.stencilFuncMask; data.stencilWriteMask = material.stencilWriteMask; data.side = material.side; data.alphaToCoverage = material.alphaToCoverage; data.sampleCount = sampleCount; data.colorSpace = colorSpace; data.colorFormat = colorFormat; data.depthStencilFormat = depthStencilFormat; data.primitiveTopology = primitiveTopology; data.clippingContextCacheKey = renderObject.clippingContext.cacheKey; needsUpdate = true; } return needsUpdate; } getRenderCacheKey(renderObject) { const { object, material } = renderObject; const utils = this.utils; const renderContext = renderObject.context; return [ material.transparent, material.blending, material.premultipliedAlpha, material.blendSrc, material.blendDst, material.blendEquation, material.blendSrcAlpha, material.blendDstAlpha, material.blendEquationAlpha, material.colorWrite, material.depthWrite, material.depthTest, material.depthFunc, material.stencilWrite, material.stencilFunc, material.stencilFail, material.stencilZFail, material.stencilZPass, material.stencilFuncMask, material.stencilWriteMask, material.side, utils.getSampleCountRenderContext(renderContext), utils.getCurrentColorSpace(renderContext), utils.getCurrentColorFormat(renderContext), utils.getCurrentDepthStencilFormat(renderContext), utils.getPrimitiveTopology(object, material), renderObject.getGeometryCacheKey(), renderObject.clippingContext.cacheKey ].join(); } // textures createSampler(texture2) { this.textureUtils.createSampler(texture2); } destroySampler(texture2) { this.textureUtils.destroySampler(texture2); } createDefaultTexture(texture2) { this.textureUtils.createDefaultTexture(texture2); } createTexture(texture2, options) { this.textureUtils.createTexture(texture2, options); } updateTexture(texture2, options) { this.textureUtils.updateTexture(texture2, options); } generateMipmaps(texture2) { this.textureUtils.generateMipmaps(texture2); } destroyTexture(texture2) { this.textureUtils.destroyTexture(texture2); } copyTextureToBuffer(texture2, x2, y2, width, height, faceIndex) { return this.textureUtils.copyTextureToBuffer(texture2, x2, y2, width, height, faceIndex); } initTimestampQuery(renderContext, descriptor) { if (!this.trackTimestamp) return; const renderContextData = this.get(renderContext); if (!renderContextData.timeStampQuerySet) { const timeStampQuerySet = this.device.createQuerySet({ type: "timestamp", count: 2 }); const timestampWrites = { querySet: timeStampQuerySet, beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins. endOfPassWriteIndex: 1 // Write timestamp in index 1 when pass ends. }; Object.assign(descriptor, { timestampWrites }); renderContextData.timeStampQuerySet = timeStampQuerySet; } } // timestamp utils prepareTimestampBuffer(renderContext, encoder) { if (!this.trackTimestamp) return; const renderContextData = this.get(renderContext); const size = 2 * BigInt64Array.BYTES_PER_ELEMENT; if (renderContextData.currentTimestampQueryBuffers === void 0) { renderContextData.currentTimestampQueryBuffers = { resolveBuffer: this.device.createBuffer({ label: "timestamp resolve buffer", size, usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC }), resultBuffer: this.device.createBuffer({ label: "timestamp result buffer", size, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ }), isMappingPending: false }; } const { resolveBuffer, resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; if (isMappingPending === true) return; encoder.resolveQuerySet(renderContextData.timeStampQuerySet, 0, 2, resolveBuffer, 0); encoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size); } async resolveTimestampAsync(renderContext, type = "render") { if (!this.trackTimestamp) return; const renderContextData = this.get(renderContext); if (renderContextData.currentTimestampQueryBuffers === void 0) return; const { resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; if (isMappingPending === true) return; renderContextData.currentTimestampQueryBuffers.isMappingPending = true; resultBuffer.mapAsync(GPUMapMode.READ).then(() => { const times = new BigUint64Array(resultBuffer.getMappedRange()); const duration = Number(times[1] - times[0]) / 1e6; this.renderer.info.updateTimestamp(type, duration); resultBuffer.unmap(); renderContextData.currentTimestampQueryBuffers.isMappingPending = false; }); } // node builder createNodeBuilder(object, renderer3) { return new WGSLNodeBuilder(object, renderer3); } // program createProgram(program) { const programGPU = this.get(program); programGPU.module = { module: this.device.createShaderModule({ code: program.code, label: program.stage }), entryPoint: "main" }; } destroyProgram(program) { this.delete(program); } // pipelines createRenderPipeline(renderObject, promises) { this.pipelineUtils.createRenderPipeline(renderObject, promises); } createComputePipeline(computePipeline, bindings) { this.pipelineUtils.createComputePipeline(computePipeline, bindings); } beginBundle(renderContext) { const renderContextData = this.get(renderContext); renderContextData._currentPass = renderContextData.currentPass; renderContextData._currentSets = renderContextData.currentSets; renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; renderContextData.currentPass = this.pipelineUtils.createBundleEncoder(renderContext); } finishBundle(renderContext, bundle) { const renderContextData = this.get(renderContext); const bundleEncoder = renderContextData.currentPass; const bundleGPU = bundleEncoder.finish(); this.get(bundle).bundleGPU = bundleGPU; renderContextData.currentSets = renderContextData._currentSets; renderContextData.currentPass = renderContextData._currentPass; } addBundle(renderContext, bundle) { const renderContextData = this.get(renderContext); renderContextData.renderBundles.push(this.get(bundle).bundleGPU); } // bindings createBindings(bindGroup) { this.bindingUtils.createBindings(bindGroup); } updateBindings(bindGroup) { this.bindingUtils.createBindings(bindGroup); } updateBinding(binding) { this.bindingUtils.updateBinding(binding); } // attributes createIndexAttribute(attribute2) { this.attributeUtils.createAttribute(attribute2, GPUBufferUsage.INDEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST); } createAttribute(attribute2) { this.attributeUtils.createAttribute(attribute2, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST); } createStorageAttribute(attribute2) { this.attributeUtils.createAttribute(attribute2, GPUBufferUsage.STORAGE | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST); } createIndirectStorageAttribute(attribute2) { this.attributeUtils.createAttribute(attribute2, GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST); } updateAttribute(attribute2) { this.attributeUtils.updateAttribute(attribute2); } destroyAttribute(attribute2) { this.attributeUtils.destroyAttribute(attribute2); } // canvas updateSize() { this.colorBuffer = this.textureUtils.getColorBuffer(); this.defaultRenderPassdescriptor = null; } // utils public getMaxAnisotropy() { return 16; } hasFeature(name) { return this.device.features.has(name); } copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { let dstX = 0; let dstY = 0; let dstLayer = 0; let srcX = 0; let srcY = 0; let srcLayer = 0; let srcWidth = srcTexture.image.width; let srcHeight = srcTexture.image.height; if (srcRegion !== null) { srcX = srcRegion.x; srcY = srcRegion.y; srcLayer = srcRegion.z || 0; srcWidth = srcRegion.width; srcHeight = srcRegion.height; } if (dstPosition !== null) { dstX = dstPosition.x; dstY = dstPosition.y; dstLayer = dstPosition.z || 0; } const encoder = this.device.createCommandEncoder({ label: "copyTextureToTexture_" + srcTexture.id + "_" + dstTexture.id }); const sourceGPU = this.get(srcTexture).texture; const destinationGPU = this.get(dstTexture).texture; encoder.copyTextureToTexture( { texture: sourceGPU, mipLevel: level, origin: { x: srcX, y: srcY, z: srcLayer } }, { texture: destinationGPU, mipLevel: level, origin: { x: dstX, y: dstY, z: dstLayer } }, [ srcWidth, srcHeight, 1 ] ); this.device.queue.submit([encoder.finish()]); } copyFramebufferToTexture(texture2, renderContext, rectangle) { const renderContextData = this.get(renderContext); let sourceGPU = null; if (renderContext.renderTarget) { if (texture2.isDepthTexture) { sourceGPU = this.get(renderContext.depthTexture).texture; } else { sourceGPU = this.get(renderContext.textures[0]).texture; } } else { if (texture2.isDepthTexture) { sourceGPU = this.textureUtils.getDepthBuffer(renderContext.depth, renderContext.stencil); } else { sourceGPU = this.context.getCurrentTexture(); } } const destinationGPU = this.get(texture2).texture; if (sourceGPU.format !== destinationGPU.format) { console.error("WebGPUBackend: copyFramebufferToTexture: Source and destination formats do not match.", sourceGPU.format, destinationGPU.format); return; } let encoder; if (renderContextData.currentPass) { renderContextData.currentPass.end(); encoder = renderContextData.encoder; } else { encoder = this.device.createCommandEncoder({ label: "copyFramebufferToTexture_" + texture2.id }); } encoder.copyTextureToTexture( { texture: sourceGPU, origin: { x: rectangle.x, y: rectangle.y, z: 0 } }, { texture: destinationGPU }, [ rectangle.z, rectangle.w ] ); if (texture2.generateMipmaps) this.textureUtils.generateMipmaps(texture2); if (renderContextData.currentPass) { const { descriptor } = renderContextData; for (let i = 0; i < descriptor.colorAttachments.length; i++) { descriptor.colorAttachments[i].loadOp = GPULoadOp.Load; } if (renderContext.depth) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load; if (renderContext.stencil) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; renderContextData.currentPass = encoder.beginRenderPass(descriptor); renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; } else { this.device.queue.submit([encoder.finish()]); } } }; var IESSpotLight = class extends SpotLight { constructor(color2, intensity, distance2, angle, penumbra, decay) { super(color2, intensity, distance2, angle, penumbra, decay); this.iesMap = null; } copy(source, recursive) { super.copy(source, recursive); this.iesMap = source.iesMap; return this; } }; var StandardNodeLibrary = class extends NodeLibrary { constructor() { super(); this.addMaterial(MeshPhongNodeMaterial, MeshPhongMaterial); this.addMaterial(MeshStandardNodeMaterial, MeshStandardMaterial); this.addMaterial(MeshPhysicalNodeMaterial, MeshPhysicalMaterial); this.addMaterial(MeshToonNodeMaterial, MeshToonMaterial); this.addMaterial(MeshBasicNodeMaterial, MeshBasicMaterial2); this.addMaterial(MeshLambertNodeMaterial, MeshLambertMaterial2); this.addMaterial(MeshNormalNodeMaterial, MeshNormalMaterial); this.addMaterial(MeshMatcapNodeMaterial, MeshMatcapMaterial); this.addMaterial(LineBasicNodeMaterial, LineBasicMaterial2); this.addMaterial(LineDashedNodeMaterial, LineDashedMaterial); this.addMaterial(PointsNodeMaterial, PointsMaterial); this.addMaterial(SpriteNodeMaterial, SpriteMaterial); this.addMaterial(ShadowNodeMaterial, ShadowMaterial); this.addLight(PointLightNode, PointLight); this.addLight(DirectionalLightNode, DirectionalLight2); this.addLight(RectAreaLightNode, RectAreaLight); this.addLight(SpotLightNode, SpotLight); this.addLight(AmbientLightNode, AmbientLight2); this.addLight(HemisphereLightNode, HemisphereLight); this.addLight(LightProbeNode, LightProbe); this.addLight(IESSpotLightNode, IESSpotLight); this.addToneMapping(linearToneMapping, LinearToneMapping2); this.addToneMapping(reinhardToneMapping, ReinhardToneMapping2); this.addToneMapping(cineonToneMapping, CineonToneMapping2); this.addToneMapping(acesFilmicToneMapping, ACESFilmicToneMapping2); this.addToneMapping(agxToneMapping, AgXToneMapping2); this.addToneMapping(neutralToneMapping, NeutralToneMapping2); } }; var WebGPURenderer = class extends Renderer { constructor(parameters = {}) { let BackendClass; if (parameters.forceWebGL) { BackendClass = WebGLBackend; } else { BackendClass = WebGPUBackend; parameters.getFallback = () => { console.warn("THREE.WebGPURenderer: WebGPU is not available, running under WebGL2 backend."); return new WebGLBackend(parameters); }; } const backend = new BackendClass(parameters); super(backend, parameters); this.library = new StandardNodeLibrary(); this.isWebGPURenderer = true; } }; if (typeof __THREE_DEVTOOLS__ !== "undefined") { __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register", { detail: { revision: REVISION2 } })); } if (typeof window !== "undefined") { if (window.__THREE__) { console.warn("WARNING: Multiple instances of Three.js being imported."); } else { window.__THREE__ = REVISION2; } } // ../../node_modules/three/examples/jsm/controls/TrackballControls.js var _changeEvent = { type: "change" }; var _startEvent = { type: "start" }; var _endEvent = { type: "end" }; var _EPS = 1e-6; var _STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 }; var _v2 = new Vector2(); var _mouseChange = new Vector2(); var _objectUp = new Vector3(); var _pan = new Vector3(); var _axis = new Vector3(); var _quaternion = new Quaternion(); var _eyeDirection = new Vector3(); var _objectUpDirection = new Vector3(); var _objectSidewaysDirection = new Vector3(); var _moveDirection = new Vector3(); var TrackballControls = class extends Controls { constructor(object, domElement = null) { super(object, domElement); this.enabled = true; this.screen = { left: 0, top: 0, width: 0, height: 0 }; this.rotateSpeed = 1; this.zoomSpeed = 1.2; this.panSpeed = 0.3; this.noRotate = false; this.noZoom = false; this.noPan = false; this.staticMoving = false; this.dynamicDampingFactor = 0.2; this.minDistance = 0; this.maxDistance = Infinity; this.minZoom = 0; this.maxZoom = Infinity; this.keys = [ "KeyA", "KeyS", "KeyD" /*D*/ ]; this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN }; this.state = _STATE.NONE; this.keyState = _STATE.NONE; this.target = new Vector3(); this._lastPosition = new Vector3(); this._lastZoom = 1; this._touchZoomDistanceStart = 0; this._touchZoomDistanceEnd = 0; this._lastAngle = 0; this._eye = new Vector3(); this._movePrev = new Vector2(); this._moveCurr = new Vector2(); this._lastAxis = new Vector3(); this._zoomStart = new Vector2(); this._zoomEnd = new Vector2(); this._panStart = new Vector2(); this._panEnd = new Vector2(); this._pointers = []; this._pointerPositions = {}; this._onPointerMove = onPointerMove2.bind(this); this._onPointerDown = onPointerDown2.bind(this); this._onPointerUp = onPointerUp.bind(this); this._onPointerCancel = onPointerCancel2.bind(this); this._onContextMenu = onContextMenu2.bind(this); this._onMouseWheel = onMouseWheel.bind(this); this._onKeyDown = onKeyDown.bind(this); this._onKeyUp = onKeyUp.bind(this); this._onTouchStart = onTouchStart.bind(this); this._onTouchMove = onTouchMove.bind(this); this._onTouchEnd = onTouchEnd.bind(this); this._onMouseDown = onMouseDown.bind(this); this._onMouseMove = onMouseMove.bind(this); this._onMouseUp = onMouseUp.bind(this); this._target0 = this.target.clone(); this._position0 = this.object.position.clone(); this._up0 = this.object.up.clone(); this._zoom0 = this.object.zoom; if (domElement !== null) { this.connect(); this.handleResize(); } this.update(); } connect() { window.addEventListener("keydown", this._onKeyDown); window.addEventListener("keyup", this._onKeyUp); this.domElement.addEventListener("pointerdown", this._onPointerDown); this.domElement.addEventListener("pointercancel", this._onPointerCancel); this.domElement.addEventListener("wheel", this._onMouseWheel, { passive: false }); this.domElement.addEventListener("contextmenu", this._onContextMenu); this.domElement.style.touchAction = "none"; } disconnect() { window.removeEventListener("keydown", this._onKeyDown); window.removeEventListener("keyup", this._onKeyUp); this.domElement.removeEventListener("pointerdown", this._onPointerDown); this.domElement.removeEventListener("pointermove", this._onPointerMove); this.domElement.removeEventListener("pointerup", this._onPointerUp); this.domElement.removeEventListener("pointercancel", this._onPointerCancel); this.domElement.removeEventListener("wheel", this._onMouseWheel); this.domElement.removeEventListener("contextmenu", this._onContextMenu); this.domElement.style.touchAction = "auto"; } dispose() { this.disconnect(); } handleResize() { const box = this.domElement.getBoundingClientRect(); const d = this.domElement.ownerDocument.documentElement; this.screen.left = box.left + window.pageXOffset - d.clientLeft; this.screen.top = box.top + window.pageYOffset - d.clientTop; this.screen.width = box.width; this.screen.height = box.height; } update() { this._eye.subVectors(this.object.position, this.target); if (!this.noRotate) { this._rotateCamera(); } if (!this.noZoom) { this._zoomCamera(); } if (!this.noPan) { this._panCamera(); } this.object.position.addVectors(this.target, this._eye); if (this.object.isPerspectiveCamera) { this._checkDistances(); this.object.lookAt(this.target); if (this._lastPosition.distanceToSquared(this.object.position) > _EPS) { this.dispatchEvent(_changeEvent); this._lastPosition.copy(this.object.position); } } else if (this.object.isOrthographicCamera) { this.object.lookAt(this.target); if (this._lastPosition.distanceToSquared(this.object.position) > _EPS || this._lastZoom !== this.object.zoom) { this.dispatchEvent(_changeEvent); this._lastPosition.copy(this.object.position); this._lastZoom = this.object.zoom; } } else { console.warn("THREE.TrackballControls: Unsupported camera type."); } } reset() { this.state = _STATE.NONE; this.keyState = _STATE.NONE; this.target.copy(this._target0); this.object.position.copy(this._position0); this.object.up.copy(this._up0); this.object.zoom = this._zoom0; this.object.updateProjectionMatrix(); this._eye.subVectors(this.object.position, this.target); this.object.lookAt(this.target); this.dispatchEvent(_changeEvent); this._lastPosition.copy(this.object.position); this._lastZoom = this.object.zoom; } _panCamera() { _mouseChange.copy(this._panEnd).sub(this._panStart); if (_mouseChange.lengthSq()) { if (this.object.isOrthographicCamera) { const scale_x = (this.object.right - this.object.left) / this.object.zoom / this.domElement.clientWidth; const scale_y = (this.object.top - this.object.bottom) / this.object.zoom / this.domElement.clientWidth; _mouseChange.x *= scale_x; _mouseChange.y *= scale_y; } _mouseChange.multiplyScalar(this._eye.length() * this.panSpeed); _pan.copy(this._eye).cross(this.object.up).setLength(_mouseChange.x); _pan.add(_objectUp.copy(this.object.up).setLength(_mouseChange.y)); this.object.position.add(_pan); this.target.add(_pan); if (this.staticMoving) { this._panStart.copy(this._panEnd); } else { this._panStart.add(_mouseChange.subVectors(this._panEnd, this._panStart).multiplyScalar(this.dynamicDampingFactor)); } } } _rotateCamera() { _moveDirection.set(this._moveCurr.x - this._movePrev.x, this._moveCurr.y - this._movePrev.y, 0); let angle = _moveDirection.length(); if (angle) { this._eye.copy(this.object.position).sub(this.target); _eyeDirection.copy(this._eye).normalize(); _objectUpDirection.copy(this.object.up).normalize(); _objectSidewaysDirection.crossVectors(_objectUpDirection, _eyeDirection).normalize(); _objectUpDirection.setLength(this._moveCurr.y - this._movePrev.y); _objectSidewaysDirection.setLength(this._moveCurr.x - this._movePrev.x); _moveDirection.copy(_objectUpDirection.add(_objectSidewaysDirection)); _axis.crossVectors(_moveDirection, this._eye).normalize(); angle *= this.rotateSpeed; _quaternion.setFromAxisAngle(_axis, angle); this._eye.applyQuaternion(_quaternion); this.object.up.applyQuaternion(_quaternion); this._lastAxis.copy(_axis); this._lastAngle = angle; } else if (!this.staticMoving && this._lastAngle) { this._lastAngle *= Math.sqrt(1 - this.dynamicDampingFactor); this._eye.copy(this.object.position).sub(this.target); _quaternion.setFromAxisAngle(this._lastAxis, this._lastAngle); this._eye.applyQuaternion(_quaternion); this.object.up.applyQuaternion(_quaternion); } this._movePrev.copy(this._moveCurr); } _zoomCamera() { let factor; if (this.state === _STATE.TOUCH_ZOOM_PAN) { factor = this._touchZoomDistanceStart / this._touchZoomDistanceEnd; this._touchZoomDistanceStart = this._touchZoomDistanceEnd; if (this.object.isPerspectiveCamera) { this._eye.multiplyScalar(factor); } else if (this.object.isOrthographicCamera) { this.object.zoom = MathUtils.clamp(this.object.zoom / factor, this.minZoom, this.maxZoom); if (this._lastZoom !== this.object.zoom) { this.object.updateProjectionMatrix(); } } else { console.warn("THREE.TrackballControls: Unsupported camera type"); } } else { factor = 1 + (this._zoomEnd.y - this._zoomStart.y) * this.zoomSpeed; if (factor !== 1 && factor > 0) { if (this.object.isPerspectiveCamera) { this._eye.multiplyScalar(factor); } else if (this.object.isOrthographicCamera) { this.object.zoom = MathUtils.clamp(this.object.zoom / factor, this.minZoom, this.maxZoom); if (this._lastZoom !== this.object.zoom) { this.object.updateProjectionMatrix(); } } else { console.warn("THREE.TrackballControls: Unsupported camera type"); } } if (this.staticMoving) { this._zoomStart.copy(this._zoomEnd); } else { this._zoomStart.y += (this._zoomEnd.y - this._zoomStart.y) * this.dynamicDampingFactor; } } } _getMouseOnScreen(pageX, pageY) { _v2.set( (pageX - this.screen.left) / this.screen.width, (pageY - this.screen.top) / this.screen.height ); return _v2; } _getMouseOnCircle(pageX, pageY) { _v2.set( (pageX - this.screen.width * 0.5 - this.screen.left) / (this.screen.width * 0.5), (this.screen.height + 2 * (this.screen.top - pageY)) / this.screen.width // screen.width intentional ); return _v2; } _addPointer(event) { this._pointers.push(event); } _removePointer(event) { delete this._pointerPositions[event.pointerId]; for (let i = 0; i < this._pointers.length; i++) { if (this._pointers[i].pointerId == event.pointerId) { this._pointers.splice(i, 1); return; } } } _trackPointer(event) { let position = this._pointerPositions[event.pointerId]; if (position === void 0) { position = new Vector2(); this._pointerPositions[event.pointerId] = position; } position.set(event.pageX, event.pageY); } _getSecondPointerPosition(event) { const pointer = event.pointerId === this._pointers[0].pointerId ? this._pointers[1] : this._pointers[0]; return this._pointerPositions[pointer.pointerId]; } _checkDistances() { if (!this.noZoom || !this.noPan) { if (this._eye.lengthSq() > this.maxDistance * this.maxDistance) { this.object.position.addVectors(this.target, this._eye.setLength(this.maxDistance)); this._zoomStart.copy(this._zoomEnd); } if (this._eye.lengthSq() < this.minDistance * this.minDistance) { this.object.position.addVectors(this.target, this._eye.setLength(this.minDistance)); this._zoomStart.copy(this._zoomEnd); } } } }; function onPointerDown2(event) { if (this.enabled === false) return; if (this._pointers.length === 0) { this.domElement.setPointerCapture(event.pointerId); this.domElement.addEventListener("pointermove", this._onPointerMove); this.domElement.addEventListener("pointerup", this._onPointerUp); } this._addPointer(event); if (event.pointerType === "touch") { this._onTouchStart(event); } else { this._onMouseDown(event); } } function onPointerMove2(event) { if (this.enabled === false) return; if (event.pointerType === "touch") { this._onTouchMove(event); } else { this._onMouseMove(event); } } function onPointerUp(event) { if (this.enabled === false) return; if (event.pointerType === "touch") { this._onTouchEnd(event); } else { this._onMouseUp(); } this._removePointer(event); if (this._pointers.length === 0) { this.domElement.releasePointerCapture(event.pointerId); this.domElement.removeEventListener("pointermove", this._onPointerMove); this.domElement.removeEventListener("pointerup", this._onPointerUp); } } function onPointerCancel2(event) { this._removePointer(event); } function onKeyUp() { if (this.enabled === false) return; this.keyState = _STATE.NONE; window.addEventListener("keydown", this._onKeyDown); } function onKeyDown(event) { if (this.enabled === false) return; window.removeEventListener("keydown", this._onKeyDown); if (this.keyState !== _STATE.NONE) { return; } else if (event.code === this.keys[_STATE.ROTATE] && !this.noRotate) { this.keyState = _STATE.ROTATE; } else if (event.code === this.keys[_STATE.ZOOM] && !this.noZoom) { this.keyState = _STATE.ZOOM; } else if (event.code === this.keys[_STATE.PAN] && !this.noPan) { this.keyState = _STATE.PAN; } } function onMouseDown(event) { let mouseAction; switch (event.button) { case 0: mouseAction = this.mouseButtons.LEFT; break; case 1: mouseAction = this.mouseButtons.MIDDLE; break; case 2: mouseAction = this.mouseButtons.RIGHT; break; default: mouseAction = -1; } switch (mouseAction) { case MOUSE.DOLLY: this.state = _STATE.ZOOM; break; case MOUSE.ROTATE: this.state = _STATE.ROTATE; break; case MOUSE.PAN: this.state = _STATE.PAN; break; default: this.state = _STATE.NONE; } const state = this.keyState !== _STATE.NONE ? this.keyState : this.state; if (state === _STATE.ROTATE && !this.noRotate) { this._moveCurr.copy(this._getMouseOnCircle(event.pageX, event.pageY)); this._movePrev.copy(this._moveCurr); } else if (state === _STATE.ZOOM && !this.noZoom) { this._zoomStart.copy(this._getMouseOnScreen(event.pageX, event.pageY)); this._zoomEnd.copy(this._zoomStart); } else if (state === _STATE.PAN && !this.noPan) { this._panStart.copy(this._getMouseOnScreen(event.pageX, event.pageY)); this._panEnd.copy(this._panStart); } this.dispatchEvent(_startEvent); } function onMouseMove(event) { const state = this.keyState !== _STATE.NONE ? this.keyState : this.state; if (state === _STATE.ROTATE && !this.noRotate) { this._movePrev.copy(this._moveCurr); this._moveCurr.copy(this._getMouseOnCircle(event.pageX, event.pageY)); } else if (state === _STATE.ZOOM && !this.noZoom) { this._zoomEnd.copy(this._getMouseOnScreen(event.pageX, event.pageY)); } else if (state === _STATE.PAN && !this.noPan) { this._panEnd.copy(this._getMouseOnScreen(event.pageX, event.pageY)); } } function onMouseUp() { this.state = _STATE.NONE; this.dispatchEvent(_endEvent); } function onMouseWheel(event) { if (this.enabled === false) return; if (this.noZoom === true) return; event.preventDefault(); switch (event.deltaMode) { case 2: this._zoomStart.y -= event.deltaY * 0.025; break; case 1: this._zoomStart.y -= event.deltaY * 0.01; break; default: this._zoomStart.y -= event.deltaY * 25e-5; break; } this.dispatchEvent(_startEvent); this.dispatchEvent(_endEvent); } function onContextMenu2(event) { if (this.enabled === false) return; event.preventDefault(); } function onTouchStart(event) { this._trackPointer(event); switch (this._pointers.length) { case 1: this.state = _STATE.TOUCH_ROTATE; this._moveCurr.copy(this._getMouseOnCircle(this._pointers[0].pageX, this._pointers[0].pageY)); this._movePrev.copy(this._moveCurr); break; default: this.state = _STATE.TOUCH_ZOOM_PAN; const dx = this._pointers[0].pageX - this._pointers[1].pageX; const dy = this._pointers[0].pageY - this._pointers[1].pageY; this._touchZoomDistanceEnd = this._touchZoomDistanceStart = Math.sqrt(dx * dx + dy * dy); const x2 = (this._pointers[0].pageX + this._pointers[1].pageX) / 2; const y2 = (this._pointers[0].pageY + this._pointers[1].pageY) / 2; this._panStart.copy(this._getMouseOnScreen(x2, y2)); this._panEnd.copy(this._panStart); break; } this.dispatchEvent(_startEvent); } function onTouchMove(event) { this._trackPointer(event); switch (this._pointers.length) { case 1: this._movePrev.copy(this._moveCurr); this._moveCurr.copy(this._getMouseOnCircle(event.pageX, event.pageY)); break; default: const position = this._getSecondPointerPosition(event); const dx = event.pageX - position.x; const dy = event.pageY - position.y; this._touchZoomDistanceEnd = Math.sqrt(dx * dx + dy * dy); const x2 = (event.pageX + position.x) / 2; const y2 = (event.pageY + position.y) / 2; this._panEnd.copy(this._getMouseOnScreen(x2, y2)); break; } } function onTouchEnd(event) { switch (this._pointers.length) { case 0: this.state = _STATE.NONE; break; case 1: this.state = _STATE.TOUCH_ROTATE; this._moveCurr.copy(this._getMouseOnCircle(event.pageX, event.pageY)); this._movePrev.copy(this._moveCurr); break; case 2: this.state = _STATE.TOUCH_ZOOM_PAN; for (let i = 0; i < this._pointers.length; i++) { if (this._pointers[i].pointerId !== event.pointerId) { const position = this._pointerPositions[this._pointers[i].pointerId]; this._moveCurr.copy(this._getMouseOnCircle(position.x, position.y)); this._movePrev.copy(this._moveCurr); break; } } break; } this.dispatchEvent(_endEvent); } // ../../node_modules/three/examples/jsm/controls/OrbitControls.js var _changeEvent2 = { type: "change" }; var _startEvent2 = { type: "start" }; var _endEvent2 = { type: "end" }; var _ray = new Ray(); var _plane3 = new Plane(); var _TILT_LIMIT = Math.cos(70 * MathUtils.DEG2RAD); var _v = new Vector3(); var _twoPI = 2 * Math.PI; var _STATE2 = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_PAN: 4, TOUCH_DOLLY_PAN: 5, TOUCH_DOLLY_ROTATE: 6 }; var _EPS2 = 1e-6; var OrbitControls = class extends Controls { constructor(object, domElement = null) { super(object, domElement); this.state = _STATE2.NONE; this.enabled = true; this.target = new Vector3(); this.cursor = new Vector3(); this.minDistance = 0; this.maxDistance = Infinity; this.minZoom = 0; this.maxZoom = Infinity; this.minTargetRadius = 0; this.maxTargetRadius = Infinity; this.minPolarAngle = 0; this.maxPolarAngle = Math.PI; this.minAzimuthAngle = -Infinity; this.maxAzimuthAngle = Infinity; this.enableDamping = false; this.dampingFactor = 0.05; this.enableZoom = true; this.zoomSpeed = 1; this.enableRotate = true; this.rotateSpeed = 1; this.enablePan = true; this.panSpeed = 1; this.screenSpacePanning = true; this.keyPanSpeed = 7; this.zoomToCursor = false; this.autoRotate = false; this.autoRotateSpeed = 2; this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" }; this.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN }; this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN }; this.target0 = this.target.clone(); this.position0 = this.object.position.clone(); this.zoom0 = this.object.zoom; this._domElementKeyEvents = null; this._lastPosition = new Vector3(); this._lastQuaternion = new Quaternion(); this._lastTargetPosition = new Vector3(); this._quat = new Quaternion().setFromUnitVectors(object.up, new Vector3(0, 1, 0)); this._quatInverse = this._quat.clone().invert(); this._spherical = new Spherical(); this._sphericalDelta = new Spherical(); this._scale = 1; this._panOffset = new Vector3(); this._rotateStart = new Vector2(); this._rotateEnd = new Vector2(); this._rotateDelta = new Vector2(); this._panStart = new Vector2(); this._panEnd = new Vector2(); this._panDelta = new Vector2(); this._dollyStart = new Vector2(); this._dollyEnd = new Vector2(); this._dollyDelta = new Vector2(); this._dollyDirection = new Vector3(); this._mouse = new Vector2(); this._performCursorZoom = false; this._pointers = []; this._pointerPositions = {}; this._controlActive = false; this._onPointerMove = onPointerMove3.bind(this); this._onPointerDown = onPointerDown3.bind(this); this._onPointerUp = onPointerUp2.bind(this); this._onContextMenu = onContextMenu3.bind(this); this._onMouseWheel = onMouseWheel2.bind(this); this._onKeyDown = onKeyDown2.bind(this); this._onTouchStart = onTouchStart2.bind(this); this._onTouchMove = onTouchMove2.bind(this); this._onMouseDown = onMouseDown2.bind(this); this._onMouseMove = onMouseMove2.bind(this); this._interceptControlDown = interceptControlDown.bind(this); this._interceptControlUp = interceptControlUp.bind(this); if (this.domElement !== null) { this.connect(); } this.update(); } connect() { this.domElement.addEventListener("pointerdown", this._onPointerDown); this.domElement.addEventListener("pointercancel", this._onPointerUp); this.domElement.addEventListener("contextmenu", this._onContextMenu); this.domElement.addEventListener("wheel", this._onMouseWheel, { passive: false }); const document2 = this.domElement.getRootNode(); document2.addEventListener("keydown", this._interceptControlDown, { passive: true, capture: true }); this.domElement.style.touchAction = "none"; } disconnect() { this.domElement.removeEventListener("pointerdown", this._onPointerDown); this.domElement.removeEventListener("pointermove", this._onPointerMove); this.domElement.removeEventListener("pointerup", this._onPointerUp); this.domElement.removeEventListener("pointercancel", this._onPointerUp); this.domElement.removeEventListener("wheel", this._onMouseWheel); this.domElement.removeEventListener("contextmenu", this._onContextMenu); this.stopListenToKeyEvents(); const document2 = this.domElement.getRootNode(); document2.removeEventListener("keydown", this._interceptControlDown, { capture: true }); this.domElement.style.touchAction = "auto"; } dispose() { this.disconnect(); } getPolarAngle() { return this._spherical.phi; } getAzimuthalAngle() { return this._spherical.theta; } getDistance() { return this.object.position.distanceTo(this.target); } listenToKeyEvents(domElement) { domElement.addEventListener("keydown", this._onKeyDown); this._domElementKeyEvents = domElement; } stopListenToKeyEvents() { if (this._domElementKeyEvents !== null) { this._domElementKeyEvents.removeEventListener("keydown", this._onKeyDown); this._domElementKeyEvents = null; } } saveState() { this.target0.copy(this.target); this.position0.copy(this.object.position); this.zoom0 = this.object.zoom; } reset() { this.target.copy(this.target0); this.object.position.copy(this.position0); this.object.zoom = this.zoom0; this.object.updateProjectionMatrix(); this.dispatchEvent(_changeEvent2); this.update(); this.state = _STATE2.NONE; } update(deltaTime = null) { const position = this.object.position; _v.copy(position).sub(this.target); _v.applyQuaternion(this._quat); this._spherical.setFromVector3(_v); if (this.autoRotate && this.state === _STATE2.NONE) { this._rotateLeft(this._getAutoRotationAngle(deltaTime)); } if (this.enableDamping) { this._spherical.theta += this._sphericalDelta.theta * this.dampingFactor; this._spherical.phi += this._sphericalDelta.phi * this.dampingFactor; } else { this._spherical.theta += this._sphericalDelta.theta; this._spherical.phi += this._sphericalDelta.phi; } let min2 = this.minAzimuthAngle; let max2 = this.maxAzimuthAngle; if (isFinite(min2) && isFinite(max2)) { if (min2 < -Math.PI) min2 += _twoPI; else if (min2 > Math.PI) min2 -= _twoPI; if (max2 < -Math.PI) max2 += _twoPI; else if (max2 > Math.PI) max2 -= _twoPI; if (min2 <= max2) { this._spherical.theta = Math.max(min2, Math.min(max2, this._spherical.theta)); } else { this._spherical.theta = this._spherical.theta > (min2 + max2) / 2 ? Math.max(min2, this._spherical.theta) : Math.min(max2, this._spherical.theta); } } this._spherical.phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this._spherical.phi)); this._spherical.makeSafe(); if (this.enableDamping === true) { this.target.addScaledVector(this._panOffset, this.dampingFactor); } else { this.target.add(this._panOffset); } this.target.sub(this.cursor); this.target.clampLength(this.minTargetRadius, this.maxTargetRadius); this.target.add(this.cursor); let zoomChanged = false; if (this.zoomToCursor && this._performCursorZoom || this.object.isOrthographicCamera) { this._spherical.radius = this._clampDistance(this._spherical.radius); } else { const prevRadius = this._spherical.radius; this._spherical.radius = this._clampDistance(this._spherical.radius * this._scale); zoomChanged = prevRadius != this._spherical.radius; } _v.setFromSpherical(this._spherical); _v.applyQuaternion(this._quatInverse); position.copy(this.target).add(_v); this.object.lookAt(this.target); if (this.enableDamping === true) { this._sphericalDelta.theta *= 1 - this.dampingFactor; this._sphericalDelta.phi *= 1 - this.dampingFactor; this._panOffset.multiplyScalar(1 - this.dampingFactor); } else { this._sphericalDelta.set(0, 0, 0); this._panOffset.set(0, 0, 0); } if (this.zoomToCursor && this._performCursorZoom) { let newRadius = null; if (this.object.isPerspectiveCamera) { const prevRadius = _v.length(); newRadius = this._clampDistance(prevRadius * this._scale); const radiusDelta = prevRadius - newRadius; this.object.position.addScaledVector(this._dollyDirection, radiusDelta); this.object.updateMatrixWorld(); zoomChanged = !!radiusDelta; } else if (this.object.isOrthographicCamera) { const mouseBefore = new Vector3(this._mouse.x, this._mouse.y, 0); mouseBefore.unproject(this.object); const prevZoom = this.object.zoom; this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / this._scale)); this.object.updateProjectionMatrix(); zoomChanged = prevZoom !== this.object.zoom; const mouseAfter = new Vector3(this._mouse.x, this._mouse.y, 0); mouseAfter.unproject(this.object); this.object.position.sub(mouseAfter).add(mouseBefore); this.object.updateMatrixWorld(); newRadius = _v.length(); } else { console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."); this.zoomToCursor = false; } if (newRadius !== null) { if (this.screenSpacePanning) { this.target.set(0, 0, -1).transformDirection(this.object.matrix).multiplyScalar(newRadius).add(this.object.position); } else { _ray.origin.copy(this.object.position); _ray.direction.set(0, 0, -1).transformDirection(this.object.matrix); if (Math.abs(this.object.up.dot(_ray.direction)) < _TILT_LIMIT) { this.object.lookAt(this.target); } else { _plane3.setFromNormalAndCoplanarPoint(this.object.up, this.target); _ray.intersectPlane(_plane3, this.target); } } } } else if (this.object.isOrthographicCamera) { const prevZoom = this.object.zoom; this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / this._scale)); if (prevZoom !== this.object.zoom) { this.object.updateProjectionMatrix(); zoomChanged = true; } } this._scale = 1; this._performCursorZoom = false; if (zoomChanged || this._lastPosition.distanceToSquared(this.object.position) > _EPS2 || 8 * (1 - this._lastQuaternion.dot(this.object.quaternion)) > _EPS2 || this._lastTargetPosition.distanceToSquared(this.target) > _EPS2) { this.dispatchEvent(_changeEvent2); this._lastPosition.copy(this.object.position); this._lastQuaternion.copy(this.object.quaternion); this._lastTargetPosition.copy(this.target); return true; } return false; } _getAutoRotationAngle(deltaTime) { if (deltaTime !== null) { return _twoPI / 60 * this.autoRotateSpeed * deltaTime; } else { return _twoPI / 60 / 60 * this.autoRotateSpeed; } } _getZoomScale(delta) { const normalizedDelta = Math.abs(delta * 0.01); return Math.pow(0.95, this.zoomSpeed * normalizedDelta); } _rotateLeft(angle) { this._sphericalDelta.theta -= angle; } _rotateUp(angle) { this._sphericalDelta.phi -= angle; } _panLeft(distance2, objectMatrix) { _v.setFromMatrixColumn(objectMatrix, 0); _v.multiplyScalar(-distance2); this._panOffset.add(_v); } _panUp(distance2, objectMatrix) { if (this.screenSpacePanning === true) { _v.setFromMatrixColumn(objectMatrix, 1); } else { _v.setFromMatrixColumn(objectMatrix, 0); _v.crossVectors(this.object.up, _v); } _v.multiplyScalar(distance2); this._panOffset.add(_v); } // deltaX and deltaY are in pixels; right and down are positive _pan(deltaX, deltaY) { const element2 = this.domElement; if (this.object.isPerspectiveCamera) { const position = this.object.position; _v.copy(position).sub(this.target); let targetDistance = _v.length(); targetDistance *= Math.tan(this.object.fov / 2 * Math.PI / 180); this._panLeft(2 * deltaX * targetDistance / element2.clientHeight, this.object.matrix); this._panUp(2 * deltaY * targetDistance / element2.clientHeight, this.object.matrix); } else if (this.object.isOrthographicCamera) { this._panLeft(deltaX * (this.object.right - this.object.left) / this.object.zoom / element2.clientWidth, this.object.matrix); this._panUp(deltaY * (this.object.top - this.object.bottom) / this.object.zoom / element2.clientHeight, this.object.matrix); } else { console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."); this.enablePan = false; } } _dollyOut(dollyScale) { if (this.object.isPerspectiveCamera || this.object.isOrthographicCamera) { this._scale /= dollyScale; } else { console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."); this.enableZoom = false; } } _dollyIn(dollyScale) { if (this.object.isPerspectiveCamera || this.object.isOrthographicCamera) { this._scale *= dollyScale; } else { console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."); this.enableZoom = false; } } _updateZoomParameters(x2, y2) { if (!this.zoomToCursor) { return; } this._performCursorZoom = true; const rect = this.domElement.getBoundingClientRect(); const dx = x2 - rect.left; const dy = y2 - rect.top; const w = rect.width; const h = rect.height; this._mouse.x = dx / w * 2 - 1; this._mouse.y = -(dy / h) * 2 + 1; this._dollyDirection.set(this._mouse.x, this._mouse.y, 1).unproject(this.object).sub(this.object.position).normalize(); } _clampDistance(dist) { return Math.max(this.minDistance, Math.min(this.maxDistance, dist)); } // // event callbacks - update the object state // _handleMouseDownRotate(event) { this._rotateStart.set(event.clientX, event.clientY); } _handleMouseDownDolly(event) { this._updateZoomParameters(event.clientX, event.clientX); this._dollyStart.set(event.clientX, event.clientY); } _handleMouseDownPan(event) { this._panStart.set(event.clientX, event.clientY); } _handleMouseMoveRotate(event) { this._rotateEnd.set(event.clientX, event.clientY); this._rotateDelta.subVectors(this._rotateEnd, this._rotateStart).multiplyScalar(this.rotateSpeed); const element2 = this.domElement; this._rotateLeft(_twoPI * this._rotateDelta.x / element2.clientHeight); this._rotateUp(_twoPI * this._rotateDelta.y / element2.clientHeight); this._rotateStart.copy(this._rotateEnd); this.update(); } _handleMouseMoveDolly(event) { this._dollyEnd.set(event.clientX, event.clientY); this._dollyDelta.subVectors(this._dollyEnd, this._dollyStart); if (this._dollyDelta.y > 0) { this._dollyOut(this._getZoomScale(this._dollyDelta.y)); } else if (this._dollyDelta.y < 0) { this._dollyIn(this._getZoomScale(this._dollyDelta.y)); } this._dollyStart.copy(this._dollyEnd); this.update(); } _handleMouseMovePan(event) { this._panEnd.set(event.clientX, event.clientY); this._panDelta.subVectors(this._panEnd, this._panStart).multiplyScalar(this.panSpeed); this._pan(this._panDelta.x, this._panDelta.y); this._panStart.copy(this._panEnd); this.update(); } _handleMouseWheel(event) { this._updateZoomParameters(event.clientX, event.clientY); if (event.deltaY < 0) { this._dollyIn(this._getZoomScale(event.deltaY)); } else if (event.deltaY > 0) { this._dollyOut(this._getZoomScale(event.deltaY)); } this.update(); } _handleKeyDown(event) { let needsUpdate = false; switch (event.code) { case this.keys.UP: if (event.ctrlKey || event.metaKey || event.shiftKey) { this._rotateUp(_twoPI * this.rotateSpeed / this.domElement.clientHeight); } else { this._pan(0, this.keyPanSpeed); } needsUpdate = true; break; case this.keys.BOTTOM: if (event.ctrlKey || event.metaKey || event.shiftKey) { this._rotateUp(-_twoPI * this.rotateSpeed / this.domElement.clientHeight); } else { this._pan(0, -this.keyPanSpeed); } needsUpdate = true; break; case this.keys.LEFT: if (event.ctrlKey || event.metaKey || event.shiftKey) { this._rotateLeft(_twoPI * this.rotateSpeed / this.domElement.clientHeight); } else { this._pan(this.keyPanSpeed, 0); } needsUpdate = true; break; case this.keys.RIGHT: if (event.ctrlKey || event.metaKey || event.shiftKey) { this._rotateLeft(-_twoPI * this.rotateSpeed / this.domElement.clientHeight); } else { this._pan(-this.keyPanSpeed, 0); } needsUpdate = true; break; } if (needsUpdate) { event.preventDefault(); this.update(); } } _handleTouchStartRotate(event) { if (this._pointers.length === 1) { this._rotateStart.set(event.pageX, event.pageY); } else { const position = this._getSecondPointerPosition(event); const x2 = 0.5 * (event.pageX + position.x); const y2 = 0.5 * (event.pageY + position.y); this._rotateStart.set(x2, y2); } } _handleTouchStartPan(event) { if (this._pointers.length === 1) { this._panStart.set(event.pageX, event.pageY); } else { const position = this._getSecondPointerPosition(event); const x2 = 0.5 * (event.pageX + position.x); const y2 = 0.5 * (event.pageY + position.y); this._panStart.set(x2, y2); } } _handleTouchStartDolly(event) { const position = this._getSecondPointerPosition(event); const dx = event.pageX - position.x; const dy = event.pageY - position.y; const distance2 = Math.sqrt(dx * dx + dy * dy); this._dollyStart.set(0, distance2); } _handleTouchStartDollyPan(event) { if (this.enableZoom) this._handleTouchStartDolly(event); if (this.enablePan) this._handleTouchStartPan(event); } _handleTouchStartDollyRotate(event) { if (this.enableZoom) this._handleTouchStartDolly(event); if (this.enableRotate) this._handleTouchStartRotate(event); } _handleTouchMoveRotate(event) { if (this._pointers.length == 1) { this._rotateEnd.set(event.pageX, event.pageY); } else { const position = this._getSecondPointerPosition(event); const x2 = 0.5 * (event.pageX + position.x); const y2 = 0.5 * (event.pageY + position.y); this._rotateEnd.set(x2, y2); } this._rotateDelta.subVectors(this._rotateEnd, this._rotateStart).multiplyScalar(this.rotateSpeed); const element2 = this.domElement; this._rotateLeft(_twoPI * this._rotateDelta.x / element2.clientHeight); this._rotateUp(_twoPI * this._rotateDelta.y / element2.clientHeight); this._rotateStart.copy(this._rotateEnd); } _handleTouchMovePan(event) { if (this._pointers.length === 1) { this._panEnd.set(event.pageX, event.pageY); } else { const position = this._getSecondPointerPosition(event); const x2 = 0.5 * (event.pageX + position.x); const y2 = 0.5 * (event.pageY + position.y); this._panEnd.set(x2, y2); } this._panDelta.subVectors(this._panEnd, this._panStart).multiplyScalar(this.panSpeed); this._pan(this._panDelta.x, this._panDelta.y); this._panStart.copy(this._panEnd); } _handleTouchMoveDolly(event) { const position = this._getSecondPointerPosition(event); const dx = event.pageX - position.x; const dy = event.pageY - position.y; const distance2 = Math.sqrt(dx * dx + dy * dy); this._dollyEnd.set(0, distance2); this._dollyDelta.set(0, Math.pow(this._dollyEnd.y / this._dollyStart.y, this.zoomSpeed)); this._dollyOut(this._dollyDelta.y); this._dollyStart.copy(this._dollyEnd); const centerX = (event.pageX + position.x) * 0.5; const centerY = (event.pageY + position.y) * 0.5; this._updateZoomParameters(centerX, centerY); } _handleTouchMoveDollyPan(event) { if (this.enableZoom) this._handleTouchMoveDolly(event); if (this.enablePan) this._handleTouchMovePan(event); } _handleTouchMoveDollyRotate(event) { if (this.enableZoom) this._handleTouchMoveDolly(event); if (this.enableRotate) this._handleTouchMoveRotate(event); } // pointers _addPointer(event) { this._pointers.push(event.pointerId); } _removePointer(event) { delete this._pointerPositions[event.pointerId]; for (let i = 0; i < this._pointers.length; i++) { if (this._pointers[i] == event.pointerId) { this._pointers.splice(i, 1); return; } } } _isTrackingPointer(event) { for (let i = 0; i < this._pointers.length; i++) { if (this._pointers[i] == event.pointerId) return true; } return false; } _trackPointer(event) { let position = this._pointerPositions[event.pointerId]; if (position === void 0) { position = new Vector2(); this._pointerPositions[event.pointerId] = position; } position.set(event.pageX, event.pageY); } _getSecondPointerPosition(event) { const pointerId = event.pointerId === this._pointers[0] ? this._pointers[1] : this._pointers[0]; return this._pointerPositions[pointerId]; } // _customWheelEvent(event) { const mode = event.deltaMode; const newEvent = { clientX: event.clientX, clientY: event.clientY, deltaY: event.deltaY }; switch (mode) { case 1: newEvent.deltaY *= 16; break; case 2: newEvent.deltaY *= 100; break; } if (event.ctrlKey && !this._controlActive) { newEvent.deltaY *= 10; } return newEvent; } }; function onPointerDown3(event) { if (this.enabled === false) return; if (this._pointers.length === 0) { this.domElement.setPointerCapture(event.pointerId); this.domElement.addEventListener("pointermove", this._onPointerMove); this.domElement.addEventListener("pointerup", this._onPointerUp); } if (this._isTrackingPointer(event)) return; this._addPointer(event); if (event.pointerType === "touch") { this._onTouchStart(event); } else { this._onMouseDown(event); } } function onPointerMove3(event) { if (this.enabled === false) return; if (event.pointerType === "touch") { this._onTouchMove(event); } else { this._onMouseMove(event); } } function onPointerUp2(event) { this._removePointer(event); switch (this._pointers.length) { case 0: this.domElement.releasePointerCapture(event.pointerId); this.domElement.removeEventListener("pointermove", this._onPointerMove); this.domElement.removeEventListener("pointerup", this._onPointerUp); this.dispatchEvent(_endEvent2); this.state = _STATE2.NONE; break; case 1: const pointerId = this._pointers[0]; const position = this._pointerPositions[pointerId]; this._onTouchStart({ pointerId, pageX: position.x, pageY: position.y }); break; } } function onMouseDown2(event) { let mouseAction; switch (event.button) { case 0: mouseAction = this.mouseButtons.LEFT; break; case 1: mouseAction = this.mouseButtons.MIDDLE; break; case 2: mouseAction = this.mouseButtons.RIGHT; break; default: mouseAction = -1; } switch (mouseAction) { case MOUSE.DOLLY: if (this.enableZoom === false) return; this._handleMouseDownDolly(event); this.state = _STATE2.DOLLY; break; case MOUSE.ROTATE: if (event.ctrlKey || event.metaKey || event.shiftKey) { if (this.enablePan === false) return; this._handleMouseDownPan(event); this.state = _STATE2.PAN; } else { if (this.enableRotate === false) return; this._handleMouseDownRotate(event); this.state = _STATE2.ROTATE; } break; case MOUSE.PAN: if (event.ctrlKey || event.metaKey || event.shiftKey) { if (this.enableRotate === false) return; this._handleMouseDownRotate(event); this.state = _STATE2.ROTATE; } else { if (this.enablePan === false) return; this._handleMouseDownPan(event); this.state = _STATE2.PAN; } break; default: this.state = _STATE2.NONE; } if (this.state !== _STATE2.NONE) { this.dispatchEvent(_startEvent2); } } function onMouseMove2(event) { switch (this.state) { case _STATE2.ROTATE: if (this.enableRotate === false) return; this._handleMouseMoveRotate(event); break; case _STATE2.DOLLY: if (this.enableZoom === false) return; this._handleMouseMoveDolly(event); break; case _STATE2.PAN: if (this.enablePan === false) return; this._handleMouseMovePan(event); break; } } function onMouseWheel2(event) { if (this.enabled === false || this.enableZoom === false || this.state !== _STATE2.NONE) return; event.preventDefault(); this.dispatchEvent(_startEvent2); this._handleMouseWheel(this._customWheelEvent(event)); this.dispatchEvent(_endEvent2); } function onKeyDown2(event) { if (this.enabled === false || this.enablePan === false) return; this._handleKeyDown(event); } function onTouchStart2(event) { this._trackPointer(event); switch (this._pointers.length) { case 1: switch (this.touches.ONE) { case TOUCH.ROTATE: if (this.enableRotate === false) return; this._handleTouchStartRotate(event); this.state = _STATE2.TOUCH_ROTATE; break; case TOUCH.PAN: if (this.enablePan === false) return; this._handleTouchStartPan(event); this.state = _STATE2.TOUCH_PAN; break; default: this.state = _STATE2.NONE; } break; case 2: switch (this.touches.TWO) { case TOUCH.DOLLY_PAN: if (this.enableZoom === false && this.enablePan === false) return; this._handleTouchStartDollyPan(event); this.state = _STATE2.TOUCH_DOLLY_PAN; break; case TOUCH.DOLLY_ROTATE: if (this.enableZoom === false && this.enableRotate === false) return; this._handleTouchStartDollyRotate(event); this.state = _STATE2.TOUCH_DOLLY_ROTATE; break; default: this.state = _STATE2.NONE; } break; default: this.state = _STATE2.NONE; } if (this.state !== _STATE2.NONE) { this.dispatchEvent(_startEvent2); } } function onTouchMove2(event) { this._trackPointer(event); switch (this.state) { case _STATE2.TOUCH_ROTATE: if (this.enableRotate === false) return; this._handleTouchMoveRotate(event); this.update(); break; case _STATE2.TOUCH_PAN: if (this.enablePan === false) return; this._handleTouchMovePan(event); this.update(); break; case _STATE2.TOUCH_DOLLY_PAN: if (this.enableZoom === false && this.enablePan === false) return; this._handleTouchMoveDollyPan(event); this.update(); break; case _STATE2.TOUCH_DOLLY_ROTATE: if (this.enableZoom === false && this.enableRotate === false) return; this._handleTouchMoveDollyRotate(event); this.update(); break; default: this.state = _STATE2.NONE; } } function onContextMenu3(event) { if (this.enabled === false) return; event.preventDefault(); } function interceptControlDown(event) { if (event.key === "Control") { this._controlActive = true; const document2 = this.domElement.getRootNode(); document2.addEventListener("keyup", this._interceptControlUp, { passive: true, capture: true }); } } function interceptControlUp(event) { if (event.key === "Control") { this._controlActive = false; const document2 = this.domElement.getRootNode(); document2.removeEventListener("keyup", this._interceptControlUp, { passive: true, capture: true }); } } // ../../node_modules/three/examples/jsm/controls/FlyControls.js var _changeEvent3 = { type: "change" }; var _EPS3 = 1e-6; var _tmpQuaternion = new Quaternion(); var FlyControls = class extends Controls { constructor(object, domElement = null) { super(object, domElement); this.movementSpeed = 1; this.rollSpeed = 5e-3; this.dragToLook = false; this.autoForward = false; this._moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 }; this._moveVector = new Vector3(0, 0, 0); this._rotationVector = new Vector3(0, 0, 0); this._lastQuaternion = new Quaternion(); this._lastPosition = new Vector3(); this._status = 0; this._onKeyDown = onKeyDown3.bind(this); this._onKeyUp = onKeyUp2.bind(this); this._onPointerMove = onPointerMove4.bind(this); this._onPointerDown = onPointerDown4.bind(this); this._onPointerUp = onPointerUp3.bind(this); this._onPointerCancel = onPointerCancel3.bind(this); this._onContextMenu = onContextMenu4.bind(this); if (domElement !== null) { this.connect(); } } connect() { window.addEventListener("keydown", this._onKeyDown); window.addEventListener("keyup", this._onKeyUp); this.domElement.addEventListener("pointermove", this._onPointerMove); this.domElement.addEventListener("pointerdown", this._onPointerDown); this.domElement.addEventListener("pointerup", this._onPointerUp); this.domElement.addEventListener("pointercancel", this._onPointerCancel); this.domElement.addEventListener("contextmenu", this._onContextMenu); } disconnect() { window.removeEventListener("keydown", this._onKeyDown); window.removeEventListener("keyup", this._onKeyUp); this.domElement.removeEventListener("pointermove", this._onPointerMove); this.domElement.removeEventListener("pointerdown", this._onPointerDown); this.domElement.removeEventListener("pointerup", this._onPointerUp); this.domElement.removeEventListener("pointercancel", this._onPointerCancel); this.domElement.removeEventListener("contextmenu", this._onContextMenu); } dispose() { this.disconnect(); } update(delta) { if (this.enabled === false) return; const object = this.object; const moveMult = delta * this.movementSpeed; const rotMult = delta * this.rollSpeed; object.translateX(this._moveVector.x * moveMult); object.translateY(this._moveVector.y * moveMult); object.translateZ(this._moveVector.z * moveMult); _tmpQuaternion.set(this._rotationVector.x * rotMult, this._rotationVector.y * rotMult, this._rotationVector.z * rotMult, 1).normalize(); object.quaternion.multiply(_tmpQuaternion); if (this._lastPosition.distanceToSquared(object.position) > _EPS3 || 8 * (1 - this._lastQuaternion.dot(object.quaternion)) > _EPS3) { this.dispatchEvent(_changeEvent3); this._lastQuaternion.copy(object.quaternion); this._lastPosition.copy(object.position); } } // private _updateMovementVector() { const forward = this._moveState.forward || this.autoForward && !this._moveState.back ? 1 : 0; this._moveVector.x = -this._moveState.left + this._moveState.right; this._moveVector.y = -this._moveState.down + this._moveState.up; this._moveVector.z = -forward + this._moveState.back; } _updateRotationVector() { this._rotationVector.x = -this._moveState.pitchDown + this._moveState.pitchUp; this._rotationVector.y = -this._moveState.yawRight + this._moveState.yawLeft; this._rotationVector.z = -this._moveState.rollRight + this._moveState.rollLeft; } _getContainerDimensions() { if (this.domElement != document) { return { size: [this.domElement.offsetWidth, this.domElement.offsetHeight], offset: [this.domElement.offsetLeft, this.domElement.offsetTop] }; } else { return { size: [window.innerWidth, window.innerHeight], offset: [0, 0] }; } } }; function onKeyDown3(event) { if (event.altKey || this.enabled === false) { return; } switch (event.code) { case "ShiftLeft": case "ShiftRight": this.movementSpeedMultiplier = 0.1; break; case "KeyW": this._moveState.forward = 1; break; case "KeyS": this._moveState.back = 1; break; case "KeyA": this._moveState.left = 1; break; case "KeyD": this._moveState.right = 1; break; case "KeyR": this._moveState.up = 1; break; case "KeyF": this._moveState.down = 1; break; case "ArrowUp": this._moveState.pitchUp = 1; break; case "ArrowDown": this._moveState.pitchDown = 1; break; case "ArrowLeft": this._moveState.yawLeft = 1; break; case "ArrowRight": this._moveState.yawRight = 1; break; case "KeyQ": this._moveState.rollLeft = 1; break; case "KeyE": this._moveState.rollRight = 1; break; } this._updateMovementVector(); this._updateRotationVector(); } function onKeyUp2(event) { if (this.enabled === false) return; switch (event.code) { case "ShiftLeft": case "ShiftRight": this.movementSpeedMultiplier = 1; break; case "KeyW": this._moveState.forward = 0; break; case "KeyS": this._moveState.back = 0; break; case "KeyA": this._moveState.left = 0; break; case "KeyD": this._moveState.right = 0; break; case "KeyR": this._moveState.up = 0; break; case "KeyF": this._moveState.down = 0; break; case "ArrowUp": this._moveState.pitchUp = 0; break; case "ArrowDown": this._moveState.pitchDown = 0; break; case "ArrowLeft": this._moveState.yawLeft = 0; break; case "ArrowRight": this._moveState.yawRight = 0; break; case "KeyQ": this._moveState.rollLeft = 0; break; case "KeyE": this._moveState.rollRight = 0; break; } this._updateMovementVector(); this._updateRotationVector(); } function onPointerDown4(event) { if (this.enabled === false) return; if (this.dragToLook) { this._status++; } else { switch (event.button) { case 0: this._moveState.forward = 1; break; case 2: this._moveState.back = 1; break; } this._updateMovementVector(); } } function onPointerMove4(event) { if (this.enabled === false) return; if (!this.dragToLook || this._status > 0) { const container = this._getContainerDimensions(); const halfWidth = container.size[0] / 2; const halfHeight = container.size[1] / 2; this._moveState.yawLeft = -(event.pageX - container.offset[0] - halfWidth) / halfWidth; this._moveState.pitchDown = (event.pageY - container.offset[1] - halfHeight) / halfHeight; this._updateRotationVector(); } } function onPointerUp3(event) { if (this.enabled === false) return; if (this.dragToLook) { this._status--; this._moveState.yawLeft = this._moveState.pitchDown = 0; } else { switch (event.button) { case 0: this._moveState.forward = 0; break; case 2: this._moveState.back = 0; break; } this._updateMovementVector(); } this._updateRotationVector(); } function onPointerCancel3() { if (this.enabled === false) return; if (this.dragToLook) { this._status = 0; this._moveState.yawLeft = this._moveState.pitchDown = 0; } else { this._moveState.forward = 0; this._moveState.back = 0; this._updateMovementVector(); } this._updateRotationVector(); } function onContextMenu4(event) { if (this.enabled === false) return; event.preventDefault(); } // ../../node_modules/three/examples/jsm/shaders/CopyShader.js var CopyShader = { name: "CopyShader", uniforms: { "tDiffuse": { value: null }, "opacity": { value: 1 } }, vertexShader: ( /* glsl */ ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }` ), fragmentShader: ( /* glsl */ ` uniform float opacity; uniform sampler2D tDiffuse; varying vec2 vUv; void main() { vec4 texel = texture2D( tDiffuse, vUv ); gl_FragColor = opacity * texel; }` ) }; // ../../node_modules/three/examples/jsm/postprocessing/Pass.js var Pass = class { constructor() { this.isPass = true; this.enabled = true; this.needsSwap = true; this.clear = false; this.renderToScreen = false; } setSize() { } render() { console.error("THREE.Pass: .render() must be implemented in derived pass."); } dispose() { } }; var _camera2 = new OrthographicCamera(-1, 1, 1, -1, 0, 1); var FullscreenTriangleGeometry = class extends BufferGeometry { constructor() { super(); this.setAttribute("position", new Float32BufferAttribute([-1, 3, 0, -1, -1, 0, 3, -1, 0], 3)); this.setAttribute("uv", new Float32BufferAttribute([0, 2, 0, 0, 2, 0], 2)); } }; var _geometry2 = new FullscreenTriangleGeometry(); var FullScreenQuad = class { constructor(material) { this._mesh = new Mesh(_geometry2, material); } dispose() { this._mesh.geometry.dispose(); } render(renderer3) { renderer3.render(this._mesh, _camera2); } get material() { return this._mesh.material; } set material(value) { this._mesh.material = value; } }; // ../../node_modules/three/examples/jsm/postprocessing/ShaderPass.js var ShaderPass = class extends Pass { constructor(shader, textureID) { super(); this.textureID = textureID !== void 0 ? textureID : "tDiffuse"; if (shader instanceof ShaderMaterial) { this.uniforms = shader.uniforms; this.material = shader; } else if (shader) { this.uniforms = UniformsUtils.clone(shader.uniforms); this.material = new ShaderMaterial({ name: shader.name !== void 0 ? shader.name : "unspecified", defines: Object.assign({}, shader.defines), uniforms: this.uniforms, vertexShader: shader.vertexShader, fragmentShader: shader.fragmentShader }); } this.fsQuad = new FullScreenQuad(this.material); } render(renderer3, writeBuffer, readBuffer) { if (this.uniforms[this.textureID]) { this.uniforms[this.textureID].value = readBuffer.texture; } this.fsQuad.material = this.material; if (this.renderToScreen) { renderer3.setRenderTarget(null); this.fsQuad.render(renderer3); } else { renderer3.setRenderTarget(writeBuffer); if (this.clear) renderer3.clear(renderer3.autoClearColor, renderer3.autoClearDepth, renderer3.autoClearStencil); this.fsQuad.render(renderer3); } } dispose() { this.material.dispose(); this.fsQuad.dispose(); } }; // ../../node_modules/three/examples/jsm/postprocessing/MaskPass.js var MaskPass = class extends Pass { constructor(scene3, camera3) { super(); this.scene = scene3; this.camera = camera3; this.clear = true; this.needsSwap = false; this.inverse = false; } render(renderer3, writeBuffer, readBuffer) { const context2 = renderer3.getContext(); const state = renderer3.state; state.buffers.color.setMask(false); state.buffers.depth.setMask(false); state.buffers.color.setLocked(true); state.buffers.depth.setLocked(true); let writeValue, clearValue; if (this.inverse) { writeValue = 0; clearValue = 1; } else { writeValue = 1; clearValue = 0; } state.buffers.stencil.setTest(true); state.buffers.stencil.setOp(context2.REPLACE, context2.REPLACE, context2.REPLACE); state.buffers.stencil.setFunc(context2.ALWAYS, writeValue, 4294967295); state.buffers.stencil.setClear(clearValue); state.buffers.stencil.setLocked(true); renderer3.setRenderTarget(readBuffer); if (this.clear) renderer3.clear(); renderer3.render(this.scene, this.camera); renderer3.setRenderTarget(writeBuffer); if (this.clear) renderer3.clear(); renderer3.render(this.scene, this.camera); state.buffers.color.setLocked(false); state.buffers.depth.setLocked(false); state.buffers.color.setMask(true); state.buffers.depth.setMask(true); state.buffers.stencil.setLocked(false); state.buffers.stencil.setFunc(context2.EQUAL, 1, 4294967295); state.buffers.stencil.setOp(context2.KEEP, context2.KEEP, context2.KEEP); state.buffers.stencil.setLocked(true); } }; var ClearMaskPass = class extends Pass { constructor() { super(); this.needsSwap = false; } render(renderer3) { renderer3.state.buffers.stencil.setLocked(false); renderer3.state.buffers.stencil.setTest(false); } }; // ../../node_modules/three/examples/jsm/postprocessing/EffectComposer.js var EffectComposer = class { constructor(renderer3, renderTarget) { this.renderer = renderer3; this._pixelRatio = renderer3.getPixelRatio(); if (renderTarget === void 0) { const size = renderer3.getSize(new Vector2()); this._width = size.width; this._height = size.height; renderTarget = new WebGLRenderTarget(this._width * this._pixelRatio, this._height * this._pixelRatio, { type: HalfFloatType }); renderTarget.texture.name = "EffectComposer.rt1"; } else { this._width = renderTarget.width; this._height = renderTarget.height; } this.renderTarget1 = renderTarget; this.renderTarget2 = renderTarget.clone(); this.renderTarget2.texture.name = "EffectComposer.rt2"; this.writeBuffer = this.renderTarget1; this.readBuffer = this.renderTarget2; this.renderToScreen = true; this.passes = []; this.copyPass = new ShaderPass(CopyShader); this.copyPass.material.blending = NoBlending; this.clock = new Clock(); } swapBuffers() { const tmp2 = this.readBuffer; this.readBuffer = this.writeBuffer; this.writeBuffer = tmp2; } addPass(pass) { this.passes.push(pass); pass.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio); } insertPass(pass, index5) { this.passes.splice(index5, 0, pass); pass.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio); } removePass(pass) { const index5 = this.passes.indexOf(pass); if (index5 !== -1) { this.passes.splice(index5, 1); } } isLastEnabledPass(passIndex) { for (let i = passIndex + 1; i < this.passes.length; i++) { if (this.passes[i].enabled) { return false; } } return true; } render(deltaTime) { if (deltaTime === void 0) { deltaTime = this.clock.getDelta(); } const currentRenderTarget = this.renderer.getRenderTarget(); let maskActive = false; for (let i = 0, il = this.passes.length; i < il; i++) { const pass = this.passes[i]; if (pass.enabled === false) continue; pass.renderToScreen = this.renderToScreen && this.isLastEnabledPass(i); pass.render(this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive); if (pass.needsSwap) { if (maskActive) { const context2 = this.renderer.getContext(); const stencil = this.renderer.state.buffers.stencil; stencil.setFunc(context2.NOTEQUAL, 1, 4294967295); this.copyPass.render(this.renderer, this.writeBuffer, this.readBuffer, deltaTime); stencil.setFunc(context2.EQUAL, 1, 4294967295); } this.swapBuffers(); } if (MaskPass !== void 0) { if (pass instanceof MaskPass) { maskActive = true; } else if (pass instanceof ClearMaskPass) { maskActive = false; } } } this.renderer.setRenderTarget(currentRenderTarget); } reset(renderTarget) { if (renderTarget === void 0) { const size = this.renderer.getSize(new Vector2()); this._pixelRatio = this.renderer.getPixelRatio(); this._width = size.width; this._height = size.height; renderTarget = this.renderTarget1.clone(); renderTarget.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio); } this.renderTarget1.dispose(); this.renderTarget2.dispose(); this.renderTarget1 = renderTarget; this.renderTarget2 = renderTarget.clone(); this.writeBuffer = this.renderTarget1; this.readBuffer = this.renderTarget2; } setSize(width, height) { this._width = width; this._height = height; const effectiveWidth = this._width * this._pixelRatio; const effectiveHeight = this._height * this._pixelRatio; this.renderTarget1.setSize(effectiveWidth, effectiveHeight); this.renderTarget2.setSize(effectiveWidth, effectiveHeight); for (let i = 0; i < this.passes.length; i++) { this.passes[i].setSize(effectiveWidth, effectiveHeight); } } setPixelRatio(pixelRatio) { this._pixelRatio = pixelRatio; this.setSize(this._width, this._height); } dispose() { this.renderTarget1.dispose(); this.renderTarget2.dispose(); this.copyPass.dispose(); } }; // ../../node_modules/three/examples/jsm/postprocessing/RenderPass.js var RenderPass = class extends Pass { constructor(scene3, camera3, overrideMaterial = null, clearColor = null, clearAlpha = null) { super(); this.scene = scene3; this.camera = camera3; this.overrideMaterial = overrideMaterial; this.clearColor = clearColor; this.clearAlpha = clearAlpha; this.clear = true; this.clearDepth = false; this.needsSwap = false; this._oldClearColor = new Color(); } render(renderer3, writeBuffer, readBuffer) { const oldAutoClear = renderer3.autoClear; renderer3.autoClear = false; let oldClearAlpha, oldOverrideMaterial; if (this.overrideMaterial !== null) { oldOverrideMaterial = this.scene.overrideMaterial; this.scene.overrideMaterial = this.overrideMaterial; } if (this.clearColor !== null) { renderer3.getClearColor(this._oldClearColor); renderer3.setClearColor(this.clearColor, renderer3.getClearAlpha()); } if (this.clearAlpha !== null) { oldClearAlpha = renderer3.getClearAlpha(); renderer3.setClearAlpha(this.clearAlpha); } if (this.clearDepth == true) { renderer3.clearDepth(); } renderer3.setRenderTarget(this.renderToScreen ? null : readBuffer); if (this.clear === true) { renderer3.clear(renderer3.autoClearColor, renderer3.autoClearDepth, renderer3.autoClearStencil); } renderer3.render(this.scene, this.camera); if (this.clearColor !== null) { renderer3.setClearColor(this._oldClearColor); } if (this.clearAlpha !== null) { renderer3.setClearAlpha(oldClearAlpha); } if (this.overrideMaterial !== null) { this.scene.overrideMaterial = oldOverrideMaterial; } renderer3.autoClear = oldAutoClear; } }; // ../../node_modules/@babel/runtime/helpers/esm/extends.js function _extends() { return _extends = Object.assign ? Object.assign.bind() : function(n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } // ../../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js function _assertThisInitialized2(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } // ../../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js function _setPrototypeOf2(t, e) { return _setPrototypeOf2 = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(t2, e2) { return t2.__proto__ = e2, t2; }, _setPrototypeOf2(t, e); } // ../../node_modules/@babel/runtime/helpers/esm/inheritsLoose.js function _inheritsLoose(t, o) { t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf2(t, o); } // ../../node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js function _getPrototypeOf2(t) { return _getPrototypeOf2 = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(t2) { return t2.__proto__ || Object.getPrototypeOf(t2); }, _getPrototypeOf2(t); } // ../../node_modules/@babel/runtime/helpers/esm/isNativeFunction.js function _isNativeFunction(t) { try { return -1 !== Function.toString.call(t).indexOf("[native code]"); } catch (n) { return "function" == typeof t; } } // ../../node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js function _isNativeReflectConstruct2() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() { })); } catch (t2) { } return (_isNativeReflectConstruct2 = function _isNativeReflectConstruct3() { return !!t; })(); } // ../../node_modules/@babel/runtime/helpers/esm/construct.js function _construct2(t, e, r) { if (_isNativeReflectConstruct2()) return Reflect.construct.apply(null, arguments); var o = [null]; o.push.apply(o, e); var p = new (t.bind.apply(t, o))(); return r && _setPrototypeOf2(p, r.prototype), p; } // ../../node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js function _wrapNativeSuper(t) { var r = "function" == typeof Map ? /* @__PURE__ */ new Map() : void 0; return _wrapNativeSuper = function _wrapNativeSuper2(t2) { if (null === t2 || !_isNativeFunction(t2)) return t2; if ("function" != typeof t2) throw new TypeError("Super expression must either be null or a function"); if (void 0 !== r) { if (r.has(t2)) return r.get(t2); r.set(t2, Wrapper); } function Wrapper() { return _construct2(t2, arguments, _getPrototypeOf2(this).constructor); } return Wrapper.prototype = Object.create(t2.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }), _setPrototypeOf2(Wrapper, t2); }, _wrapNativeSuper(t); } // ../../node_modules/polished/dist/polished.esm.js var ERRORS = { "1": "Passed invalid arguments to hsl, please pass multiple numbers e.g. hsl(360, 0.75, 0.4) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75 }).\n\n", "2": "Passed invalid arguments to hsla, please pass multiple numbers e.g. hsla(360, 0.75, 0.4, 0.7) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75, alpha: 0.7 }).\n\n", "3": "Passed an incorrect argument to a color function, please pass a string representation of a color.\n\n", "4": "Couldn't generate valid rgb string from %s, it returned %s.\n\n", "5": "Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.\n\n", "6": "Passed invalid arguments to rgb, please pass multiple numbers e.g. rgb(255, 205, 100) or an object e.g. rgb({ red: 255, green: 205, blue: 100 }).\n\n", "7": "Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 0.75) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 0.75 }).\n\n", "8": "Passed invalid argument to toColorString, please pass a RgbColor, RgbaColor, HslColor or HslaColor object.\n\n", "9": "Please provide a number of steps to the modularScale helper.\n\n", "10": "Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\n\n", "11": 'Invalid value passed as base to modularScale, expected number or em string but got "%s"\n\n', "12": 'Expected a string ending in "px" or a number passed as the first argument to %s(), got "%s" instead.\n\n', "13": 'Expected a string ending in "px" or a number passed as the second argument to %s(), got "%s" instead.\n\n', "14": 'Passed invalid pixel value ("%s") to %s(), please pass a value like "12px" or 12.\n\n', "15": 'Passed invalid base value ("%s") to %s(), please pass a value like "12px" or 12.\n\n', "16": "You must provide a template to this method.\n\n", "17": "You passed an unsupported selector state to this method.\n\n", "18": "minScreen and maxScreen must be provided as stringified numbers with the same units.\n\n", "19": "fromSize and toSize must be provided as stringified numbers with the same units.\n\n", "20": "expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\n\n", "21": "expects the objects in the first argument array to have the properties `prop`, `fromSize`, and `toSize`.\n\n", "22": "expects the first argument object to have the properties `prop`, `fromSize`, and `toSize`.\n\n", "23": "fontFace expects a name of a font-family.\n\n", "24": "fontFace expects either the path to the font file(s) or a name of a local copy.\n\n", "25": "fontFace expects localFonts to be an array.\n\n", "26": "fontFace expects fileFormats to be an array.\n\n", "27": "radialGradient requries at least 2 color-stops to properly render.\n\n", "28": "Please supply a filename to retinaImage() as the first argument.\n\n", "29": "Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\n\n", "30": "Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n", "31": "The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation\n\n", "32": "To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s')\n\n", "33": "The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation\n\n", "34": "borderRadius expects a radius value as a string or number as the second argument.\n\n", "35": 'borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.\n\n', "36": "Property must be a string value.\n\n", "37": "Syntax Error at %s.\n\n", "38": "Formula contains a function that needs parentheses at %s.\n\n", "39": "Formula is missing closing parenthesis at %s.\n\n", "40": "Formula has too many closing parentheses at %s.\n\n", "41": "All values in a formula must have the same unit or be unitless.\n\n", "42": "Please provide a number of steps to the modularScale helper.\n\n", "43": "Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\n\n", "44": "Invalid value passed as base to modularScale, expected number or em/rem string but got %s.\n\n", "45": "Passed invalid argument to hslToColorString, please pass a HslColor or HslaColor object.\n\n", "46": "Passed invalid argument to rgbToColorString, please pass a RgbColor or RgbaColor object.\n\n", "47": "minScreen and maxScreen must be provided as stringified numbers with the same units.\n\n", "48": "fromSize and toSize must be provided as stringified numbers with the same units.\n\n", "49": "Expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\n\n", "50": "Expects the objects in the first argument array to have the properties prop, fromSize, and toSize.\n\n", "51": "Expects the first argument object to have the properties prop, fromSize, and toSize.\n\n", "52": "fontFace expects either the path to the font file(s) or a name of a local copy.\n\n", "53": "fontFace expects localFonts to be an array.\n\n", "54": "fontFace expects fileFormats to be an array.\n\n", "55": "fontFace expects a name of a font-family.\n\n", "56": "linearGradient requries at least 2 color-stops to properly render.\n\n", "57": "radialGradient requries at least 2 color-stops to properly render.\n\n", "58": "Please supply a filename to retinaImage() as the first argument.\n\n", "59": "Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\n\n", "60": "Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n", "61": "Property must be a string value.\n\n", "62": "borderRadius expects a radius value as a string or number as the second argument.\n\n", "63": 'borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.\n\n', "64": "The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation.\n\n", "65": "To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s').\n\n", "66": "The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation.\n\n", "67": "You must provide a template to this method.\n\n", "68": "You passed an unsupported selector state to this method.\n\n", "69": 'Expected a string ending in "px" or a number passed as the first argument to %s(), got %s instead.\n\n', "70": 'Expected a string ending in "px" or a number passed as the second argument to %s(), got %s instead.\n\n', "71": 'Passed invalid pixel value %s to %s(), please pass a value like "12px" or 12.\n\n', "72": 'Passed invalid base value %s to %s(), please pass a value like "12px" or 12.\n\n', "73": "Please provide a valid CSS variable.\n\n", "74": "CSS variable not found and no default was provided.\n\n", "75": "important requires a valid style object, got a %s instead.\n\n", "76": "fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.\n\n", "77": 'remToPx expects a value in "rem" but you provided it in "%s".\n\n', "78": 'base must be set in "px" or "%" but you set it in "%s".\n' }; function format() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var a2 = args[0]; var b = []; var c2; for (c2 = 1; c2 < args.length; c2 += 1) { b.push(args[c2]); } b.forEach(function(d) { a2 = a2.replace(/%[a-z]/, d); }); return a2; } var PolishedError = /* @__PURE__ */ function(_Error) { _inheritsLoose(PolishedError2, _Error); function PolishedError2(code) { var _this; if (false) { _this = _Error.call(this, "An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#" + code + " for more information.") || this; } else { for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } _this = _Error.call(this, format.apply(void 0, [ERRORS[code]].concat(args))) || this; } return _assertThisInitialized2(_this); } return PolishedError2; }(/* @__PURE__ */ _wrapNativeSuper(Error)); function endsWith(string, suffix) { return string.substr(-suffix.length) === suffix; } var cssRegex$1 = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/; function stripUnit(value) { if (typeof value !== "string") return value; var matchedValue = value.match(cssRegex$1); return matchedValue ? parseFloat(value) : value; } var pxtoFactory = function pxtoFactory2(to) { return function(pxval, base) { if (base === void 0) { base = "16px"; } var newPxval = pxval; var newBase = base; if (typeof pxval === "string") { if (!endsWith(pxval, "px")) { throw new PolishedError(69, to, pxval); } newPxval = stripUnit(pxval); } if (typeof base === "string") { if (!endsWith(base, "px")) { throw new PolishedError(70, to, base); } newBase = stripUnit(base); } if (typeof newPxval === "string") { throw new PolishedError(71, pxval, to); } if (typeof newBase === "string") { throw new PolishedError(72, base, to); } return "" + newPxval / newBase + to; }; }; var pixelsto = pxtoFactory; var em = pixelsto("em"); var rem = pixelsto("rem"); function colorToInt(color2) { return Math.round(color2 * 255); } function convertToInt(red, green, blue) { return colorToInt(red) + "," + colorToInt(green) + "," + colorToInt(blue); } function hslToRgb2(hue, saturation, lightness, convert2) { if (convert2 === void 0) { convert2 = convertToInt; } if (saturation === 0) { return convert2(lightness, lightness, lightness); } var huePrime = (hue % 360 + 360) % 360 / 60; var chroma = (1 - Math.abs(2 * lightness - 1)) * saturation; var secondComponent = chroma * (1 - Math.abs(huePrime % 2 - 1)); var red = 0; var green = 0; var blue = 0; if (huePrime >= 0 && huePrime < 1) { red = chroma; green = secondComponent; } else if (huePrime >= 1 && huePrime < 2) { red = secondComponent; green = chroma; } else if (huePrime >= 2 && huePrime < 3) { green = chroma; blue = secondComponent; } else if (huePrime >= 3 && huePrime < 4) { green = secondComponent; blue = chroma; } else if (huePrime >= 4 && huePrime < 5) { red = secondComponent; blue = chroma; } else if (huePrime >= 5 && huePrime < 6) { red = chroma; blue = secondComponent; } var lightnessModification = lightness - chroma / 2; var finalRed = red + lightnessModification; var finalGreen = green + lightnessModification; var finalBlue = blue + lightnessModification; return convert2(finalRed, finalGreen, finalBlue); } var namedColorMap = { aliceblue: "f0f8ff", antiquewhite: "faebd7", aqua: "00ffff", aquamarine: "7fffd4", azure: "f0ffff", beige: "f5f5dc", bisque: "ffe4c4", black: "000", blanchedalmond: "ffebcd", blue: "0000ff", blueviolet: "8a2be2", brown: "a52a2a", burlywood: "deb887", cadetblue: "5f9ea0", chartreuse: "7fff00", chocolate: "d2691e", coral: "ff7f50", cornflowerblue: "6495ed", cornsilk: "fff8dc", crimson: "dc143c", cyan: "00ffff", darkblue: "00008b", darkcyan: "008b8b", darkgoldenrod: "b8860b", darkgray: "a9a9a9", darkgreen: "006400", darkgrey: "a9a9a9", darkkhaki: "bdb76b", darkmagenta: "8b008b", darkolivegreen: "556b2f", darkorange: "ff8c00", darkorchid: "9932cc", darkred: "8b0000", darksalmon: "e9967a", darkseagreen: "8fbc8f", darkslateblue: "483d8b", darkslategray: "2f4f4f", darkslategrey: "2f4f4f", darkturquoise: "00ced1", darkviolet: "9400d3", deeppink: "ff1493", deepskyblue: "00bfff", dimgray: "696969", dimgrey: "696969", dodgerblue: "1e90ff", firebrick: "b22222", floralwhite: "fffaf0", forestgreen: "228b22", fuchsia: "ff00ff", gainsboro: "dcdcdc", ghostwhite: "f8f8ff", gold: "ffd700", goldenrod: "daa520", gray: "808080", green: "008000", greenyellow: "adff2f", grey: "808080", honeydew: "f0fff0", hotpink: "ff69b4", indianred: "cd5c5c", indigo: "4b0082", ivory: "fffff0", khaki: "f0e68c", lavender: "e6e6fa", lavenderblush: "fff0f5", lawngreen: "7cfc00", lemonchiffon: "fffacd", lightblue: "add8e6", lightcoral: "f08080", lightcyan: "e0ffff", lightgoldenrodyellow: "fafad2", lightgray: "d3d3d3", lightgreen: "90ee90", lightgrey: "d3d3d3", lightpink: "ffb6c1", lightsalmon: "ffa07a", lightseagreen: "20b2aa", lightskyblue: "87cefa", lightslategray: "789", lightslategrey: "789", lightsteelblue: "b0c4de", lightyellow: "ffffe0", lime: "0f0", limegreen: "32cd32", linen: "faf0e6", magenta: "f0f", maroon: "800000", mediumaquamarine: "66cdaa", mediumblue: "0000cd", mediumorchid: "ba55d3", mediumpurple: "9370db", mediumseagreen: "3cb371", mediumslateblue: "7b68ee", mediumspringgreen: "00fa9a", mediumturquoise: "48d1cc", mediumvioletred: "c71585", midnightblue: "191970", mintcream: "f5fffa", mistyrose: "ffe4e1", moccasin: "ffe4b5", navajowhite: "ffdead", navy: "000080", oldlace: "fdf5e6", olive: "808000", olivedrab: "6b8e23", orange: "ffa500", orangered: "ff4500", orchid: "da70d6", palegoldenrod: "eee8aa", palegreen: "98fb98", paleturquoise: "afeeee", palevioletred: "db7093", papayawhip: "ffefd5", peachpuff: "ffdab9", peru: "cd853f", pink: "ffc0cb", plum: "dda0dd", powderblue: "b0e0e6", purple: "800080", rebeccapurple: "639", red: "f00", rosybrown: "bc8f8f", royalblue: "4169e1", saddlebrown: "8b4513", salmon: "fa8072", sandybrown: "f4a460", seagreen: "2e8b57", seashell: "fff5ee", sienna: "a0522d", silver: "c0c0c0", skyblue: "87ceeb", slateblue: "6a5acd", slategray: "708090", slategrey: "708090", snow: "fffafa", springgreen: "00ff7f", steelblue: "4682b4", tan: "d2b48c", teal: "008080", thistle: "d8bfd8", tomato: "ff6347", turquoise: "40e0d0", violet: "ee82ee", wheat: "f5deb3", white: "fff", whitesmoke: "f5f5f5", yellow: "ff0", yellowgreen: "9acd32" }; function nameToHex(color2) { if (typeof color2 !== "string") return color2; var normalizedColorName = color2.toLowerCase(); return namedColorMap[normalizedColorName] ? "#" + namedColorMap[normalizedColorName] : color2; } var hexRegex = /^#[a-fA-F0-9]{6}$/; var hexRgbaRegex = /^#[a-fA-F0-9]{8}$/; var reducedHexRegex = /^#[a-fA-F0-9]{3}$/; var reducedRgbaHexRegex = /^#[a-fA-F0-9]{4}$/; var rgbRegex = /^rgb\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*\)$/i; var rgbaRegex = /^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i; var hslRegex = /^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i; var hslaRegex = /^hsl(?:a)?\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i; function parseToRgb(color2) { if (typeof color2 !== "string") { throw new PolishedError(3); } var normalizedColor = nameToHex(color2); if (normalizedColor.match(hexRegex)) { return { red: parseInt("" + normalizedColor[1] + normalizedColor[2], 16), green: parseInt("" + normalizedColor[3] + normalizedColor[4], 16), blue: parseInt("" + normalizedColor[5] + normalizedColor[6], 16) }; } if (normalizedColor.match(hexRgbaRegex)) { var alpha = parseFloat((parseInt("" + normalizedColor[7] + normalizedColor[8], 16) / 255).toFixed(2)); return { red: parseInt("" + normalizedColor[1] + normalizedColor[2], 16), green: parseInt("" + normalizedColor[3] + normalizedColor[4], 16), blue: parseInt("" + normalizedColor[5] + normalizedColor[6], 16), alpha }; } if (normalizedColor.match(reducedHexRegex)) { return { red: parseInt("" + normalizedColor[1] + normalizedColor[1], 16), green: parseInt("" + normalizedColor[2] + normalizedColor[2], 16), blue: parseInt("" + normalizedColor[3] + normalizedColor[3], 16) }; } if (normalizedColor.match(reducedRgbaHexRegex)) { var _alpha = parseFloat((parseInt("" + normalizedColor[4] + normalizedColor[4], 16) / 255).toFixed(2)); return { red: parseInt("" + normalizedColor[1] + normalizedColor[1], 16), green: parseInt("" + normalizedColor[2] + normalizedColor[2], 16), blue: parseInt("" + normalizedColor[3] + normalizedColor[3], 16), alpha: _alpha }; } var rgbMatched = rgbRegex.exec(normalizedColor); if (rgbMatched) { return { red: parseInt("" + rgbMatched[1], 10), green: parseInt("" + rgbMatched[2], 10), blue: parseInt("" + rgbMatched[3], 10) }; } var rgbaMatched = rgbaRegex.exec(normalizedColor.substring(0, 50)); if (rgbaMatched) { return { red: parseInt("" + rgbaMatched[1], 10), green: parseInt("" + rgbaMatched[2], 10), blue: parseInt("" + rgbaMatched[3], 10), alpha: parseFloat("" + rgbaMatched[4]) > 1 ? parseFloat("" + rgbaMatched[4]) / 100 : parseFloat("" + rgbaMatched[4]) }; } var hslMatched = hslRegex.exec(normalizedColor); if (hslMatched) { var hue = parseInt("" + hslMatched[1], 10); var saturation = parseInt("" + hslMatched[2], 10) / 100; var lightness = parseInt("" + hslMatched[3], 10) / 100; var rgbColorString = "rgb(" + hslToRgb2(hue, saturation, lightness) + ")"; var hslRgbMatched = rgbRegex.exec(rgbColorString); if (!hslRgbMatched) { throw new PolishedError(4, normalizedColor, rgbColorString); } return { red: parseInt("" + hslRgbMatched[1], 10), green: parseInt("" + hslRgbMatched[2], 10), blue: parseInt("" + hslRgbMatched[3], 10) }; } var hslaMatched = hslaRegex.exec(normalizedColor.substring(0, 50)); if (hslaMatched) { var _hue = parseInt("" + hslaMatched[1], 10); var _saturation = parseInt("" + hslaMatched[2], 10) / 100; var _lightness = parseInt("" + hslaMatched[3], 10) / 100; var _rgbColorString = "rgb(" + hslToRgb2(_hue, _saturation, _lightness) + ")"; var _hslRgbMatched = rgbRegex.exec(_rgbColorString); if (!_hslRgbMatched) { throw new PolishedError(4, normalizedColor, _rgbColorString); } return { red: parseInt("" + _hslRgbMatched[1], 10), green: parseInt("" + _hslRgbMatched[2], 10), blue: parseInt("" + _hslRgbMatched[3], 10), alpha: parseFloat("" + hslaMatched[4]) > 1 ? parseFloat("" + hslaMatched[4]) / 100 : parseFloat("" + hslaMatched[4]) }; } throw new PolishedError(5); } function rgbToHsl2(color2) { var red = color2.red / 255; var green = color2.green / 255; var blue = color2.blue / 255; var max2 = Math.max(red, green, blue); var min2 = Math.min(red, green, blue); var lightness = (max2 + min2) / 2; if (max2 === min2) { if (color2.alpha !== void 0) { return { hue: 0, saturation: 0, lightness, alpha: color2.alpha }; } else { return { hue: 0, saturation: 0, lightness }; } } var hue; var delta = max2 - min2; var saturation = lightness > 0.5 ? delta / (2 - max2 - min2) : delta / (max2 + min2); switch (max2) { case red: hue = (green - blue) / delta + (green < blue ? 6 : 0); break; case green: hue = (blue - red) / delta + 2; break; default: hue = (red - green) / delta + 4; break; } hue *= 60; if (color2.alpha !== void 0) { return { hue, saturation, lightness, alpha: color2.alpha }; } return { hue, saturation, lightness }; } function parseToHsl(color2) { return rgbToHsl2(parseToRgb(color2)); } var reduceHexValue = function reduceHexValue2(value) { if (value.length === 7 && value[1] === value[2] && value[3] === value[4] && value[5] === value[6]) { return "#" + value[1] + value[3] + value[5]; } return value; }; var reduceHexValue$1 = reduceHexValue; function numberToHex(value) { var hex = value.toString(16); return hex.length === 1 ? "0" + hex : hex; } function colorToHex(color2) { return numberToHex(Math.round(color2 * 255)); } function convertToHex(red, green, blue) { return reduceHexValue$1("#" + colorToHex(red) + colorToHex(green) + colorToHex(blue)); } function hslToHex(hue, saturation, lightness) { return hslToRgb2(hue, saturation, lightness, convertToHex); } function hsl(value, saturation, lightness) { if (typeof value === "number" && typeof saturation === "number" && typeof lightness === "number") { return hslToHex(value, saturation, lightness); } else if (typeof value === "object" && saturation === void 0 && lightness === void 0) { return hslToHex(value.hue, value.saturation, value.lightness); } throw new PolishedError(1); } function hsla(value, saturation, lightness, alpha) { if (typeof value === "number" && typeof saturation === "number" && typeof lightness === "number" && typeof alpha === "number") { return alpha >= 1 ? hslToHex(value, saturation, lightness) : "rgba(" + hslToRgb2(value, saturation, lightness) + "," + alpha + ")"; } else if (typeof value === "object" && saturation === void 0 && lightness === void 0 && alpha === void 0) { return value.alpha >= 1 ? hslToHex(value.hue, value.saturation, value.lightness) : "rgba(" + hslToRgb2(value.hue, value.saturation, value.lightness) + "," + value.alpha + ")"; } throw new PolishedError(2); } function rgb(value, green, blue) { if (typeof value === "number" && typeof green === "number" && typeof blue === "number") { return reduceHexValue$1("#" + numberToHex(value) + numberToHex(green) + numberToHex(blue)); } else if (typeof value === "object" && green === void 0 && blue === void 0) { return reduceHexValue$1("#" + numberToHex(value.red) + numberToHex(value.green) + numberToHex(value.blue)); } throw new PolishedError(6); } function rgba(firstValue, secondValue, thirdValue, fourthValue) { if (typeof firstValue === "string" && typeof secondValue === "number") { var rgbValue = parseToRgb(firstValue); return "rgba(" + rgbValue.red + "," + rgbValue.green + "," + rgbValue.blue + "," + secondValue + ")"; } else if (typeof firstValue === "number" && typeof secondValue === "number" && typeof thirdValue === "number" && typeof fourthValue === "number") { return fourthValue >= 1 ? rgb(firstValue, secondValue, thirdValue) : "rgba(" + firstValue + "," + secondValue + "," + thirdValue + "," + fourthValue + ")"; } else if (typeof firstValue === "object" && secondValue === void 0 && thirdValue === void 0 && fourthValue === void 0) { return firstValue.alpha >= 1 ? rgb(firstValue.red, firstValue.green, firstValue.blue) : "rgba(" + firstValue.red + "," + firstValue.green + "," + firstValue.blue + "," + firstValue.alpha + ")"; } throw new PolishedError(7); } var isRgb = function isRgb2(color2) { return typeof color2.red === "number" && typeof color2.green === "number" && typeof color2.blue === "number" && (typeof color2.alpha !== "number" || typeof color2.alpha === "undefined"); }; var isRgba = function isRgba2(color2) { return typeof color2.red === "number" && typeof color2.green === "number" && typeof color2.blue === "number" && typeof color2.alpha === "number"; }; var isHsl = function isHsl2(color2) { return typeof color2.hue === "number" && typeof color2.saturation === "number" && typeof color2.lightness === "number" && (typeof color2.alpha !== "number" || typeof color2.alpha === "undefined"); }; var isHsla = function isHsla2(color2) { return typeof color2.hue === "number" && typeof color2.saturation === "number" && typeof color2.lightness === "number" && typeof color2.alpha === "number"; }; function toColorString(color2) { if (typeof color2 !== "object") throw new PolishedError(8); if (isRgba(color2)) return rgba(color2); if (isRgb(color2)) return rgb(color2); if (isHsla(color2)) return hsla(color2); if (isHsl(color2)) return hsl(color2); throw new PolishedError(8); } function curried(f, length2, acc) { return function fn() { var combined = acc.concat(Array.prototype.slice.call(arguments)); return combined.length >= length2 ? f.apply(this, combined) : curried(f, length2, combined); }; } function curry(f) { return curried(f, f.length, []); } function adjustHue(degree, color2) { if (color2 === "transparent") return color2; var hslColor = parseToHsl(color2); return toColorString(_extends({}, hslColor, { hue: hslColor.hue + parseFloat(degree) })); } var curriedAdjustHue = curry(adjustHue); function guard(lowerBoundary, upperBoundary, value) { return Math.max(lowerBoundary, Math.min(upperBoundary, value)); } function darken2(amount, color2) { if (color2 === "transparent") return color2; var hslColor = parseToHsl(color2); return toColorString(_extends({}, hslColor, { lightness: guard(0, 1, hslColor.lightness - parseFloat(amount)) })); } var curriedDarken = curry(darken2); function desaturate2(amount, color2) { if (color2 === "transparent") return color2; var hslColor = parseToHsl(color2); return toColorString(_extends({}, hslColor, { saturation: guard(0, 1, hslColor.saturation - parseFloat(amount)) })); } var curriedDesaturate = curry(desaturate2); function lighten2(amount, color2) { if (color2 === "transparent") return color2; var hslColor = parseToHsl(color2); return toColorString(_extends({}, hslColor, { lightness: guard(0, 1, hslColor.lightness + parseFloat(amount)) })); } var curriedLighten = curry(lighten2); function mix2(weight, color2, otherColor) { if (color2 === "transparent") return otherColor; if (otherColor === "transparent") return color2; if (weight === 0) return otherColor; var parsedColor1 = parseToRgb(color2); var color1 = _extends({}, parsedColor1, { alpha: typeof parsedColor1.alpha === "number" ? parsedColor1.alpha : 1 }); var parsedColor2 = parseToRgb(otherColor); var color22 = _extends({}, parsedColor2, { alpha: typeof parsedColor2.alpha === "number" ? parsedColor2.alpha : 1 }); var alphaDelta = color1.alpha - color22.alpha; var x2 = parseFloat(weight) * 2 - 1; var y2 = x2 * alphaDelta === -1 ? x2 : x2 + alphaDelta; var z2 = 1 + x2 * alphaDelta; var weight1 = (y2 / z2 + 1) / 2; var weight2 = 1 - weight1; var mixedColor = { red: Math.floor(color1.red * weight1 + color22.red * weight2), green: Math.floor(color1.green * weight1 + color22.green * weight2), blue: Math.floor(color1.blue * weight1 + color22.blue * weight2), alpha: color1.alpha * parseFloat(weight) + color22.alpha * (1 - parseFloat(weight)) }; return rgba(mixedColor); } var curriedMix = curry(mix2); var mix$1 = curriedMix; function opacify(amount, color2) { if (color2 === "transparent") return color2; var parsedColor = parseToRgb(color2); var alpha = typeof parsedColor.alpha === "number" ? parsedColor.alpha : 1; var colorWithAlpha = _extends({}, parsedColor, { alpha: guard(0, 1, (alpha * 100 + parseFloat(amount) * 100) / 100) }); return rgba(colorWithAlpha); } var curriedOpacify = curry(opacify); var curriedOpacify$1 = curriedOpacify; function saturate3(amount, color2) { if (color2 === "transparent") return color2; var hslColor = parseToHsl(color2); return toColorString(_extends({}, hslColor, { saturation: guard(0, 1, hslColor.saturation + parseFloat(amount)) })); } var curriedSaturate = curry(saturate3); function setHue(hue, color2) { if (color2 === "transparent") return color2; return toColorString(_extends({}, parseToHsl(color2), { hue: parseFloat(hue) })); } var curriedSetHue = curry(setHue); function setLightness(lightness, color2) { if (color2 === "transparent") return color2; return toColorString(_extends({}, parseToHsl(color2), { lightness: parseFloat(lightness) })); } var curriedSetLightness = curry(setLightness); function setSaturation(saturation, color2) { if (color2 === "transparent") return color2; return toColorString(_extends({}, parseToHsl(color2), { saturation: parseFloat(saturation) })); } var curriedSetSaturation = curry(setSaturation); function shade(percentage, color2) { if (color2 === "transparent") return color2; return mix$1(parseFloat(percentage), "rgb(0, 0, 0)", color2); } var curriedShade = curry(shade); function tint(percentage, color2) { if (color2 === "transparent") return color2; return mix$1(parseFloat(percentage), "rgb(255, 255, 255)", color2); } var curriedTint = curry(tint); function transparentize(amount, color2) { if (color2 === "transparent") return color2; var parsedColor = parseToRgb(color2); var alpha = typeof parsedColor.alpha === "number" ? parsedColor.alpha : 1; var colorWithAlpha = _extends({}, parsedColor, { alpha: guard(0, 1, +(alpha * 100 - parseFloat(amount) * 100).toFixed(2) / 100) }); return rgba(colorWithAlpha); } var curriedTransparentize = curry(transparentize); // ../../node_modules/@tweenjs/tween.js/dist/tween.esm.js var Easing = Object.freeze({ Linear: Object.freeze({ None: function(amount) { return amount; }, In: function(amount) { return amount; }, Out: function(amount) { return amount; }, InOut: function(amount) { return amount; } }), Quadratic: Object.freeze({ In: function(amount) { return amount * amount; }, Out: function(amount) { return amount * (2 - amount); }, InOut: function(amount) { if ((amount *= 2) < 1) { return 0.5 * amount * amount; } return -0.5 * (--amount * (amount - 2) - 1); } }), Cubic: Object.freeze({ In: function(amount) { return amount * amount * amount; }, Out: function(amount) { return --amount * amount * amount + 1; }, InOut: function(amount) { if ((amount *= 2) < 1) { return 0.5 * amount * amount * amount; } return 0.5 * ((amount -= 2) * amount * amount + 2); } }), Quartic: Object.freeze({ In: function(amount) { return amount * amount * amount * amount; }, Out: function(amount) { return 1 - --amount * amount * amount * amount; }, InOut: function(amount) { if ((amount *= 2) < 1) { return 0.5 * amount * amount * amount * amount; } return -0.5 * ((amount -= 2) * amount * amount * amount - 2); } }), Quintic: Object.freeze({ In: function(amount) { return amount * amount * amount * amount * amount; }, Out: function(amount) { return --amount * amount * amount * amount * amount + 1; }, InOut: function(amount) { if ((amount *= 2) < 1) { return 0.5 * amount * amount * amount * amount * amount; } return 0.5 * ((amount -= 2) * amount * amount * amount * amount + 2); } }), Sinusoidal: Object.freeze({ In: function(amount) { return 1 - Math.sin((1 - amount) * Math.PI / 2); }, Out: function(amount) { return Math.sin(amount * Math.PI / 2); }, InOut: function(amount) { return 0.5 * (1 - Math.sin(Math.PI * (0.5 - amount))); } }), Exponential: Object.freeze({ In: function(amount) { return amount === 0 ? 0 : Math.pow(1024, amount - 1); }, Out: function(amount) { return amount === 1 ? 1 : 1 - Math.pow(2, -10 * amount); }, InOut: function(amount) { if (amount === 0) { return 0; } if (amount === 1) { return 1; } if ((amount *= 2) < 1) { return 0.5 * Math.pow(1024, amount - 1); } return 0.5 * (-Math.pow(2, -10 * (amount - 1)) + 2); } }), Circular: Object.freeze({ In: function(amount) { return 1 - Math.sqrt(1 - amount * amount); }, Out: function(amount) { return Math.sqrt(1 - --amount * amount); }, InOut: function(amount) { if ((amount *= 2) < 1) { return -0.5 * (Math.sqrt(1 - amount * amount) - 1); } return 0.5 * (Math.sqrt(1 - (amount -= 2) * amount) + 1); } }), Elastic: Object.freeze({ In: function(amount) { if (amount === 0) { return 0; } if (amount === 1) { return 1; } return -Math.pow(2, 10 * (amount - 1)) * Math.sin((amount - 1.1) * 5 * Math.PI); }, Out: function(amount) { if (amount === 0) { return 0; } if (amount === 1) { return 1; } return Math.pow(2, -10 * amount) * Math.sin((amount - 0.1) * 5 * Math.PI) + 1; }, InOut: function(amount) { if (amount === 0) { return 0; } if (amount === 1) { return 1; } amount *= 2; if (amount < 1) { return -0.5 * Math.pow(2, 10 * (amount - 1)) * Math.sin((amount - 1.1) * 5 * Math.PI); } return 0.5 * Math.pow(2, -10 * (amount - 1)) * Math.sin((amount - 1.1) * 5 * Math.PI) + 1; } }), Back: Object.freeze({ In: function(amount) { var s = 1.70158; return amount === 1 ? 1 : amount * amount * ((s + 1) * amount - s); }, Out: function(amount) { var s = 1.70158; return amount === 0 ? 0 : --amount * amount * ((s + 1) * amount + s) + 1; }, InOut: function(amount) { var s = 1.70158 * 1.525; if ((amount *= 2) < 1) { return 0.5 * (amount * amount * ((s + 1) * amount - s)); } return 0.5 * ((amount -= 2) * amount * ((s + 1) * amount + s) + 2); } }), Bounce: Object.freeze({ In: function(amount) { return 1 - Easing.Bounce.Out(1 - amount); }, Out: function(amount) { if (amount < 1 / 2.75) { return 7.5625 * amount * amount; } else if (amount < 2 / 2.75) { return 7.5625 * (amount -= 1.5 / 2.75) * amount + 0.75; } else if (amount < 2.5 / 2.75) { return 7.5625 * (amount -= 2.25 / 2.75) * amount + 0.9375; } else { return 7.5625 * (amount -= 2.625 / 2.75) * amount + 0.984375; } }, InOut: function(amount) { if (amount < 0.5) { return Easing.Bounce.In(amount * 2) * 0.5; } return Easing.Bounce.Out(amount * 2 - 1) * 0.5 + 0.5; } }), generatePow: function(power) { if (power === void 0) { power = 4; } power = power < Number.EPSILON ? Number.EPSILON : power; power = power > 1e4 ? 1e4 : power; return { In: function(amount) { return Math.pow(amount, power); }, Out: function(amount) { return 1 - Math.pow(1 - amount, power); }, InOut: function(amount) { if (amount < 0.5) { return Math.pow(amount * 2, power) / 2; } return (1 - Math.pow(2 - amount * 2, power)) / 2 + 0.5; } }; } }); var now4 = function() { return performance.now(); }; var Group2 = ( /** @class */ function() { function Group3() { var tweens = []; for (var _i = 0; _i < arguments.length; _i++) { tweens[_i] = arguments[_i]; } this._tweens = {}; this._tweensAddedDuringUpdate = {}; this.add.apply(this, tweens); } Group3.prototype.getAll = function() { var _this = this; return Object.keys(this._tweens).map(function(tweenId) { return _this._tweens[tweenId]; }); }; Group3.prototype.removeAll = function() { this._tweens = {}; }; Group3.prototype.add = function() { var _a; var tweens = []; for (var _i = 0; _i < arguments.length; _i++) { tweens[_i] = arguments[_i]; } for (var _b = 0, tweens_1 = tweens; _b < tweens_1.length; _b++) { var tween = tweens_1[_b]; (_a = tween._group) === null || _a === void 0 ? void 0 : _a.remove(tween); tween._group = this; this._tweens[tween.getId()] = tween; this._tweensAddedDuringUpdate[tween.getId()] = tween; } }; Group3.prototype.remove = function() { var tweens = []; for (var _i = 0; _i < arguments.length; _i++) { tweens[_i] = arguments[_i]; } for (var _a = 0, tweens_2 = tweens; _a < tweens_2.length; _a++) { var tween = tweens_2[_a]; tween._group = void 0; delete this._tweens[tween.getId()]; delete this._tweensAddedDuringUpdate[tween.getId()]; } }; Group3.prototype.allStopped = function() { return this.getAll().every(function(tween) { return !tween.isPlaying(); }); }; Group3.prototype.update = function(time, preserve) { if (time === void 0) { time = now4(); } if (preserve === void 0) { preserve = true; } var tweenIds = Object.keys(this._tweens); if (tweenIds.length === 0) return; while (tweenIds.length > 0) { this._tweensAddedDuringUpdate = {}; for (var i = 0; i < tweenIds.length; i++) { var tween = this._tweens[tweenIds[i]]; var autoStart = !preserve; if (tween && tween.update(time, autoStart) === false && !preserve) this.remove(tween); } tweenIds = Object.keys(this._tweensAddedDuringUpdate); } }; return Group3; }() ); var Interpolation = { Linear: function(v, k) { var m2 = v.length - 1; var f = m2 * k; var i = Math.floor(f); var fn = Interpolation.Utils.Linear; if (k < 0) { return fn(v[0], v[1], f); } if (k > 1) { return fn(v[m2], v[m2 - 1], m2 - f); } return fn(v[i], v[i + 1 > m2 ? m2 : i + 1], f - i); }, Bezier: function(v, k) { var b = 0; var n = v.length - 1; var pw = Math.pow; var bn = Interpolation.Utils.Bernstein; for (var i = 0; i <= n; i++) { b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i); } return b; }, CatmullRom: function(v, k) { var m2 = v.length - 1; var f = m2 * k; var i = Math.floor(f); var fn = Interpolation.Utils.CatmullRom; if (v[0] === v[m2]) { if (k < 0) { i = Math.floor(f = m2 * (1 + k)); } return fn(v[(i - 1 + m2) % m2], v[i], v[(i + 1) % m2], v[(i + 2) % m2], f - i); } else { if (k < 0) { return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]); } if (k > 1) { return v[m2] - (fn(v[m2], v[m2], v[m2 - 1], v[m2 - 1], f - m2) - v[m2]); } return fn(v[i ? i - 1 : 0], v[i], v[m2 < i + 1 ? m2 : i + 1], v[m2 < i + 2 ? m2 : i + 2], f - i); } }, Utils: { Linear: function(p0, p1, t) { return (p1 - p0) * t + p0; }, Bernstein: function(n, i) { var fc = Interpolation.Utils.Factorial; return fc(n) / fc(i) / fc(n - i); }, Factorial: /* @__PURE__ */ function() { var a2 = [1]; return function(n) { var s = 1; if (a2[n]) { return a2[n]; } for (var i = n; i > 1; i--) { s *= i; } a2[n] = s; return s; }; }(), CatmullRom: function(p0, p1, p2, p3, t) { var v0 = (p2 - p0) * 0.5; var v1 = (p3 - p1) * 0.5; var t2 = t * t; var t3 = t * t2; return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; } } }; var Sequence = ( /** @class */ function() { function Sequence2() { } Sequence2.nextId = function() { return Sequence2._nextId++; }; Sequence2._nextId = 0; return Sequence2; }() ); var mainGroup = new Group2(); var Tween = ( /** @class */ function() { function Tween2(object, group) { this._isPaused = false; this._pauseStart = 0; this._valuesStart = {}; this._valuesEnd = {}; this._valuesStartRepeat = {}; this._duration = 1e3; this._isDynamic = false; this._initialRepeat = 0; this._repeat = 0; this._yoyo = false; this._isPlaying = false; this._reversed = false; this._delayTime = 0; this._startTime = 0; this._easingFunction = Easing.Linear.None; this._interpolationFunction = Interpolation.Linear; this._chainedTweens = []; this._onStartCallbackFired = false; this._onEveryStartCallbackFired = false; this._id = Sequence.nextId(); this._isChainStopped = false; this._propertiesAreSetUp = false; this._goToEnd = false; this._object = object; if (typeof group === "object") { this._group = group; group.add(this); } else if (group === true) { this._group = mainGroup; mainGroup.add(this); } } Tween2.prototype.getId = function() { return this._id; }; Tween2.prototype.isPlaying = function() { return this._isPlaying; }; Tween2.prototype.isPaused = function() { return this._isPaused; }; Tween2.prototype.getDuration = function() { return this._duration; }; Tween2.prototype.to = function(target, duration) { if (duration === void 0) { duration = 1e3; } if (this._isPlaying) throw new Error("Can not call Tween.to() while Tween is already started or paused. Stop the Tween first."); this._valuesEnd = target; this._propertiesAreSetUp = false; this._duration = duration < 0 ? 0 : duration; return this; }; Tween2.prototype.duration = function(duration) { if (duration === void 0) { duration = 1e3; } this._duration = duration < 0 ? 0 : duration; return this; }; Tween2.prototype.dynamic = function(dynamic) { if (dynamic === void 0) { dynamic = false; } this._isDynamic = dynamic; return this; }; Tween2.prototype.start = function(time, overrideStartingValues) { if (time === void 0) { time = now4(); } if (overrideStartingValues === void 0) { overrideStartingValues = false; } if (this._isPlaying) { return this; } this._repeat = this._initialRepeat; if (this._reversed) { this._reversed = false; for (var property2 in this._valuesStartRepeat) { this._swapEndStartRepeatValues(property2); this._valuesStart[property2] = this._valuesStartRepeat[property2]; } } this._isPlaying = true; this._isPaused = false; this._onStartCallbackFired = false; this._onEveryStartCallbackFired = false; this._isChainStopped = false; this._startTime = time; this._startTime += this._delayTime; if (!this._propertiesAreSetUp || overrideStartingValues) { this._propertiesAreSetUp = true; if (!this._isDynamic) { var tmp2 = {}; for (var prop in this._valuesEnd) tmp2[prop] = this._valuesEnd[prop]; this._valuesEnd = tmp2; } this._setupProperties(this._object, this._valuesStart, this._valuesEnd, this._valuesStartRepeat, overrideStartingValues); } return this; }; Tween2.prototype.startFromCurrentValues = function(time) { return this.start(time, true); }; Tween2.prototype._setupProperties = function(_object, _valuesStart, _valuesEnd, _valuesStartRepeat, overrideStartingValues) { for (var property2 in _valuesEnd) { var startValue = _object[property2]; var startValueIsArray = Array.isArray(startValue); var propType = startValueIsArray ? "array" : typeof startValue; var isInterpolationList = !startValueIsArray && Array.isArray(_valuesEnd[property2]); if (propType === "undefined" || propType === "function") { continue; } if (isInterpolationList) { var endValues = _valuesEnd[property2]; if (endValues.length === 0) { continue; } var temp2 = [startValue]; for (var i = 0, l = endValues.length; i < l; i += 1) { var value = this._handleRelativeValue(startValue, endValues[i]); if (isNaN(value)) { isInterpolationList = false; console.warn("Found invalid interpolation list. Skipping."); break; } temp2.push(value); } if (isInterpolationList) { _valuesEnd[property2] = temp2; } } if ((propType === "object" || startValueIsArray) && startValue && !isInterpolationList) { _valuesStart[property2] = startValueIsArray ? [] : {}; var nestedObject = startValue; for (var prop in nestedObject) { _valuesStart[property2][prop] = nestedObject[prop]; } _valuesStartRepeat[property2] = startValueIsArray ? [] : {}; var endValues = _valuesEnd[property2]; if (!this._isDynamic) { var tmp2 = {}; for (var prop in endValues) tmp2[prop] = endValues[prop]; _valuesEnd[property2] = endValues = tmp2; } this._setupProperties(nestedObject, _valuesStart[property2], endValues, _valuesStartRepeat[property2], overrideStartingValues); } else { if (typeof _valuesStart[property2] === "undefined" || overrideStartingValues) { _valuesStart[property2] = startValue; } if (!startValueIsArray) { _valuesStart[property2] *= 1; } if (isInterpolationList) { _valuesStartRepeat[property2] = _valuesEnd[property2].slice().reverse(); } else { _valuesStartRepeat[property2] = _valuesStart[property2] || 0; } } } }; Tween2.prototype.stop = function() { if (!this._isChainStopped) { this._isChainStopped = true; this.stopChainedTweens(); } if (!this._isPlaying) { return this; } this._isPlaying = false; this._isPaused = false; if (this._onStopCallback) { this._onStopCallback(this._object); } return this; }; Tween2.prototype.end = function() { this._goToEnd = true; this.update(this._startTime + this._duration); return this; }; Tween2.prototype.pause = function(time) { if (time === void 0) { time = now4(); } if (this._isPaused || !this._isPlaying) { return this; } this._isPaused = true; this._pauseStart = time; return this; }; Tween2.prototype.resume = function(time) { if (time === void 0) { time = now4(); } if (!this._isPaused || !this._isPlaying) { return this; } this._isPaused = false; this._startTime += time - this._pauseStart; this._pauseStart = 0; return this; }; Tween2.prototype.stopChainedTweens = function() { for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { this._chainedTweens[i].stop(); } return this; }; Tween2.prototype.group = function(group) { if (!group) { console.warn("tween.group() without args has been removed, use group.add(tween) instead."); return this; } group.add(this); return this; }; Tween2.prototype.remove = function() { var _a; (_a = this._group) === null || _a === void 0 ? void 0 : _a.remove(this); return this; }; Tween2.prototype.delay = function(amount) { if (amount === void 0) { amount = 0; } this._delayTime = amount; return this; }; Tween2.prototype.repeat = function(times) { if (times === void 0) { times = 0; } this._initialRepeat = times; this._repeat = times; return this; }; Tween2.prototype.repeatDelay = function(amount) { this._repeatDelayTime = amount; return this; }; Tween2.prototype.yoyo = function(yoyo) { if (yoyo === void 0) { yoyo = false; } this._yoyo = yoyo; return this; }; Tween2.prototype.easing = function(easingFunction) { if (easingFunction === void 0) { easingFunction = Easing.Linear.None; } this._easingFunction = easingFunction; return this; }; Tween2.prototype.interpolation = function(interpolationFunction) { if (interpolationFunction === void 0) { interpolationFunction = Interpolation.Linear; } this._interpolationFunction = interpolationFunction; return this; }; Tween2.prototype.chain = function() { var tweens = []; for (var _i = 0; _i < arguments.length; _i++) { tweens[_i] = arguments[_i]; } this._chainedTweens = tweens; return this; }; Tween2.prototype.onStart = function(callback) { this._onStartCallback = callback; return this; }; Tween2.prototype.onEveryStart = function(callback) { this._onEveryStartCallback = callback; return this; }; Tween2.prototype.onUpdate = function(callback) { this._onUpdateCallback = callback; return this; }; Tween2.prototype.onRepeat = function(callback) { this._onRepeatCallback = callback; return this; }; Tween2.prototype.onComplete = function(callback) { this._onCompleteCallback = callback; return this; }; Tween2.prototype.onStop = function(callback) { this._onStopCallback = callback; return this; }; Tween2.prototype.update = function(time, autoStart) { var _this = this; var _a; if (time === void 0) { time = now4(); } if (autoStart === void 0) { autoStart = Tween2.autoStartOnUpdate; } if (this._isPaused) return true; var property2; if (!this._goToEnd && !this._isPlaying) { if (autoStart) this.start(time, true); else return false; } this._goToEnd = false; if (time < this._startTime) { return true; } if (this._onStartCallbackFired === false) { if (this._onStartCallback) { this._onStartCallback(this._object); } this._onStartCallbackFired = true; } if (this._onEveryStartCallbackFired === false) { if (this._onEveryStartCallback) { this._onEveryStartCallback(this._object); } this._onEveryStartCallbackFired = true; } var elapsedTime = time - this._startTime; var durationAndDelay = this._duration + ((_a = this._repeatDelayTime) !== null && _a !== void 0 ? _a : this._delayTime); var totalTime = this._duration + this._repeat * durationAndDelay; var calculateElapsedPortion = function() { if (_this._duration === 0) return 1; if (elapsedTime > totalTime) { return 1; } var timesRepeated = Math.trunc(elapsedTime / durationAndDelay); var timeIntoCurrentRepeat = elapsedTime - timesRepeated * durationAndDelay; var portion = Math.min(timeIntoCurrentRepeat / _this._duration, 1); if (portion === 0 && elapsedTime === _this._duration) { return 1; } return portion; }; var elapsed = calculateElapsedPortion(); var value = this._easingFunction(elapsed); this._updateProperties(this._object, this._valuesStart, this._valuesEnd, value); if (this._onUpdateCallback) { this._onUpdateCallback(this._object, elapsed); } if (this._duration === 0 || elapsedTime >= this._duration) { if (this._repeat > 0) { var completeCount = Math.min(Math.trunc((elapsedTime - this._duration) / durationAndDelay) + 1, this._repeat); if (isFinite(this._repeat)) { this._repeat -= completeCount; } for (property2 in this._valuesStartRepeat) { if (!this._yoyo && typeof this._valuesEnd[property2] === "string") { this._valuesStartRepeat[property2] = // eslint-disable-next-line // @ts-ignore FIXME? this._valuesStartRepeat[property2] + parseFloat(this._valuesEnd[property2]); } if (this._yoyo) { this._swapEndStartRepeatValues(property2); } this._valuesStart[property2] = this._valuesStartRepeat[property2]; } if (this._yoyo) { this._reversed = !this._reversed; } this._startTime += durationAndDelay * completeCount; if (this._onRepeatCallback) { this._onRepeatCallback(this._object); } this._onEveryStartCallbackFired = false; return true; } else { if (this._onCompleteCallback) { this._onCompleteCallback(this._object); } for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { this._chainedTweens[i].start(this._startTime + this._duration, false); } this._isPlaying = false; return false; } } return true; }; Tween2.prototype._updateProperties = function(_object, _valuesStart, _valuesEnd, value) { for (var property2 in _valuesEnd) { if (_valuesStart[property2] === void 0) { continue; } var start = _valuesStart[property2] || 0; var end = _valuesEnd[property2]; var startIsArray = Array.isArray(_object[property2]); var endIsArray = Array.isArray(end); var isInterpolationList = !startIsArray && endIsArray; if (isInterpolationList) { _object[property2] = this._interpolationFunction(end, value); } else if (typeof end === "object" && end) { this._updateProperties(_object[property2], start, end, value); } else { end = this._handleRelativeValue(start, end); if (typeof end === "number") { _object[property2] = start + (end - start) * value; } } } }; Tween2.prototype._handleRelativeValue = function(start, end) { if (typeof end !== "string") { return end; } if (end.charAt(0) === "+" || end.charAt(0) === "-") { return start + parseFloat(end); } return parseFloat(end); }; Tween2.prototype._swapEndStartRepeatValues = function(property2) { var tmp2 = this._valuesStartRepeat[property2]; var endValue = this._valuesEnd[property2]; if (typeof endValue === "string") { this._valuesStartRepeat[property2] = this._valuesStartRepeat[property2] + parseFloat(endValue); } else { this._valuesStartRepeat[property2] = this._valuesEnd[property2]; } this._valuesEnd[property2] = tmp2; }; Tween2.autoStartOnUpdate = false; return Tween2; }() ); var nextId = Sequence.nextId; var TWEEN = mainGroup; var getAll = TWEEN.getAll.bind(TWEEN); var removeAll4 = TWEEN.removeAll.bind(TWEEN); var add5 = TWEEN.add.bind(TWEEN); var remove = TWEEN.remove.bind(TWEEN); var update2 = TWEEN.update.bind(TWEEN); // ../../node_modules/three-render-objects/dist/three-render-objects.mjs function styleInject(css, ref) { if (ref === void 0) ref = {}; var insertAt = ref.insertAt; if (typeof document === "undefined") { return; } var head = document.head || document.getElementsByTagName("head")[0]; var style = document.createElement("style"); style.type = "text/css"; if (insertAt === "top") { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z = ".scene-nav-info {\n bottom: 5px;\n width: 100%;\n text-align: center;\n color: slategrey;\n opacity: 0.7;\n font-size: 10px;\n}\n\n.scene-tooltip {\n top: 0;\n color: lavender;\n font-size: 15px;\n}\n\n.scene-nav-info, .scene-tooltip {\n position: absolute;\n font-family: sans-serif;\n pointer-events: none;\n user-select: none;\n}\n\n.scene-container canvas:focus {\n outline: none;\n}"; styleInject(css_248z); function _arrayLikeToArray5(r, a2) { (null == a2 || a2 > r.length) && (a2 = r.length); for (var e = 0, n = Array(a2); e < a2; e++) n[e] = r[e]; return n; } function _arrayWithHoles5(r) { if (Array.isArray(r)) return r; } function _arrayWithoutHoles4(r) { if (Array.isArray(r)) return _arrayLikeToArray5(r); } function _defineProperty3(e, r, t) { return (r = _toPropertyKey4(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e; } function _iterableToArray4(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _iterableToArrayLimit5(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a2 = [], f = true, o = false; try { if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a2.push(e.value), a2.length !== l); f = true) ; } catch (r2) { o = true, n = r2; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a2; } } function _nonIterableRest5() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableSpread4() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _slicedToArray5(r, e) { return _arrayWithHoles5(r) || _iterableToArrayLimit5(r, e) || _unsupportedIterableToArray5(r, e) || _nonIterableRest5(); } function _toConsumableArray4(r) { return _arrayWithoutHoles4(r) || _iterableToArray4(r) || _unsupportedIterableToArray5(r) || _nonIterableSpread4(); } function _toPrimitive4(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _toPropertyKey4(t) { var i = _toPrimitive4(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _unsupportedIterableToArray5(r, a2) { if (r) { if ("string" == typeof r) return _arrayLikeToArray5(r, a2); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray5(r, a2) : void 0; } } var three2 = window.THREE ? window.THREE : { WebGLRenderer, Scene, PerspectiveCamera, Raycaster, SRGBColorSpace, TextureLoader, Vector2, Vector3, Box3, Color, Mesh, SphereGeometry, MeshBasicMaterial, BackSide, EventDispatcher, MOUSE, Quaternion, Spherical, Clock }; var threeRenderObjects = index2({ props: { width: { "default": window.innerWidth, onChange: function onChange8(width, state, prevWidth) { isNaN(width) && (state.width = prevWidth); } }, height: { "default": window.innerHeight, onChange: function onChange9(height, state, prevHeight) { isNaN(height) && (state.height = prevHeight); } }, backgroundColor: { "default": "#000011" }, backgroundImageUrl: {}, onBackgroundImageLoaded: {}, showNavInfo: { "default": true }, skyRadius: { "default": 5e4 }, objects: { "default": [] }, lights: { "default": [] }, enablePointerInteraction: { "default": true, onChange: function onChange10(_, state) { state.hoverObj = null; if (state.toolTipElem) state.toolTipElem.innerHTML = ""; }, triggerUpdate: false }, lineHoverPrecision: { "default": 1, triggerUpdate: false }, hoverOrderComparator: { "default": function _default8() { return -1; }, triggerUpdate: false }, // keep existing order by default hoverFilter: { "default": function _default9() { return true; }, triggerUpdate: false }, // exclude objects from interaction tooltipContent: { triggerUpdate: false }, hoverDuringDrag: { "default": false, triggerUpdate: false }, clickAfterDrag: { "default": false, triggerUpdate: false }, onHover: { "default": function _default10() { }, triggerUpdate: false }, onClick: { "default": function _default11() { }, triggerUpdate: false }, onRightClick: { triggerUpdate: false } }, methods: { tick: function tick(state) { if (state.initialised) { state.controls.update && state.controls.update(Math.min(1, state.clock.getDelta())); state.postProcessingComposer ? state.postProcessingComposer.render() : state.renderer.render(state.scene, state.camera); state.extraRenderers.forEach(function(r) { return r.render(state.scene, state.camera); }); if (state.enablePointerInteraction) { var topObject = null; if (state.hoverDuringDrag || !state.isPointerDragging) { var intersects = this.intersectingObjects(state.pointerPos.x, state.pointerPos.y).filter(function(d) { return state.hoverFilter(d.object); }).sort(function(a2, b) { return state.hoverOrderComparator(a2.object, b.object); }); var topIntersect = intersects.length ? intersects[0] : null; topObject = topIntersect ? topIntersect.object : null; state.intersectionPoint = topIntersect ? topIntersect.point : null; } if (topObject !== state.hoverObj) { state.onHover(topObject, state.hoverObj); state.toolTipElem.innerHTML = topObject ? index3(state.tooltipContent)(topObject) || "" : ""; state.hoverObj = topObject; } } state.tweenGroup.update(); } return this; }, getPointerPos: function getPointerPos(state) { var _state$pointerPos = state.pointerPos, x2 = _state$pointerPos.x, y2 = _state$pointerPos.y; return { x: x2, y: y2 }; }, cameraPosition: function cameraPosition2(state, position, lookAt, transitionDuration) { var camera3 = state.camera; if (position && state.initialised) { var finalPos = position; var finalLookAt = lookAt || { x: 0, y: 0, z: 0 }; if (!transitionDuration) { setCameraPos(finalPos); setLookAt(finalLookAt); } else { var camPos = Object.assign({}, camera3.position); var camLookAt = getLookAt(); state.tweenGroup.add(new Tween(camPos).to(finalPos, transitionDuration).easing(Easing.Quadratic.Out).onUpdate(setCameraPos).start()); state.tweenGroup.add(new Tween(camLookAt).to(finalLookAt, transitionDuration / 3).easing(Easing.Quadratic.Out).onUpdate(setLookAt).start()); } return this; } return Object.assign({}, camera3.position, { lookAt: getLookAt() }); function setCameraPos(pos) { var x2 = pos.x, y2 = pos.y, z2 = pos.z; if (x2 !== void 0) camera3.position.x = x2; if (y2 !== void 0) camera3.position.y = y2; if (z2 !== void 0) camera3.position.z = z2; } function setLookAt(lookAt2) { var lookAtVect = new three2.Vector3(lookAt2.x, lookAt2.y, lookAt2.z); if (state.controls.target) { state.controls.target = lookAtVect; } else { camera3.lookAt(lookAtVect); } } function getLookAt() { return Object.assign(new three2.Vector3(0, 0, -1e3).applyQuaternion(camera3.quaternion).add(camera3.position)); } }, zoomToFit: function zoomToFit(state) { var transitionDuration = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0; var padding = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 10; for (var _len = arguments.length, bboxArgs = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) { bboxArgs[_key - 3] = arguments[_key]; } return this.fitToBbox(this.getBbox.apply(this, bboxArgs), transitionDuration, padding); }, fitToBbox: function fitToBbox(state, bbox) { var transitionDuration = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 0; var padding = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : 10; var camera3 = state.camera; if (bbox) { var center = new three2.Vector3(0, 0, 0); var maxBoxSide = Math.max.apply(Math, _toConsumableArray4(Object.entries(bbox).map(function(_ref) { var _ref2 = _slicedToArray5(_ref, 2), coordType = _ref2[0], coords = _ref2[1]; return Math.max.apply(Math, _toConsumableArray4(coords.map(function(c2) { return Math.abs(center[coordType] - c2); }))); }))) * 2; var paddedFov = (1 - padding * 2 / state.height) * camera3.fov; var fitHeightDistance = maxBoxSide / Math.atan(paddedFov * Math.PI / 180); var fitWidthDistance = fitHeightDistance / camera3.aspect; var distance2 = Math.max(fitHeightDistance, fitWidthDistance); if (distance2 > 0) { var newCameraPosition = center.clone().sub(camera3.position).normalize().multiplyScalar(-distance2); this.cameraPosition(newCameraPosition, center, transitionDuration); } } return this; }, getBbox: function getBbox(state) { var objFilter = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : function() { return true; }; var box = new three2.Box3(new three2.Vector3(0, 0, 0), new three2.Vector3(0, 0, 0)); var objs = state.objects.filter(objFilter); if (!objs.length) return null; objs.forEach(function(obj) { return box.expandByObject(obj); }); return Object.assign.apply(Object, _toConsumableArray4(["x", "y", "z"].map(function(c2) { return _defineProperty3({}, c2, [box.min[c2], box.max[c2]]); }))); }, getScreenCoords: function getScreenCoords(state, x2, y2, z2) { var vec = new three2.Vector3(x2, y2, z2); vec.project(this.camera()); return { // align relative pos to canvas dimensions x: (vec.x + 1) * state.width / 2, y: -(vec.y - 1) * state.height / 2 }; }, getSceneCoords: function getSceneCoords(state, screenX, screenY) { var distance2 = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : 0; var relCoords = new three2.Vector2(screenX / state.width * 2 - 1, -(screenY / state.height) * 2 + 1); var raycaster = new three2.Raycaster(); raycaster.setFromCamera(relCoords, state.camera); return Object.assign({}, raycaster.ray.at(distance2, new three2.Vector3())); }, intersectingObjects: function intersectingObjects(state, x2, y2) { var relCoords = new three2.Vector2(x2 / state.width * 2 - 1, -(y2 / state.height) * 2 + 1); var raycaster = new three2.Raycaster(); raycaster.params.Line.threshold = state.lineHoverPrecision; raycaster.setFromCamera(relCoords, state.camera); return raycaster.intersectObjects(state.objects, true); }, renderer: function renderer(state) { return state.renderer; }, scene: function scene(state) { return state.scene; }, camera: function camera(state) { return state.camera; }, postProcessingComposer: function postProcessingComposer(state) { return state.postProcessingComposer; }, controls: function controls(state) { return state.controls; }, tbControls: function tbControls(state) { return state.controls; } // to be deprecated }, stateInit: function stateInit2() { return { scene: new three2.Scene(), camera: new three2.PerspectiveCamera(), clock: new three2.Clock(), tweenGroup: new Group2() }; }, init: function init2(domNode, state) { var _ref4 = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}, _ref4$controlType = _ref4.controlType, controlType = _ref4$controlType === void 0 ? "trackball" : _ref4$controlType, _ref4$useWebGPU = _ref4.useWebGPU, useWebGPU = _ref4$useWebGPU === void 0 ? false : _ref4$useWebGPU, _ref4$rendererConfig = _ref4.rendererConfig, rendererConfig = _ref4$rendererConfig === void 0 ? {} : _ref4$rendererConfig, _ref4$extraRenderers = _ref4.extraRenderers, extraRenderers = _ref4$extraRenderers === void 0 ? [] : _ref4$extraRenderers, _ref4$waitForLoadComp = _ref4.waitForLoadComplete, waitForLoadComplete = _ref4$waitForLoadComp === void 0 ? true : _ref4$waitForLoadComp; domNode.innerHTML = ""; domNode.appendChild(state.container = document.createElement("div")); state.container.className = "scene-container"; state.container.style.position = "relative"; state.container.appendChild(state.navInfo = document.createElement("div")); state.navInfo.className = "scene-nav-info"; state.navInfo.textContent = { orbit: "Left-click: rotate, Mouse-wheel/middle-click: zoom, Right-click: pan", trackball: "Left-click: rotate, Mouse-wheel/middle-click: zoom, Right-click: pan", fly: "WASD: move, R|F: up | down, Q|E: roll, up|down: pitch, left|right: yaw" }[controlType] || ""; state.navInfo.style.display = state.showNavInfo ? null : "none"; state.toolTipElem = document.createElement("div"); state.toolTipElem.classList.add("scene-tooltip"); state.container.appendChild(state.toolTipElem); state.pointerPos = new three2.Vector2(); state.pointerPos.x = -2; state.pointerPos.y = -2; ["pointermove", "pointerdown"].forEach(function(evType) { return state.container.addEventListener(evType, function(ev) { evType === "pointerdown" && (state.isPointerPressed = true); !state.isPointerDragging && ev.type === "pointermove" && (ev.pressure > 0 || state.isPointerPressed) && (ev.pointerType !== "touch" || ev.movementX === void 0 || [ev.movementX, ev.movementY].some(function(m2) { return Math.abs(m2) > 1; })) && (state.isPointerDragging = true); if (state.enablePointerInteraction) { var offset = getOffset(state.container); state.pointerPos.x = ev.pageX - offset.left; state.pointerPos.y = ev.pageY - offset.top; state.toolTipElem.style.top = "".concat(state.pointerPos.y, "px"); state.toolTipElem.style.left = "".concat(state.pointerPos.x, "px"); state.toolTipElem.style.transform = "translate(-".concat(state.pointerPos.x / state.width * 100, "%, ").concat( // flip to above if near bottom state.height - state.pointerPos.y < 100 ? "calc(-100% - 8px)" : "21px", ")" ); } function getOffset(el) { var rect = el.getBoundingClientRect(), scrollLeft = window.pageXOffset || document.documentElement.scrollLeft, scrollTop = window.pageYOffset || document.documentElement.scrollTop; return { top: rect.top + scrollTop, left: rect.left + scrollLeft }; } }, { passive: true }); }); state.container.addEventListener("pointerup", function(ev) { state.isPointerPressed = false; if (state.isPointerDragging) { state.isPointerDragging = false; if (!state.clickAfterDrag) return; } requestAnimationFrame(function() { if (ev.button === 0) { state.onClick(state.hoverObj || null, ev, state.intersectionPoint); } if (ev.button === 2 && state.onRightClick) { state.onRightClick(state.hoverObj || null, ev, state.intersectionPoint); } }); }, { passive: true, capture: true }); state.container.addEventListener("contextmenu", function(ev) { if (state.onRightClick) ev.preventDefault(); }); state.renderer = new (useWebGPU ? WebGPURenderer : three2.WebGLRenderer)(Object.assign({ antialias: true, alpha: true }, rendererConfig)); state.renderer.setPixelRatio(Math.min(2, window.devicePixelRatio)); state.container.appendChild(state.renderer.domElement); state.extraRenderers = extraRenderers; state.extraRenderers.forEach(function(r) { r.domElement.style.position = "absolute"; r.domElement.style.top = "0px"; r.domElement.style.pointerEvents = "none"; state.container.appendChild(r.domElement); }); state.postProcessingComposer = new EffectComposer(state.renderer); state.postProcessingComposer.addPass(new RenderPass(state.scene, state.camera)); state.controls = new { trackball: TrackballControls, orbit: OrbitControls, fly: FlyControls }[controlType](state.camera, state.renderer.domElement); if (controlType === "fly") { state.controls.movementSpeed = 300; state.controls.rollSpeed = Math.PI / 6; state.controls.dragToLook = true; } if (controlType === "trackball" || controlType === "orbit") { state.controls.minDistance = 0.1; state.controls.maxDistance = state.skyRadius; state.controls.addEventListener("start", function() { state.controlsEngaged = true; }); state.controls.addEventListener("change", function() { if (state.controlsEngaged) { state.controlsDragging = true; } }); state.controls.addEventListener("end", function() { state.controlsEngaged = false; state.controlsDragging = false; }); } [state.renderer, state.postProcessingComposer].concat(_toConsumableArray4(state.extraRenderers)).forEach(function(r) { return r.setSize(state.width, state.height); }); state.camera.aspect = state.width / state.height; state.camera.updateProjectionMatrix(); state.camera.position.z = 1e3; state.scene.add(state.skysphere = new three2.Mesh()); state.skysphere.visible = false; state.loadComplete = state.scene.visible = !waitForLoadComplete; window.scene = state.scene; }, update: function update3(state, changedProps) { if (state.width && state.height && (changedProps.hasOwnProperty("width") || changedProps.hasOwnProperty("height"))) { state.container.style.width = "".concat(state.width, "px"); state.container.style.height = "".concat(state.height, "px"); [state.renderer, state.postProcessingComposer].concat(_toConsumableArray4(state.extraRenderers)).forEach(function(r) { return r.setSize(state.width, state.height); }); state.camera.aspect = state.width / state.height; state.camera.updateProjectionMatrix(); } if (changedProps.hasOwnProperty("skyRadius") && state.skyRadius) { state.controls.hasOwnProperty("maxDistance") && changedProps.skyRadius && (state.controls.maxDistance = Math.min(state.controls.maxDistance, state.skyRadius)); state.camera.far = state.skyRadius * 2.5; state.camera.updateProjectionMatrix(); state.skysphere.geometry = new three2.SphereGeometry(state.skyRadius); } if (changedProps.hasOwnProperty("backgroundColor")) { var alpha = parseToRgb(state.backgroundColor).alpha; if (alpha === void 0) alpha = 1; state.renderer.setClearColor(new three2.Color(curriedOpacify$1(1, state.backgroundColor)), alpha); } if (changedProps.hasOwnProperty("backgroundImageUrl")) { if (!state.backgroundImageUrl) { state.skysphere.visible = false; state.skysphere.material.map = null; !state.loadComplete && finishLoad(); } else { new three2.TextureLoader().load(state.backgroundImageUrl, function(texture2) { texture2.colorSpace = three2.SRGBColorSpace; state.skysphere.material = new three2.MeshBasicMaterial({ map: texture2, side: three2.BackSide }); state.skysphere.visible = true; state.onBackgroundImageLoaded && setTimeout(state.onBackgroundImageLoaded); !state.loadComplete && finishLoad(); }); } } changedProps.hasOwnProperty("showNavInfo") && (state.navInfo.style.display = state.showNavInfo ? null : "none"); if (changedProps.hasOwnProperty("lights")) { (changedProps.lights || []).forEach(function(light) { return state.scene.remove(light); }); state.lights.forEach(function(light) { return state.scene.add(light); }); } if (changedProps.hasOwnProperty("objects")) { (changedProps.objects || []).forEach(function(obj) { return state.scene.remove(obj); }); state.objects.forEach(function(obj) { return state.scene.add(obj); }); } function finishLoad() { state.loadComplete = state.scene.visible = true; } } }); // ../../node_modules/3d-force-graph/dist/3d-force-graph.mjs function styleInject2(css, ref) { if (ref === void 0) ref = {}; var insertAt = ref.insertAt; if (typeof document === "undefined") { return; } var head = document.head || document.getElementsByTagName("head")[0]; var style = document.createElement("style"); style.type = "text/css"; if (insertAt === "top") { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z2 = ".graph-info-msg {\n top: 50%;\n width: 100%;\n text-align: center;\n color: lavender;\n opacity: 0.7;\n font-size: 22px;\n position: absolute;\n font-family: Sans-serif;\n}\n\n.scene-container .clickable {\n cursor: pointer;\n}\n\n.scene-container .grabbable {\n cursor: move;\n cursor: grab;\n cursor: -moz-grab;\n cursor: -webkit-grab;\n}\n\n.scene-container .grabbable:active {\n cursor: grabbing;\n cursor: -moz-grabbing;\n cursor: -webkit-grabbing;\n}"; styleInject2(css_248z2); function _arrayLikeToArray6(r, a2) { (null == a2 || a2 > r.length) && (a2 = r.length); for (var e = 0, n = Array(a2); e < a2; e++) n[e] = r[e]; return n; } function _arrayWithoutHoles5(r) { if (Array.isArray(r)) return _arrayLikeToArray6(r); } function _defineProperty4(e, r, t) { return (r = _toPropertyKey5(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e; } function _iterableToArray5(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _nonIterableSpread5() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function ownKeys3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function(r2) { return Object.getOwnPropertyDescriptor(e, r2).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread23(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys3(Object(t), true).forEach(function(r2) { _defineProperty4(e, r2, t[r2]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys3(Object(t)).forEach(function(r2) { Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2)); }); } return e; } function _toConsumableArray5(r) { return _arrayWithoutHoles5(r) || _iterableToArray5(r) || _unsupportedIterableToArray6(r) || _nonIterableSpread5(); } function _toPrimitive5(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _toPropertyKey5(t) { var i = _toPrimitive5(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _unsupportedIterableToArray6(r, a2) { if (r) { if ("string" == typeof r) return _arrayLikeToArray6(r, a2); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray6(r, a2) : void 0; } } function linkKapsule(kapsulePropName, kapsuleType) { var dummyK = new kapsuleType(); dummyK._destructor && dummyK._destructor(); return { linkProp: function linkProp(prop) { return { "default": dummyK[prop](), onChange: function onChange13(v, state) { state[kapsulePropName][prop](v); }, triggerUpdate: false }; }, linkMethod: function linkMethod(method) { return function(state) { var kapsuleInstance = state[kapsulePropName]; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } var returnVal = kapsuleInstance[method].apply(kapsuleInstance, args); return returnVal === kapsuleInstance ? this : returnVal; }; } }; } var three3 = window.THREE ? window.THREE : { AmbientLight, DirectionalLight, Vector3, REVISION }; var CAMERA_DISTANCE2NODES_FACTOR = 170; var bindFG = linkKapsule("forceGraph", threeForcegraph); var linkedFGProps = Object.assign.apply(Object, _toConsumableArray5(["jsonUrl", "graphData", "numDimensions", "dagMode", "dagLevelDistance", "dagNodeFilter", "onDagError", "nodeRelSize", "nodeId", "nodeVal", "nodeResolution", "nodeColor", "nodeAutoColorBy", "nodeOpacity", "nodeVisibility", "nodeThreeObject", "nodeThreeObjectExtend", "linkSource", "linkTarget", "linkVisibility", "linkColor", "linkAutoColorBy", "linkOpacity", "linkWidth", "linkResolution", "linkCurvature", "linkCurveRotation", "linkMaterial", "linkThreeObject", "linkThreeObjectExtend", "linkPositionUpdate", "linkDirectionalArrowLength", "linkDirectionalArrowColor", "linkDirectionalArrowRelPos", "linkDirectionalArrowResolution", "linkDirectionalParticles", "linkDirectionalParticleSpeed", "linkDirectionalParticleWidth", "linkDirectionalParticleColor", "linkDirectionalParticleResolution", "forceEngine", "d3AlphaDecay", "d3VelocityDecay", "d3AlphaMin", "ngraphPhysics", "warmupTicks", "cooldownTicks", "cooldownTime", "onEngineTick", "onEngineStop"].map(function(p) { return _defineProperty4({}, p, bindFG.linkProp(p)); }))); var linkedFGMethods = Object.assign.apply(Object, _toConsumableArray5(["refresh", "getGraphBbox", "d3Force", "d3ReheatSimulation", "emitParticle"].map(function(p) { return _defineProperty4({}, p, bindFG.linkMethod(p)); }))); var bindRenderObjs = linkKapsule("renderObjs", threeRenderObjects); var linkedRenderObjsProps = Object.assign.apply(Object, _toConsumableArray5(["width", "height", "backgroundColor", "showNavInfo", "enablePointerInteraction"].map(function(p) { return _defineProperty4({}, p, bindRenderObjs.linkProp(p)); }))); var linkedRenderObjsMethods = Object.assign.apply(Object, _toConsumableArray5(["lights", "cameraPosition", "postProcessingComposer"].map(function(p) { return _defineProperty4({}, p, bindRenderObjs.linkMethod(p)); })).concat([{ graph2ScreenCoords: bindRenderObjs.linkMethod("getScreenCoords"), screen2GraphCoords: bindRenderObjs.linkMethod("getSceneCoords") }])); var _3dForceGraph = index2({ props: _objectSpread23(_objectSpread23({ nodeLabel: { "default": "name", triggerUpdate: false }, linkLabel: { "default": "name", triggerUpdate: false }, linkHoverPrecision: { "default": 1, onChange: function onChange11(p, state) { return state.renderObjs.lineHoverPrecision(p); }, triggerUpdate: false }, enableNavigationControls: { "default": true, onChange: function onChange12(enable, state) { var controls3 = state.renderObjs.controls(); if (controls3) { controls3.enabled = enable; enable && controls3.domElement && controls3.domElement.dispatchEvent(new PointerEvent("pointerup")); } }, triggerUpdate: false }, enableNodeDrag: { "default": true, triggerUpdate: false }, onNodeDrag: { "default": function _default12() { }, triggerUpdate: false }, onNodeDragEnd: { "default": function _default13() { }, triggerUpdate: false }, onNodeClick: { triggerUpdate: false }, onNodeRightClick: { triggerUpdate: false }, onNodeHover: { triggerUpdate: false }, onLinkClick: { triggerUpdate: false }, onLinkRightClick: { triggerUpdate: false }, onLinkHover: { triggerUpdate: false }, onBackgroundClick: { triggerUpdate: false }, onBackgroundRightClick: { triggerUpdate: false } }, linkedFGProps), linkedRenderObjsProps), methods: _objectSpread23(_objectSpread23({ zoomToFit: function zoomToFit2(state, transitionDuration, padding) { var _state$forceGraph; for (var _len = arguments.length, bboxArgs = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) { bboxArgs[_key - 3] = arguments[_key]; } state.renderObjs.fitToBbox((_state$forceGraph = state.forceGraph).getGraphBbox.apply(_state$forceGraph, bboxArgs), transitionDuration, padding); return this; }, pauseAnimation: function pauseAnimation(state) { if (state.animationFrameRequestId !== null) { cancelAnimationFrame(state.animationFrameRequestId); state.animationFrameRequestId = null; } return this; }, resumeAnimation: function resumeAnimation(state) { if (state.animationFrameRequestId === null) { this._animationCycle(); } return this; }, _animationCycle: function _animationCycle(state) { if (state.enablePointerInteraction) { this.renderer().domElement.style.cursor = null; } state.forceGraph.tickFrame(); state.renderObjs.tick(); state.animationFrameRequestId = requestAnimationFrame(this._animationCycle); }, scene: function scene2(state) { return state.renderObjs.scene(); }, // Expose scene camera: function camera2(state) { return state.renderObjs.camera(); }, // Expose camera renderer: function renderer2(state) { return state.renderObjs.renderer(); }, // Expose renderer controls: function controls2(state) { return state.renderObjs.controls(); }, // Expose controls tbControls: function tbControls2(state) { return state.renderObjs.tbControls(); }, // To be deprecated _destructor: function _destructor() { this.pauseAnimation(); this.graphData({ nodes: [], links: [] }); } }, linkedFGMethods), linkedRenderObjsMethods), stateInit: function stateInit3(_ref5) { var controlType = _ref5.controlType, rendererConfig = _ref5.rendererConfig, extraRenderers = _ref5.extraRenderers; var forceGraph = new threeForcegraph(); return { forceGraph, renderObjs: threeRenderObjects({ controlType, rendererConfig, extraRenderers }).objects([forceGraph]).lights([new three3.AmbientLight(13421772, Math.PI), new three3.DirectionalLight(16777215, 0.6 * Math.PI)]) }; }, init: function init3(domNode, state) { domNode.innerHTML = ""; domNode.appendChild(state.container = document.createElement("div")); state.container.style.position = "relative"; var roDomNode = document.createElement("div"); state.container.appendChild(roDomNode); state.renderObjs(roDomNode); var camera3 = state.renderObjs.camera(); var renderer3 = state.renderObjs.renderer(); var controls3 = state.renderObjs.controls(); controls3.enabled = !!state.enableNavigationControls; state.lastSetCameraZ = camera3.position.z; var infoElem; state.container.appendChild(infoElem = document.createElement("div")); infoElem.className = "graph-info-msg"; infoElem.textContent = ""; state.forceGraph.onLoading(function() { infoElem.textContent = "Loading..."; }).onFinishLoading(function() { infoElem.textContent = ""; }).onUpdate(function() { state.graphData = state.forceGraph.graphData(); if (camera3.position.x === 0 && camera3.position.y === 0 && camera3.position.z === state.lastSetCameraZ && state.graphData.nodes.length) { camera3.lookAt(state.forceGraph.position); state.lastSetCameraZ = camera3.position.z = Math.cbrt(state.graphData.nodes.length) * CAMERA_DISTANCE2NODES_FACTOR; } }).onFinishUpdate(function() { if (state._dragControls) { var curNodeDrag = state.graphData.nodes.find(function(node) { return node.__initialFixedPos && !node.__disposeControlsAfterDrag; }); if (curNodeDrag) { curNodeDrag.__disposeControlsAfterDrag = true; } else { state._dragControls.dispose(); } state._dragControls = void 0; } if (state.enableNodeDrag && state.enablePointerInteraction && state.forceEngine === "d3") { var dragControls = state._dragControls = new DragControls(state.graphData.nodes.map(function(node) { return node.__threeObj; }).filter(function(obj) { return obj; }), camera3, renderer3.domElement); dragControls.addEventListener("dragstart", function(event) { controls3.enabled = false; event.object.__initialPos = event.object.position.clone(); event.object.__prevPos = event.object.position.clone(); var node = getGraphObj(event.object).__data; !node.__initialFixedPos && (node.__initialFixedPos = { fx: node.fx, fy: node.fy, fz: node.fz }); !node.__initialPos && (node.__initialPos = { x: node.x, y: node.y, z: node.z }); ["x", "y", "z"].forEach(function(c2) { return node["f".concat(c2)] = node[c2]; }); renderer3.domElement.classList.add("grabbable"); }); dragControls.addEventListener("drag", function(event) { var nodeObj = getGraphObj(event.object); if (!event.object.hasOwnProperty("__graphObjType")) { var initPos = event.object.__initialPos; var prevPos = event.object.__prevPos; var _newPos = event.object.position; nodeObj.position.add(_newPos.clone().sub(prevPos)); prevPos.copy(_newPos); _newPos.copy(initPos); } var node = nodeObj.__data; var newPos = nodeObj.position; var translate = { x: newPos.x - node.x, y: newPos.y - node.y, z: newPos.z - node.z }; ["x", "y", "z"].forEach(function(c2) { return node["f".concat(c2)] = node[c2] = newPos[c2]; }); state.forceGraph.d3AlphaTarget(0.3).resetCountdown(); node.__dragged = true; state.onNodeDrag(node, translate); }); dragControls.addEventListener("dragend", function(event) { delete event.object.__initialPos; delete event.object.__prevPos; var node = getGraphObj(event.object).__data; if (node.__disposeControlsAfterDrag) { dragControls.dispose(); delete node.__disposeControlsAfterDrag; } var initFixedPos = node.__initialFixedPos; var initPos = node.__initialPos; var translate = { x: initPos.x - node.x, y: initPos.y - node.y, z: initPos.z - node.z }; if (initFixedPos) { ["x", "y", "z"].forEach(function(c2) { var fc = "f".concat(c2); if (initFixedPos[fc] === void 0) { delete node[fc]; } }); delete node.__initialFixedPos; delete node.__initialPos; if (node.__dragged) { delete node.__dragged; state.onNodeDragEnd(node, translate); } } state.forceGraph.d3AlphaTarget(0).resetCountdown(); if (state.enableNavigationControls) { controls3.enabled = true; controls3.domElement && controls3.domElement.ownerDocument && controls3.domElement.ownerDocument.dispatchEvent( // simulate mouseup to ensure the controls don't take over after dragend new PointerEvent("pointerup", { pointerType: "touch" }) ); } renderer3.domElement.classList.remove("grabbable"); }); } }); three3.REVISION < 155 && (state.renderObjs.renderer().useLegacyLights = false); state.renderObjs.hoverOrderComparator(function(a2, b) { var aObj = getGraphObj(a2); if (!aObj) return 1; var bObj = getGraphObj(b); if (!bObj) return -1; var isNode = function isNode2(o) { return o.__graphObjType === "node"; }; return isNode(bObj) - isNode(aObj); }).tooltipContent(function(obj) { var graphObj = getGraphObj(obj); return graphObj ? index3(state["".concat(graphObj.__graphObjType, "Label")])(graphObj.__data) || "" : ""; }).hoverDuringDrag(false).onHover(function(obj) { var hoverObj = getGraphObj(obj); if (hoverObj !== state.hoverObj) { var prevObjType = state.hoverObj ? state.hoverObj.__graphObjType : null; var prevObjData = state.hoverObj ? state.hoverObj.__data : null; var objType = hoverObj ? hoverObj.__graphObjType : null; var objData = hoverObj ? hoverObj.__data : null; if (prevObjType && prevObjType !== objType) { var fn = state["on".concat(prevObjType === "node" ? "Node" : "Link", "Hover")]; fn && fn(null, prevObjData); } if (objType) { var _fn = state["on".concat(objType === "node" ? "Node" : "Link", "Hover")]; _fn && _fn(objData, prevObjType === objType ? prevObjData : null); } renderer3.domElement.classList[hoverObj && state["on".concat(objType === "node" ? "Node" : "Link", "Click")] || !hoverObj && state.onBackgroundClick ? "add" : "remove"]("clickable"); state.hoverObj = hoverObj; } }).clickAfterDrag(false).onClick(function(obj, ev) { var graphObj = getGraphObj(obj); if (graphObj) { var fn = state["on".concat(graphObj.__graphObjType === "node" ? "Node" : "Link", "Click")]; fn && fn(graphObj.__data, ev); } else { state.onBackgroundClick && state.onBackgroundClick(ev); } }).onRightClick(function(obj, ev) { var graphObj = getGraphObj(obj); if (graphObj) { var fn = state["on".concat(graphObj.__graphObjType === "node" ? "Node" : "Link", "RightClick")]; fn && fn(graphObj.__data, ev); } else { state.onBackgroundRightClick && state.onBackgroundRightClick(ev); } }); this._animationCycle(); } }); function getGraphObj(object) { var obj = object; while (obj && !obj.hasOwnProperty("__graphObjType")) { obj = obj.parent; } return obj; } // <stdin> core.ForceGraph3D = async (args, env) => { await interpretate.shared.SpriteText.load(); const data = await interpretate(args[0], env); const SpriteText = interpretate.shared.SpriteText.SpriteText; const opts = await core._getRules(args, env); const labels = (opts.VertexLabels || []).reduce((acc, { lhs, rhs }) => { acc[lhs] = rhs; return acc; }, {}); const nodeIds = /* @__PURE__ */ new Set(); const links = data.map(({ lhs, rhs }) => { nodeIds.add(lhs); nodeIds.add(rhs); return { source: String(rhs), target: String(lhs) }; }); const nodes = Array.from(nodeIds).map((id2) => ({ id: String(id2), label: labels[id2] || String(id2) })); let imageSize = opts.ImageSize || 350; if (!Array.isArray(imageSize)) { imageSize = [imageSize, imageSize * 0.7]; } const Graph = _3dForceGraph({})(env.element).width(imageSize[0]).height(imageSize[1]).cooldownTicks(100).graphData({ nodes, links }).nodeThreeObject((node) => { const sprite = new SpriteText(node.label); sprite.material.depthWrite = true; sprite.color = "white"; sprite.textHeight = 12; return sprite; }).nodeThreeObjectExtend(false); if ("Charge" in opts) { Graph.d3Force("charge").strength(opts.Charge); } Graph.onEngineStop(() => Graph.zoomToFit(400)); env.local.Graph = Graph; }; core.ForceGraph3D.destroy = () => { console.warn("3D graph was removed"); }; core.ForceGraph3D.virtual = true; /*! Bundled license information: three/build/three.module.js: (** * @license * Copyright 2010-2024 Three.js Authors * SPDX-License-Identifier: MIT *) three/build/three.webgpu.js: (** * @license * Copyright 2010-2024 Three.js Authors * SPDX-License-Identifier: MIT *) */
Note, you don't need to compile and reevaluate the cell above an invisible output cell stores JS module in this notebook.
Now we need to register this symbol in Wolfram Language
ForceGraph3D /: MakeBoxes[f_ForceGraph3D, StandardForm] := With[{ (* compress it for the case if you have many labels and vertices *) o = CreateFrontEndObject[f] }, (* low-level decoration box *) ViewBox[o, o] ]
Testing
Let us make a simple graph
ForceGraph3D[{ 1->2, 2->3, 3->4, 4->2, 3->5 }, "VertexLabels"->{1->"one", 4->"four", 5->"five"}, ImageSize->500]
(*VB[*)(FrontEndExecutable["7350994e-9424-4b9f-a7f0-dcc29c29ba2a"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKmxubGlhamqTqWpoYmeiaJFmm6SaapxnopiQnG1kCUVKiUSIAeQIVrA=="*)(*]VB*)
Try to drag around the nodes.
More nodes!
words = DictionaryLookup["pea*"]; Flatten[Map[(Thread[# -> DeleteCases[Nearest[words, #, 3], #]]) &, words]]; ForceGraph3D[%, ImageSize->500]
(*VB[*)(FrontEndExecutable["bcb3e485-f716-4f53-bc06-81af27eda67a"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJyUnGaeaWJjqppkbmumapJka6yYlG5jpWhgmphmZp6YkmpknAgCK7hYF"*)(*]VB*)