UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

492 lines (468 loc) 18.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.If = exports.Fn = void 0; exports.ShaderNode = ShaderNode; exports.addMethodChaining = addMethodChaining; exports.append = append; exports.vec4 = exports.vec3 = exports.vec2 = exports.uvec4 = exports.uvec3 = exports.uvec2 = exports.uint = exports.tslFn = exports.string = exports.split = exports.setCurrentStack = exports.nodeProxy = exports.nodeObjects = exports.nodeObject = exports.nodeImmutable = exports.nodeArray = exports.mat4 = exports.mat3 = exports.mat2 = exports.ivec4 = exports.ivec3 = exports.ivec2 = exports.int = exports.getCurrentStack = exports.getConstNodeType = exports.float = exports.element = exports.defined = exports.convert = exports.color = exports.bvec4 = exports.bvec3 = exports.bvec2 = exports.bool = exports.arrayBuffer = void 0; var _Node = _interopRequireDefault(require("../core/Node.js")); var _ArrayElementNode = _interopRequireDefault(require("../utils/ArrayElementNode.js")); var _ConvertNode = _interopRequireDefault(require("../utils/ConvertNode.js")); var _JoinNode = _interopRequireDefault(require("../utils/JoinNode.js")); var _SplitNode = _interopRequireDefault(require("../utils/SplitNode.js")); var _SetNode = _interopRequireDefault(require("../utils/SetNode.js")); var _FlipNode = _interopRequireDefault(require("../utils/FlipNode.js")); var _ConstNode = _interopRequireDefault(require("../core/ConstNode.js")); var _MemberNode = _interopRequireDefault(require("../utils/MemberNode.js")); var _NodeUtils = require("../core/NodeUtils.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } let currentStack = null; const NodeElements = new Map(); function addMethodChaining(name, nodeElement) { if (NodeElements.has(name)) { console.warn(`THREE.TSL: Redefinition of method chaining '${name}'.`); return; } if (typeof nodeElement !== 'function') throw new Error(`THREE.TSL: Node element ${name} is not a function`); NodeElements.set(name, nodeElement); } const parseSwizzle = props => props.replace(/r|s/g, 'x').replace(/g|t/g, 'y').replace(/b|p/g, 'z').replace(/a|q/g, 'w'); const parseSwizzleAndSort = props => parseSwizzle(props).split('').sort().join(''); const shaderNodeHandler = { setup(NodeClosure, params) { const inputs = params.shift(); return NodeClosure(nodeObjects(inputs), ...params); }, get(node, prop, nodeObj) { if (typeof prop === 'string' && node[prop] === undefined) { 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) { // accessing properties ( swizzle ) prop = parseSwizzle(prop); return nodeObject(new _SplitNode.default(nodeObj, prop)); } else if (/^set[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { // set properties ( swizzle ) and sort to xyzw sequence prop = parseSwizzleAndSort(prop.slice(3).toLowerCase()); return value => nodeObject(new _SetNode.default(node, prop, value)); } else if (/^flip[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { // set properties ( swizzle ) and sort to xyzw sequence prop = parseSwizzleAndSort(prop.slice(4).toLowerCase()); return () => nodeObject(new _FlipNode.default(nodeObject(node), prop)); } else if (prop === 'width' || prop === 'height' || prop === 'depth') { // accessing property if (prop === 'width') prop = 'x';else if (prop === 'height') prop = 'y';else if (prop === 'depth') prop = 'z'; return nodeObject(new _SplitNode.default(node, prop)); } else if (/^\d+$/.test(prop) === true) { // accessing array return nodeObject(new _ArrayElementNode.default(nodeObj, new _ConstNode.default(Number(prop), 'uint'))); } else if (/^get$/.test(prop) === true) { // accessing properties return value => nodeObject(new _MemberNode.default(nodeObj, value)); } } return Reflect.get(node, prop, nodeObj); }, set(node, prop, value, nodeObj) { if (typeof prop === 'string' && node[prop] === undefined) { // setting properties 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); } }; const nodeObjectsCacheMap = new WeakMap(); const nodeBuilderFunctionsCacheMap = new WeakMap(); const ShaderNodeObject = function (obj, altType = null) { const type = (0, _NodeUtils.getValueType)(obj); if (type === 'node') { let nodeObject = nodeObjectsCacheMap.get(obj); if (nodeObject === undefined) { nodeObject = new Proxy(obj, shaderNodeHandler); nodeObjectsCacheMap.set(obj, nodeObject); nodeObjectsCacheMap.set(nodeObject, nodeObject); } return nodeObject; } 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; }; const ShaderNodeObjects = function (objects, altType = null) { for (const name in objects) { objects[name] = nodeObject(objects[name], altType); } return objects; }; const ShaderNodeArray = function (array, altType = null) { const len = array.length; for (let i = 0; i < len; i++) { array[i] = nodeObject(array[i], altType); } return array; }; const ShaderNodeProxy = function (NodeClass, scope = null, factor = null, settings = null) { const assignNode = node => nodeObject(settings !== null ? Object.assign(node, settings) : node); let fn, name = scope, minParams, maxParams; function verifyParamsLimit(params) { let tslName; if (name) tslName = /[a-z]/i.test(name) ? name + '()' : name;else tslName = NodeClass.type; if (minParams !== undefined && params.length < minParams) { console.error(`THREE.TSL: "${tslName}" parameter length is less than minimum required.`); return params.concat(new Array(minParams - params.length).fill(0)); } else if (maxParams !== undefined && params.length > maxParams) { console.error(`THREE.TSL: "${tslName}" parameter length exceeds limit.`); return params.slice(0, maxParams); } return params; } if (scope === null) { fn = (...params) => { return assignNode(new NodeClass(...nodeArray(verifyParamsLimit(params)))); }; } else if (factor !== null) { factor = nodeObject(factor); fn = (...params) => { return assignNode(new NodeClass(scope, ...nodeArray(verifyParamsLimit(params)), factor)); }; } else { fn = (...params) => { return assignNode(new NodeClass(scope, ...nodeArray(verifyParamsLimit(params)))); }; } fn.setParameterLength = (...params) => { if (params.length === 1) minParams = maxParams = params[0];else if (params.length === 2) [minParams, maxParams] = params; return fn; }; fn.setName = value => { name = value; return fn; }; return fn; }; const ShaderNodeImmutable = function (NodeClass, ...params) { return nodeObject(new NodeClass(...nodeArray(params))); }; class ShaderCallNodeInternal extends _Node.default { constructor(shaderNode, inputNodes) { super(); this.shaderNode = shaderNode; this.inputNodes = inputNodes; } getNodeType(builder) { return this.shaderNode.nodeType || this.getOutputNode(builder).getNodeType(builder); } getMemberType(builder, name) { return this.getOutputNode(builder).getMemberType(builder, name); } 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 === undefined) { functionNodesCacheMap = new WeakMap(); nodeBuilderFunctionsCacheMap.set(builder.constructor, functionNodesCacheMap); } let functionNode = functionNodesCacheMap.get(shaderNode); if (functionNode === undefined) { functionNode = nodeObject(builder.buildFunctionNode(shaderNode)); functionNodesCacheMap.set(shaderNode, functionNode); } builder.addInclude(functionNode); result = nodeObject(functionNode.call(inputNodes)); } else { const jsFunc = shaderNode.jsFunc; const outputNode = inputNodes !== null || jsFunc.length > 1 ? 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, output) { const outputNode = this.getOutputNode(builder); return outputNode.build(builder, output); } } class ShaderNodeInternal extends _Node.default { 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(); } } const bools = [false, true]; const uints = [0, 1, 2, 3]; const ints = [-1, -2]; const 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]; const boolsCacheMap = new Map(); for (const bool of bools) boolsCacheMap.set(bool, new _ConstNode.default(bool)); const uintsCacheMap = new Map(); for (const uint of uints) uintsCacheMap.set(uint, new _ConstNode.default(uint, 'uint')); const intsCacheMap = new Map([...uintsCacheMap].map(el => new _ConstNode.default(el.value, 'int'))); for (const int of ints) intsCacheMap.set(int, new _ConstNode.default(int, 'int')); const floatsCacheMap = new Map([...intsCacheMap].map(el => new _ConstNode.default(el.value))); for (const float of floats) floatsCacheMap.set(float, new _ConstNode.default(float)); for (const float of floats) floatsCacheMap.set(-float, new _ConstNode.default(-float)); const cacheMaps = { bool: boolsCacheMap, uint: uintsCacheMap, ints: intsCacheMap, float: floatsCacheMap }; const constNodesCacheMap = new Map([...boolsCacheMap, ...floatsCacheMap]); const getConstNode = (value, type) => { if (constNodesCacheMap.has(value)) { return constNodesCacheMap.get(value); } else if (value.isNode === true) { return value; } else { return new _ConstNode.default(value, type); } }; const safeGetNodeType = node => { try { return node.getNodeType(); } catch (_) { return undefined; } }; const ConvertType = function (type, cacheMap = null) { return (...params) => { if (params.length === 0 || !['bool', 'float', 'int', 'uint'].includes(type) && params.every(param => typeof param !== 'object')) { params = [(0, _NodeUtils.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.default(node, type)); } const nodes = params.map(param => getConstNode(param)); return nodeObject(new _JoinNode.default(nodes, type)); }; }; // exports const defined = v => typeof v === 'object' && v !== null ? v.value : v; // TODO: remove boolean conversion and defined function // utils exports.defined = defined; const getConstNodeType = value => value !== undefined && value !== null ? value.nodeType || value.convertTo || (typeof value === 'string' ? value : null) : null; // shader node base exports.getConstNodeType = getConstNodeType; function ShaderNode(jsFunc, nodeType) { return new Proxy(new ShaderNodeInternal(jsFunc, nodeType), shaderNodeHandler); } const nodeObject = (val, altType = null) => /* new */ShaderNodeObject(val, altType); exports.nodeObject = nodeObject; const nodeObjects = (val, altType = null) => new ShaderNodeObjects(val, altType); exports.nodeObjects = nodeObjects; const nodeArray = (val, altType = null) => new ShaderNodeArray(val, altType); exports.nodeArray = nodeArray; const nodeProxy = (...params) => new ShaderNodeProxy(...params); exports.nodeProxy = nodeProxy; const nodeImmutable = (...params) => new ShaderNodeImmutable(...params); exports.nodeImmutable = nodeImmutable; let fnId = 0; const Fn = (jsFunc, layout = null) => { let nodeType = null; if (layout !== null) { if (typeof layout === 'object') { nodeType = layout.return; } else { if (typeof layout === 'string') { nodeType = layout; } else { console.error('THREE.TSL: Invalid layout type.'); } layout = null; } } 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; }; if (layout !== null) { if (typeof layout.inputs !== 'object') { const fullLayout = { name: 'fn' + fnId++, type: nodeType, inputs: [] }; for (const name in layout) { if (name === 'return') continue; fullLayout.inputs.push({ name: name, type: layout[name] }); } layout = fullLayout; } fn.setLayout(layout); } return fn; }; /** * @tsl * @function * @deprecated since r168. Use {@link Fn} instead. * * @param {...any} params * @returns {Function} */ exports.Fn = Fn; const tslFn = (...params) => { // @deprecated, r168 console.warn('THREE.TSL: tslFn() has been renamed to Fn().'); return Fn(...params); }; // exports.tslFn = tslFn; addMethodChaining('toGlobal', node => { node.global = true; return node; }); // const setCurrentStack = stack => { if (currentStack === stack) { //throw new Error( 'Stack already defined.' ); } currentStack = stack; }; exports.setCurrentStack = setCurrentStack; const getCurrentStack = () => currentStack; exports.getCurrentStack = getCurrentStack; const If = (...params) => currentStack.If(...params); exports.If = If; function append(node) { if (currentStack) currentStack.add(node); return node; } addMethodChaining('append', append); // types const color = exports.color = new ConvertType('color'); const float = exports.float = new ConvertType('float', cacheMaps.float); const int = exports.int = new ConvertType('int', cacheMaps.ints); const uint = exports.uint = new ConvertType('uint', cacheMaps.uint); const bool = exports.bool = new ConvertType('bool', cacheMaps.bool); const vec2 = exports.vec2 = new ConvertType('vec2'); const ivec2 = exports.ivec2 = new ConvertType('ivec2'); const uvec2 = exports.uvec2 = new ConvertType('uvec2'); const bvec2 = exports.bvec2 = new ConvertType('bvec2'); const vec3 = exports.vec3 = new ConvertType('vec3'); const ivec3 = exports.ivec3 = new ConvertType('ivec3'); const uvec3 = exports.uvec3 = new ConvertType('uvec3'); const bvec3 = exports.bvec3 = new ConvertType('bvec3'); const vec4 = exports.vec4 = new ConvertType('vec4'); const ivec4 = exports.ivec4 = new ConvertType('ivec4'); const uvec4 = exports.uvec4 = new ConvertType('uvec4'); const bvec4 = exports.bvec4 = new ConvertType('bvec4'); const mat2 = exports.mat2 = new ConvertType('mat2'); const mat3 = exports.mat3 = new ConvertType('mat3'); const mat4 = exports.mat4 = new ConvertType('mat4'); const string = (value = '') => nodeObject(new _ConstNode.default(value, 'string')); exports.string = string; const arrayBuffer = value => nodeObject(new _ConstNode.default(value, 'ArrayBuffer')); exports.arrayBuffer = arrayBuffer; 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); // basic nodes const element = exports.element = /*@__PURE__*/nodeProxy(_ArrayElementNode.default).setParameterLength(2); const convert = (node, types) => nodeObject(new _ConvertNode.default(nodeObject(node), types)); exports.convert = convert; const split = (node, channels) => nodeObject(new _SplitNode.default(nodeObject(node), channels)); exports.split = split; addMethodChaining('element', element); addMethodChaining('convert', convert);