(function (global, factory) { if (typeof define === "function" && define.amd) { define(["exports", "three", "./NodeUniform.js", "./NodeUtils.js", "./NodeLib.js", "./FunctionNode.js", "./ConstNode.js", "./StructNode.js", "../inputs/Vector2Node.js", "../inputs/Vector3Node.js", "../inputs/Vector4Node.js", "../inputs/TextureNode.js", "../inputs/CubeTextureNode.js", "../misc/TextureCubeNode.js"], factory); } else if (typeof exports !== "undefined") { factory(exports, require("three"), require("./NodeUniform.js"), require("./NodeUtils.js"), require("./NodeLib.js"), require("./FunctionNode.js"), require("./ConstNode.js"), require("./StructNode.js"), require("../inputs/Vector2Node.js"), require("../inputs/Vector3Node.js"), require("../inputs/Vector4Node.js"), require("../inputs/TextureNode.js"), require("../inputs/CubeTextureNode.js"), require("../misc/TextureCubeNode.js")); } else { var mod = { exports: {} }; factory(mod.exports, global.three, global.NodeUniform, global.NodeUtils, global.NodeLib, global.FunctionNode, global.ConstNode, global.StructNode, global.Vector2Node, global.Vector3Node, global.Vector4Node, global.TextureNode, global.CubeTextureNode, global.TextureCubeNode); global.NodeBuilder = mod.exports; } })(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _three, _NodeUniform, _NodeUtils, _NodeLib, _FunctionNode, _ConstNode, _StructNode, _Vector2Node, _Vector3Node, _Vector4Node, _TextureNode, _CubeTextureNode, _TextureCubeNode) { "use strict"; Object.defineProperty(_exports, "__esModule", { value: true }); _exports.NodeBuilder = void 0; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } var elements = _NodeUtils.NodeUtils.elements, constructors = ['float', 'vec2', 'vec3', 'vec4'], convertFormatToType = { float: 'f', vec2: 'v2', vec3: 'v3', vec4: 'v4', mat4: 'v4', int: 'i', bool: 'b' }, convertTypeToFormat = { t: 'sampler2D', tc: 'samplerCube', b: 'bool', i: 'int', f: 'float', c: 'vec3', v2: 'vec2', v3: 'vec3', v4: 'vec4', m3: 'mat3', m4: 'mat4' }; var NodeBuilder = /*#__PURE__*/function () { function NodeBuilder() { _classCallCheck(this, NodeBuilder); this.slots = []; this.caches = []; this.contexts = []; this.keywords = {}; this.nodeData = {}; this.requires = { uv: [], color: [], lights: false, fog: false, transparent: false, irradiance: false }; this.includes = { consts: [], functions: [], structs: [] }; this.attributes = {}; this.prefixCode = /* glsl */ "\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\n\t\t\t\t#define texCube(a, b) textureCube(a, b)\n\t\t\t\t#define texCubeBias(a, b, c) textureCubeLodEXT(a, b, c)\n\n\t\t\t\t#define tex2D(a, b) texture2D(a, b)\n\t\t\t\t#define tex2DBias(a, b, c) texture2DLodEXT(a, b, c)\n\n\t\t\t#else\n\n\t\t\t\t#define texCube(a, b) textureCube(a, b)\n\t\t\t\t#define texCubeBias(a, b, c) textureCube(a, b, c)\n\n\t\t\t\t#define tex2D(a, b) texture2D(a, b)\n\t\t\t\t#define tex2DBias(a, b, c) texture2D(a, b, c)\n\n\t\t\t#endif\n\n\t\t\t#include \n\t\t\t#include "; this.parsCode = { vertex: '', fragment: '' }; this.code = { vertex: '', fragment: '' }; this.nodeCode = { vertex: '', fragment: '' }; this.resultCode = { vertex: '', fragment: '' }; this.finalCode = { vertex: '', fragment: '' }; this.inputs = { uniforms: { list: [], vertex: [], fragment: [] }, vars: { varying: [], vertex: [], fragment: [] } }; // send to material this.defines = {}; this.uniforms = {}; this.extensions = {}; this.updaters = []; this.nodes = []; // -- this.analyzing = false; } _createClass(NodeBuilder, [{ key: "build", value: function build(vertex, fragment) { this.buildShader('vertex', vertex); this.buildShader('fragment', fragment); for (var i = 0; i < this.requires.uv.length; i++) { if (this.requires.uv[i]) { var uvIndex = i > 0 ? i + 1 : ''; this.addVaryCode('varying vec2 vUv' + uvIndex + ';'); if (i > 0) { this.addVertexParsCode('attribute vec2 uv' + uvIndex + ';'); } this.addVertexFinalCode('vUv' + uvIndex + ' = uv' + uvIndex + ';'); } } if (this.requires.color[0]) { this.addVaryCode('varying vec4 vColor;'); this.addVertexParsCode('attribute vec4 color;'); this.addVertexFinalCode('vColor = color;'); } if (this.requires.color[1]) { this.addVaryCode('varying vec4 vColor2;'); this.addVertexParsCode('attribute vec4 color2;'); this.addVertexFinalCode('vColor2 = color2;'); } if (this.requires.position) { this.addVaryCode('varying vec3 vPosition;'); this.addVertexFinalCode('vPosition = transformed;'); } if (this.requires.worldPosition) { this.addVaryCode('varying vec3 vWPosition;'); this.addVertexFinalCode('vWPosition = ( modelMatrix * vec4( transformed, 1.0 ) ).xyz;'); } if (this.requires.normal) { this.addVaryCode('varying vec3 vObjectNormal;'); this.addVertexFinalCode('vObjectNormal = normal;'); } if (this.requires.worldNormal) { this.addVaryCode('varying vec3 vWNormal;'); this.addVertexFinalCode('vWNormal = inverseTransformDirection( transformedNormal, viewMatrix ).xyz;'); } return this; } }, { key: "buildShader", value: function buildShader(shader, node) { this.resultCode[shader] = node.build(this.setShader(shader), 'v4'); } }, { key: "setMaterial", value: function setMaterial(material, renderer) { this.material = material; this.renderer = renderer; this.requires.lights = material.lights; this.requires.fog = material.fog; this.mergeDefines(material.defines); return this; } }, { key: "addFlow", value: function addFlow(slot, cache, context) { return this.addSlot(slot).addCache(cache).addContext(context); } }, { key: "removeFlow", value: function removeFlow() { return this.removeSlot().removeCache().removeContext(); } }, { key: "addCache", value: function addCache(name) { this.cache = name || ''; this.caches.push(this.cache); return this; } }, { key: "removeCache", value: function removeCache() { this.caches.pop(); this.cache = this.caches[this.caches.length - 1] || ''; return this; } }, { key: "addContext", value: function addContext(context) { this.context = Object.assign({}, this.context, context); this.context.extra = this.context.extra || {}; this.contexts.push(this.context); return this; } }, { key: "removeContext", value: function removeContext() { this.contexts.pop(); this.context = this.contexts[this.contexts.length - 1] || {}; return this; } }, { key: "addSlot", value: function addSlot() { var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; this.slot = name; this.slots.push(this.slot); return this; } }, { key: "removeSlot", value: function removeSlot() { this.slots.pop(); this.slot = this.slots[this.slots.length - 1] || ''; return this; } }, { key: "addVertexCode", value: function addVertexCode(code) { this.addCode(code, 'vertex'); } }, { key: "addFragmentCode", value: function addFragmentCode(code) { this.addCode(code, 'fragment'); } }, { key: "addCode", value: function addCode(code, shader) { this.code[shader || this.shader] += code + '\n'; } }, { key: "addVertexNodeCode", value: function addVertexNodeCode(code) { this.addNodeCode(code, 'vertex'); } }, { key: "addFragmentNodeCode", value: function addFragmentNodeCode(code) { this.addNodeCode(code, 'fragment'); } }, { key: "addNodeCode", value: function addNodeCode(code, shader) { this.nodeCode[shader || this.shader] += code + '\n'; } }, { key: "clearNodeCode", value: function clearNodeCode(shader) { shader = shader || this.shader; var code = this.nodeCode[shader]; this.nodeCode[shader] = ''; return code; } }, { key: "clearVertexNodeCode", value: function clearVertexNodeCode() { return this.clearNodeCode('vertex'); } }, { key: "clearFragmentNodeCode", value: function clearFragmentNodeCode() { return this.clearNodeCode('fragment'); } }, { key: "addVertexFinalCode", value: function addVertexFinalCode(code) { this.addFinalCode(code, 'vertex'); } }, { key: "addFragmentFinalCode", value: function addFragmentFinalCode(code) { this.addFinalCode(code, 'fragment'); } }, { key: "addFinalCode", value: function addFinalCode(code, shader) { this.finalCode[shader || this.shader] += code + '\n'; } }, { key: "addVertexParsCode", value: function addVertexParsCode(code) { this.addParsCode(code, 'vertex'); } }, { key: "addFragmentParsCode", value: function addFragmentParsCode(code) { this.addParsCode(code, 'fragment'); } }, { key: "addParsCode", value: function addParsCode(code, shader) { this.parsCode[shader || this.shader] += code + '\n'; } }, { key: "addVaryCode", value: function addVaryCode(code) { this.addVertexParsCode(code); this.addFragmentParsCode(code); } }, { key: "isCache", value: function isCache(name) { return this.caches.indexOf(name) !== -1; } }, { key: "isSlot", value: function isSlot(name) { return this.slots.indexOf(name) !== -1; } }, { key: "define", value: function define(name, value) { this.defines[name] = value === undefined ? 1 : value; } }, { key: "require", value: function require(name) { this.requires[name] = true; } }, { key: "isDefined", value: function isDefined(name) { return this.defines[name] !== undefined; } }, { key: "getVar", value: function getVar(uuid, type, ns) { var shader = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'varying'; var prefix = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'V'; var label = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : ''; var vars = this.getVars(shader); var data = vars[uuid]; if (!data) { var index = vars.length, name = ns ? ns : 'node' + prefix + index + (label ? '_' + label : ''); data = { name: name, type: type }; vars.push(data); vars[uuid] = data; } return data; } }, { key: "getTempVar", value: function getTempVar(uuid, type, ns, label) { return this.getVar(uuid, type, ns, this.shader, 'T', label); } }, { key: "getAttribute", value: function getAttribute(name, type) { if (!this.attributes[name]) { var varying = this.getVar(name, type); this.addVertexParsCode('attribute ' + type + ' ' + name + ';'); this.addVertexFinalCode(varying.name + ' = ' + name + ';'); this.attributes[name] = { varying: varying, name: name, type: type }; } return this.attributes[name]; } }, { key: "getCode", value: function getCode(shader) { return [this.prefixCode, this.parsCode[shader], this.getVarListCode(this.getVars('varying'), 'varying'), this.getVarListCode(this.inputs.uniforms[shader], 'uniform'), this.getIncludesCode('consts', shader), this.getIncludesCode('structs', shader), this.getIncludesCode('functions', shader), 'void main() {', this.getVarListCode(this.getVars(shader)), this.code[shader], this.resultCode[shader], this.finalCode[shader], '}'].join('\n'); } }, { key: "getVarListCode", value: function getVarListCode(vars) { var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; var code = ''; for (var i = 0, l = vars.length; i < l; ++i) { var nVar = vars[i], type = nVar.type, name = nVar.name; var formatType = this.getFormatByType(type); if (formatType === undefined) { throw new Error('Node pars ' + formatType + ' not found.'); } code += prefix + ' ' + formatType + ' ' + name + ';\n'; } return code; } }, { key: "getVars", value: function getVars(shader) { return this.inputs.vars[shader || this.shader]; } }, { key: "getNodeData", value: function getNodeData(node) { var uuid = node.isNode ? node.uuid : node; return this.nodeData[uuid] = this.nodeData[uuid] || {}; } }, { key: "createUniform", value: function createUniform(shader, type, node, ns, needsUpdate, label) { var uniforms = this.inputs.uniforms, index = uniforms.list.length; var uniform = new _NodeUniform.NodeUniform({ type: type, name: ns ? ns : 'nodeU' + index + (label ? '_' + label : ''), node: node, needsUpdate: needsUpdate }); uniforms.list.push(uniform); uniforms[shader].push(uniform); uniforms[shader][uniform.name] = uniform; this.uniforms[uniform.name] = uniform; return uniform; } }, { key: "createVertexUniform", value: function createVertexUniform(type, node, ns, needsUpdate, label) { return this.createUniform('vertex', type, node, ns, needsUpdate, label); } }, { key: "createFragmentUniform", value: function createFragmentUniform(type, node, ns, needsUpdate, label) { return this.createUniform('fragment', type, node, ns, needsUpdate, label); } }, { key: "include", value: function include(node, parent, source) { var includesStruct; node = typeof node === 'string' ? _NodeLib.NodeLib.get(node) : node; if (this.context.include === false) { return node.name; } if (node instanceof _FunctionNode.FunctionNode) { includesStruct = this.includes.functions; } else if (node instanceof _ConstNode.ConstNode) { includesStruct = this.includes.consts; } else if (node instanceof _StructNode.StructNode) { includesStruct = this.includes.structs; } var includes = includesStruct[this.shader] = includesStruct[this.shader] || []; if (node) { var included = includes[node.name]; if (!included) { included = includes[node.name] = { node: node, deps: [] }; includes.push(included); included.src = node.build(this, 'source'); } if (node instanceof _FunctionNode.FunctionNode && parent && includes[parent.name] && includes[parent.name].deps.indexOf(node) == -1) { includes[parent.name].deps.push(node); if (node.includes && node.includes.length) { var i = 0; do { this.include(node.includes[i++], parent); } while (i < node.includes.length); } } if (source) { included.src = source; } return node.name; } else { throw new Error('Include not found.'); } } }, { key: "colorToVectorProperties", value: function colorToVectorProperties(color) { return color.replace('r', 'x').replace('g', 'y').replace('b', 'z').replace('a', 'w'); } }, { key: "colorToVector", value: function colorToVector(color) { return color.replace(/c/g, 'v3'); } }, { key: "getIncludes", value: function getIncludes(type, shader) { return this.includes[type][shader || this.shader]; } }, { key: "getIncludesCode", value: function getIncludesCode(type, shader) { var includes = this.getIncludes(type, shader); if (!includes) return ''; var code = ''; includes = includes.sort(sortByPosition); for (var i = 0; i < includes.length; i++) { if (includes[i].src) code += includes[i].src + '\n'; } return code; } }, { key: "getConstructorFromLength", value: function getConstructorFromLength(len) { return constructors[len - 1]; } }, { key: "isTypeMatrix", value: function isTypeMatrix(format) { return /^m/.test(format); } }, { key: "getTypeLength", value: function getTypeLength(type) { if (type === 'f') return 1; return parseInt(this.colorToVector(type).substr(1)); } }, { key: "getTypeFromLength", value: function getTypeFromLength(len) { if (len === 1) return 'f'; return 'v' + len; } }, { key: "findNode", value: function findNode() { for (var i = 0; i < arguments.length; i++) { var nodeCandidate = arguments[i]; if (nodeCandidate !== undefined && nodeCandidate.isNode) { return nodeCandidate; } } } }, { key: "resolve", value: function resolve() { for (var i = 0; i < arguments.length; i++) { var nodeCandidate = arguments[i]; if (nodeCandidate !== undefined) { if (nodeCandidate.isNode) { return nodeCandidate; } else if (nodeCandidate.isTexture) { switch (nodeCandidate.mapping) { case _three.CubeReflectionMapping: case _three.CubeRefractionMapping: return new _CubeTextureNode.CubeTextureNode(nodeCandidate); break; case _three.CubeUVReflectionMapping: case _three.CubeUVRefractionMapping: return new _TextureCubeNode.TextureCubeNode(new _TextureNode.TextureNode(nodeCandidate)); break; default: return new _TextureNode.TextureNode(nodeCandidate); } } else if (nodeCandidate.isVector2) { return new _Vector2Node.Vector2Node(nodeCandidate); } else if (nodeCandidate.isVector3) { return new _Vector3Node.Vector3Node(nodeCandidate); } else if (nodeCandidate.isVector4) { return new _Vector4Node.Vector4Node(nodeCandidate); } } } } }, { key: "format", value: function format(code, from, to) { var typeToType = this.colorToVector(to + ' <- ' + from); switch (typeToType) { case 'f <- v2': return code + '.x'; case 'f <- v3': return code + '.x'; case 'f <- v4': return code + '.x'; case 'f <- i': case 'f <- b': return 'float( ' + code + ' )'; case 'v2 <- f': return 'vec2( ' + code + ' )'; case 'v2 <- v3': return code + '.xy'; case 'v2 <- v4': return code + '.xy'; case 'v2 <- i': case 'v2 <- b': return 'vec2( float( ' + code + ' ) )'; case 'v3 <- f': return 'vec3( ' + code + ' )'; case 'v3 <- v2': return 'vec3( ' + code + ', 0.0 )'; case 'v3 <- v4': return code + '.xyz'; case 'v3 <- i': case 'v3 <- b': return 'vec2( float( ' + code + ' ) )'; case 'v4 <- f': return 'vec4( ' + code + ' )'; case 'v4 <- v2': return 'vec4( ' + code + ', 0.0, 1.0 )'; case 'v4 <- v3': return 'vec4( ' + code + ', 1.0 )'; case 'v4 <- i': case 'v4 <- b': return 'vec4( float( ' + code + ' ) )'; case 'i <- f': case 'i <- b': return 'int( ' + code + ' )'; case 'i <- v2': return 'int( ' + code + '.x )'; case 'i <- v3': return 'int( ' + code + '.x )'; case 'i <- v4': return 'int( ' + code + '.x )'; case 'b <- f': return '( ' + code + ' != 0.0 )'; case 'b <- v2': return '( ' + code + ' != vec2( 0.0 ) )'; case 'b <- v3': return '( ' + code + ' != vec3( 0.0 ) )'; case 'b <- v4': return '( ' + code + ' != vec4( 0.0 ) )'; case 'b <- i': return '( ' + code + ' != 0 )'; } return code; } }, { key: "getTypeByFormat", value: function getTypeByFormat(format) { return convertFormatToType[format] || format; } }, { key: "getFormatByType", value: function getFormatByType(type) { return convertTypeToFormat[type] || type; } }, { key: "getUuid", value: function getUuid(uuid, useCache) { useCache = useCache !== undefined ? useCache : true; if (useCache && this.cache) uuid = this.cache + '-' + uuid; return uuid; } }, { key: "getElementByIndex", value: function getElementByIndex(index) { return elements[index]; } }, { key: "getIndexByElement", value: function getIndexByElement(elm) { return elements.indexOf(elm); } }, { key: "isShader", value: function isShader(shader) { return this.shader === shader; } }, { key: "setShader", value: function setShader(shader) { this.shader = shader; return this; } }, { key: "mergeDefines", value: function mergeDefines(defines) { for (var name in defines) { this.defines[name] = defines[name]; } return this.defines; } }, { key: "mergeUniform", value: function mergeUniform(uniforms) { for (var name in uniforms) { this.uniforms[name] = uniforms[name]; } return this.uniforms; } }, { key: "getTextureEncodingFromMap", value: function getTextureEncodingFromMap(map) { var encoding; if (!map) { encoding = _three.LinearEncoding; } else if (map.isTexture) { encoding = map.encoding; } else if (map.isWebGLRenderTarget) { console.warn('THREE.WebGLPrograms.getTextureEncodingFromMap: don\'t use render targets as textures. Use their .texture property instead.'); encoding = map.texture.encoding; } if (encoding === _three.LinearEncoding && this.context.gamma) { encoding = _three.GammaEncoding; } return encoding; } }]); return NodeBuilder; }(); _exports.NodeBuilder = NodeBuilder; function sortByPosition(a, b) { return a.deps.length - b.deps.length; } });